我只是想知道为什么我下面这段代码的输出是abcdef def
而不是abc def
.
main()
{
char array1[3]="abc";
array1[3]='\0';
char array2[3]="def";
array2[3]='\0';
printf("%s %s", array1, array2);
}
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";
并且不要手动添加空终止符,因为它已经包含在上面的声明中。
编辑:
其他一些答案错误地假设
char array1[3]="abc";
将在数组外写入一个尾随空字符。实际上,在此初始化中没有写入尾随空字符。声明等价于:
char array1[3]= {'a', 'b', 'c'};
当你这样做时:
char array1[3]="abc";
然后array1[3]
就出界了。
你应该做:
char array1[4]="abc"; //Remember the '\0'
^^^
请注意,'\0'
将以这种方式添加。
另请注意,当您有大小数组时N
,索引是 from 0
to N - 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);
}
它将提供所需的输出
这是一个糟糕的代码!正在发生的事情如下:
编译器为 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”。点仍然可以:array1 指向“a”,array2 指向“d”。在 C 标准库中,字符串大小由结束零终止符确定。因此,当您 printf array1 时,它将读取“abcdef”,直到 \0。