0

我只是想知道为什么我下面这段代码的输出是abcdef def而不是abc def.

 main()
{
    char array1[3]="abc";
    array1[3]='\0';    

    char array2[3]="def";
    array2[3]='\0';

    printf("%s  %s", array1, array2);
}
4

4 回答 4

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";

并且不要手动添加空终止符,因为它已经包含在上面的声明中。

编辑

其他一些答案错误地假设

char array1[3]="abc"; 

将在数组外写入一个尾随空字符。实际上,在此初始化中没有写入尾随空字符。声明等价于:

char array1[3]= {'a', 'b', 'c'}; 
于 2013-07-18T09:34:39.510 回答
3

当你这样做时:

char array1[3]="abc";

然后array1[3]就出界了。

你应该做:

char array1[4]="abc"; //Remember the '\0'
           ^^^

请注意,'\0'将以这种方式添加。

另请注意,当您有大小数组时N,索引是 from 0to N - 1

于 2013-07-18T09:34:50.217 回答
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);
}

它将提供所需的输出

于 2013-07-18T09:48:46.033 回答
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”。点仍然可以:array1 指向“a”,array2 指向“d”。在 C 标准库中,字符串大小由结束零终止符确定。因此,当您 printf array1 时,它将读取“abcdef”,直到 \0。

于 2013-07-18T09:56:03.793 回答