【发布时间】:2019-01-09 11:20:08
【问题描述】:
在阅读有关打印字符串的信息时,我看到了一条语句 "printf 一个接一个地写入字符,直到遇到一个空字符。如果空字符丢失,printf 继续超过字符串直到最终在内存中找到一个空字符”。 所以我写了一些代码:
案例 1:
char arr[4] = { 'a', 'b', 'c' } ;
if (arr[3]== '\0')
printf ("%s",arr);
输出为abc。
这是否意味着编译器已自动将'\0' 存储在arr[3]。因为按照说法,printf只有遇到'\0'才会终止。
案例 2:
char arr[3] = { 'a', 'b', 'c' } ;
if (arr[3]== '\0')
printf ("%s",arr);
虽然不存在数组块arr[3],但输出还是abc,那为什么不是错误呢? printf 也打印了abc 并停止了,这意味着它一定遇到了'\0'。那么这是否意味着编译器在arr[2] 之后创建一个额外的数组块来存储'\0'。如果是这样,那么数组大小必须增加到4 个字节(每个char 类型字符1 个字节)。但是执行语句printf ("%d",sizeof (arr));给了我输出3,表明数组大小没有增加,表明没有arr[3]。那么if (arr[3]== '\0')这个条件是怎么成真的呢?
案例 3:
char arr[3] = "abc";
if (arr[3]== '\0')
printf ("%s",arr);
现在它给了我一个错误,说 “数组索引 3 超出了结尾(包含 3 个元素)”。 那么为什么这与 case 2不一样>。这是否意味着声明:
char arr[3] = "abc"; 和
char arr[3] = { 'a', 'b', 'c' } ; 不同。
【问题讨论】:
-
"[...] 那为什么不是错误?" 这是错误。只是 C 不需要编译器或运行时系统来检测错误。任何事情都有可能发生。
-
那么不同编译器的答案是否会有所不同?
-
同一个编译器的不同版本,不同的编译选项,或者只是多次运行同一个程序,它们甚至可能不同。没有保证,也没有期望的一致性。
-
我现在明白了。看来我在这个话题上想得太多了。
标签: c arrays string initialization c-strings