在声明一个字符的数组时是否需要提供空字符?

C中的字符串常量存储为字符数组,而按元素创建这样的数组元素时,是否需要提供空字符。

我需要存储一个字符串常量,比如S[number]= "hello\n" 。 字符串常量在C中存储为字符数组,此外,这样的字符串由空字符'\0'终止。 将短语存储在数组中时,是否需要考虑空字符并分配额外的空间,或者我只需要提及需要存储的字符数?

如果你打算使用C字符串函数,比如strlen,那么答案就是YES 。 您的字符串应以空值终止。 如果您介绍自定义函数来处理字符串 – 您可以随意存储它。

值得一提的是,如果使用字符串常量创建数组,则会自动为空字符保留空间。 例如输出以下代码:

 char s[] = "hello"; printf("%d", sizeof(s) / sizeof(char)); 

 6 

对于’h,’e’,’l’,’l’,’o’为1,对于’\ 0’为1。

将短语存储在数组中时,是否需要考虑空字符并分配额外空间,或者我只需要提及需要存储的字符数?

是的 ,您应该计算空字符以分配额外的空间。 你必须在这里注意重点:

 S[number]= "hello\n"; 

如果number值等于(或大于)字符串"hello\n" pule的长度为\0 char(或者如果你根本不给出大小为s[] = "hello\n";将在S[]数组中追加\0 s[] = "hello\n"; )。

来自:ISO / IEC 9899:201x委员会草案2011年4月12日N1570:

6.7.9 [初始化]

[…]
14:字符类型数组可以由字符串文字或UTF-8字符串文字初始化,可选地用大括号括起来。 字符串文字的连续字节( 如果有空间或数组大小未知,则包括终止空字符 )初始化数组的元素。
[..]
例8声明

 char s[] = "abc", t[3] = "abc"; 

定义“plain”char数组对象s和t,其元素用字符串文字初始化。 该声明与以下内容相同:

  char s[] = { 'a', 'b', 'c', '\0' }, t[] = { 'a', 'b', 'c' }; // you are missing this point 

数组的内容是可修改的。 另一方面,声明

  char *p = "abc"; 

使用pointer to char'' and initializes it to point to an object with type类型pointer to char'' and initializes it to point to an object with type定义p pointer to char'' and initializes it to point to an object with type为char” pointer to char'' and initializes it to point to an object with type其长度为4,其元素使用字符串文字初始化。 如果尝试使用p修改数组的内容,则行为未定义。

因此,我对您的问题发表了评论:这取决于您在声明中声明的number值。 它可能会添加'\0'字符(在大多数情况下)或者可能不会添加(在一个有效的声明中)。 这是非常重要的一点,大多数答案都缺失了。

更珍贵:

注意"hello"是六个char长字符串(包括字符串终止nul char '\0'

 S[6]= "hello"; 

与:

 S[6]= {'h', 'e', 'l', 'l', 'o', '\0'}; // ^ is 6 

 S[5]= "hello"; 

在C中有效 ,但不要追加 nul \0 char。 它相当于:

 S[5]= {'h', 'e', 'l', 'l', 'o'}; // ^ is 5 

现在这是非常重要的注意,在这个声明中,如果在声明中给出5 = 5的大小,那么你可以使用循环打印字符for(i = 0; i < sizeof(S); i++) ,但你可以'在S[]上使用%s或类似strcpy的函数 - 使用此调用未定义的行为。

除此之外,我还建议您在编译代码时始终使用-Wall和-pedantic标志。 现在看看这是如何工作的:

让我们用char s[4] = "hello";编译这段代码char s[4] = "hello";

 int main(){ char s[4] = "hello"; int i = 0; for (i = 0; i < sizeof s; i++) printf("%c", s[i]); printf("\n"); return 0; } 

您将收到如下警告:

 $ gcc -Wall -pedantic xc xc: In function 'main': xc:3:15: warning: initializer-string for array of chars is too long [enabled by default] 

但是代码在C中有效,而char s[5] = "hello"; 编译相同的代码,它不会给你任何警告,也暗示它是一个有效的代码,但显然它不添加\0

 #include  int main(){ char s[5] = "hello"; int i = 0; for (i = 0; i < sizeof s; i++) printf("%c", s[i]); printf("\n"); return 0; } 

检查一下(你应该注意到这次编译器没有发出任何警告):

 $ gcc -Wall -pedantic xc @:~$ ./a.out hello 

但这次我们应该使用printf("%s", s); 它将调用未定义的行为。

因此,当您使用字符串文字创建数组时,最好避免声明中的大小,如下所示:

  char s[] = "hello"; 

但这与char s[6] = "hello"; 并且你不能将新的字符附加到s[]作为strcat(s, " world!")

如果您打算在代码中修改s[] ,那么您可能希望创建一个足够大的字符串:

  char s[100] = "hello"; 

现在strcat(s, " world!")是完全有效的代码。

不,但你应该省略number

 char S[]= "hello\n"; 

将具有尾随0字符,并根据需要调整数组大小。

number太小你可能会意外地切断0字符。