在C中打印字符串和空字符的概念

Avi*_*Avi 5 c arrays string initialization c-strings

在阅读有关打印字符串的过程中,我通过一个声明" printf逐个写入字符,直到它遇到一个空字符.如果缺少空字符,则printf继续超过字符串的结尾,直到最终它在字符串中找到一个空字符.记忆".所以我写了一些代码:

情况1:

char arr[4] = { 'a', 'b', 'c' } ;

if (arr[3]== '\0')

printf ("%s",arr);
Run Code Online (Sandbox Code Playgroud)

输出是abc.

这是否意味着编译器已自动存储'\0'arr[3].因为根据声明,printf只会在遇到时终止'\0'.

案例2:

char arr[3] = { 'a', 'b', 'c' } ;

if (arr[3]== '\0')

printf ("%s",arr);
Run Code Online (Sandbox Code Playgroud)

abc尽管没有数组块arr[3]存在,但输出又是 ,所以为什么不是错误呢?printf也已打印abc并停止,这意味着它必须遇到'\0'.那么这意味着编译器在arr[2]存储后会创建一个额外的数组块'\0'.如果这样那么数组大小必须增加到4个字节(每个字符类型字符为1个字节).但是执行语句printf ("%d",sizeof (arr));会给出输出3,表明数组大小没有增加,表明没有arr[3].那条件怎么if (arr[3]== '\0')变成了真的呢?

案例3:

char arr[3] = "abc";

if (arr[3]== '\0')

printf ("%s",arr);
Run Code Online (Sandbox Code Playgroud)

现在它给我一个错误,说"数组索引3超过了结尾(包含3个元素)".那么为什么案例2不一样.这是否意味着声明:

char arr[3] = "abc";

char arr[3] = { 'a', 'b', 'c' } ; 是不同的.

Som*_*ude 2

如果数组的大小大于您显式初始化的元素数量,则其余元素将被零初始化。

所以你可以有例如

char arr[50] = { 'a' };
Run Code Online (Sandbox Code Playgroud)

第一个元素 ( arr[0]) 将被初始化为包含'a',其余 49 个元素将全部为零。

另请注意,当您定义一个包含三个元素的数组(如问题中的后两个示例)然后使用时,arr[3]== '\0'您的索引超出范围并具有未定义的行为

此外,不在数组内的内存内容是不确定的。你不能依赖它有任何价值。

最后,

char arr[3] = "abc";
Run Code Online (Sandbox Code Playgroud)

char arr[3] = { 'a', 'b', 'c' };
Run Code Online (Sandbox Code Playgroud)

实际上是相同的,都创建一个包含三个元素的数组,其内容为'a''b''c'

  • @Avi 未定义的行为是未定义的。 (2认同)