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

Printing strings and concept of null character in C

在阅读有关打印字符串的内容时,我通过语句 "printf 逐个写入字符,直到遇到空字符。如果缺少空字符,printf 继续越过字符串的末尾,直到最终在内存中找到一个空字符。 所以我写了一些代码:

案例一:

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

if (arr[3]== '[=10=]')

printf ("%s",arr);

输出为 abc

这是否意味着编译器已自动将 '[=16=]' 存储在 arr[3]。因为按照声明,printf只有遇到'[=16=]'.

才会终止

案例二:

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

if (arr[3]== '[=11=]')

printf ("%s",arr);

尽管不存在数组块 arr[3],但输出再次为 abc,那么为什么这不是错误? printf 也打印了 abc 并停止了,这意味着它一定遇到了 '[=16=]'。这是否意味着编译器在 arr[2] 之后创建一个额外的数组块来存储 '[=16=]'。如果是这样,则数组大小必须增加到 4 个字节(每个 char 类型字符 1 个字节)。但是执行语句printf ("%d",sizeof (arr));给我输出3,显示数组大小没有增加,说明没有arr[3]。那么条件if (arr[3]== '[=28=]')是怎么变成真的呢?

案例三:

char arr[3] = "abc";

if (arr[3]== '[=12=]')

printf ("%s",arr);

现在它给我一个错误,说 "array index 3 is past the end (which contains 3 elements)"。 那么为什么 case 2 不一样呢?这是否意味着声明:

char arr[3] = "abc";

char arr[3] = { 'a', 'b', 'c' } ;不一样。

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

所以你可以有例如

char arr[50] = { 'a' };

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

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

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

最后,

char arr[3] = "abc";

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

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