打印相同内容的三个字符串会产生不同的结果

时间:2014-10-01 11:03:01

标签: c arrays gcc

#include "stdio.h"

void main()
{
    char firstName[1] = "1";
    char middleName[1] = "1";
    char lastName[1] = "1";

    printf("%p\t%s\n",firstName,firstName);
    printf("%p\t%s\n",middleName,middleName);
    printf("%p\t%s\n",lastName,lastName);
}

我使用gcc 4.8.2编译此代码,令我困惑的是它为什么打印:

  

>   root @ ubuntu:〜#。/ main

0x7fff7124273d  111
0x7fff7124273e  11
0x7fff7124273f  1

我认为应该打印:

0x7fff7124273d  1
0x7fff7124273e  1
0x7fff7124273f  1

你能帮助我吗?

6 个答案:

答案 0 :(得分:6)

char firstName[1] = "1";

像这样初始化char数组是合法的,但它不是字符串,因为它不是以空值终止的。

"%s"中的

printf需要一个字符串,所以你所做的是未定义的行为。


我的猜测是,编译器将变量放在一起,它们之后的字节恰好是0,这可以解释发生了什么。但同样,它的未定义行为,任何事情都可能发生。

     '1'      '1'     '1'      0
     ^         ^       ^
 firstName     |       |
         middleName    |
                    lastName

答案 1 :(得分:4)

因为数组的大小是1而你正在分配长度为2的数组(字符串文字在末尾也有空字符\0)。因此,指针指向的字符串可能不是NULL终止字符串。你需要大小为2的数组。

char firstName[2] = "1";
char middleName[2] = "1";
char lastName[2] = "1";

char firstName[] = "1";
char middleName[] = "1";
char lastName[] = "1";

此外,请勿在C中使用void main。使用int main

答案 2 :(得分:2)

"1"实际上是两个字节大小 - '1', '\0' - 您忘记了C字符串是以空字符结尾的。空字节被初始化破坏。您的数组需要足够大才能包含初始化程序中的所有数据以避免这种情况。

答案 3 :(得分:2)

请记住, C风格的字符串以null结尾的数组,这意味着字符串后面应该有'\0'。可能对您有用的注意事项:

  • char firstName[2] = "1"; - 自行添加'\0',注意2而不是1。
  • char firstName[] = {'1'} - 添加'\0'
  • char firstName[2] = {'1'} - 添加 '\0'

您正在获取此输出,因为可能将字符放在一起,这是未定义的行为。

答案 4 :(得分:2)

代码

printf("%p\t%s\n",firstName,firstName);

打印的第一件事是数组firstName的基地址,

第二件事实际上是未定义的行为。要将任何字符数组作为字符串,它必须在结尾处具有空字符\0。你的数组只有1个字符长,并且包含'1'。所以你不要使用%s来打印它。

而不是%s使用%c来打印字符,例如\

printf("%p\t%c\n",firstName,firstName);

答案 5 :(得分:1)

在C中,字符串是NUL终止的,即字符串“1”是字符{'1',0}。你没有为终结者留出足够的空间,所以你的字符串被截断了,printf不知道它们的结束位置。

将它们定义为

会更好
char firstName[2] = "1";

最好做

char firstName[] = "1";

所以如果你应该处理一些长度超过1个字符的名字,编译器会为你计算适量的内存。