我只是想知道为什么我在下面的代码输出是abcdef def
而不是abc def
。
main()
{
char array1[3]="abc";
array1[3]='\0';
char array2[3]="def";
array2[3]='\0';
printf("%s %s", array1, array2);
}
答案 0 :(得分:6)
char array1[3]="abc";
array1[3]='\0';
char array2[3]="def";
array2[3]='\0';
array1[3]='\0';
和array2[3]='\0';
语句访问数组超出范围并调用未定义的行为。 3个元素数组的最后一个元素是array1[2]
而不是array[3]
。
要修复程序,请将数组声明为:
char array1[]="abc";
char array2[]="def";
并且不要手动添加null终止符,因为它已经包含在上面的声明中。
修改强>:
其他一些答案错误地假设
char array1[3]="abc";
会在数组外部写一个尾随空字符。实际上在此初始化中没有写入尾随空字符。声明等同于:
char array1[3]= {'a', 'b', 'c'};
答案 1 :(得分:3)
当你这样做时:
char array1[3]="abc";
然后array1[3]
超出范围。
你应该这样做:
char array1[4]="abc"; //Remember the '\0'
^^^
请注意,'\0'
将以这种方式添加。
另请注意,当您拥有大小为N
的数组时,索引将从0
到N - 1
。
答案 2 :(得分:1)
在您的代码中
main()
{
char array1[3]="abc"; //Undefined ,when you access this using printf() with %s
array1[3]='\0'; //here you are storing value which is out of bound in nature
char array2[3]="def"; //same as above
array2[3]='\0'; //same as above
printf("%s %s", array1, array2);
}
memory:
---------------
| a | b | c |\0|
----------------
最后\ 0你所投入的比你分配的空间更多。
溶液:
main()
{
char array1[4]="abc";
//array1[3]='\0'; //no need
char array2[4]="def";
// array2[3]='\0'; //no need
printf("%s %s", array1, array2);
}
它将提供所需的输出
答案 3 :(得分:0)
这是一个糟糕的代码!发生的事情如下:
编译器为2x3字符分配空间。
main()
{
char array1[3]="abc"; //Will write "abc" in array 1 AND \0 in array2[0]
array1[3]='\0'; //Out of array!!! (Re)writing \0 in array2[0]
char array2[3]="def"; //Will write "def" in array2 AND \0 after array2 space, POTTENCIALLY corrupting code!
array2[3]='\0'; //\0 (re)wrote after array2, POTTENCIALLY corrupting code!
你在内存中的内容是7个字节(只分配了6个):“abcdef \ 0”。 Pointes仍然可以:array1指向“a”,array2指向“d”。 在C标准库中,字符串大小由结束零终止符确定。所以当你printf array1时,它会读到“abcdef”直到\ 0。