【问题标题】:Printing three strings with identical content gives different results打印三个具有相同内容的字符串会产生不同的结果
【发布时间】:2014-10-01 11:03:01
【问题描述】:
#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

你能帮帮我吗?

【问题讨论】:

  • 为 char 数组分配 2 个字节而不是 1 个字节。您总是必须为 '\0' 字符串终止符保留 1 个额外的字符
  • 记住字符串应该以'\0'结尾。
  • 您的阵列中没有足够的空间用于\0
  • 更改为char firstName[] = "1";。所有人都一样。
  • 谢谢大家,我明白了。:)

标签: c arrays gcc


【解决方案1】:
char firstName[1] = "1";

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

printf 中的"%s" 需要一个字符串,因此您所做的是未定义的行为。


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

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

【讨论】:

    【解决方案2】:

    因为数组的大小为 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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        请记住,C 风格的字符串null-terminated 数组,这意味着字符串后面应该有'\0'。可能对您有所帮助的注意事项:

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

        你得到这个输出是因为字符可能放在一起,这是未定义的行为。

        【讨论】:

        • 第二个和第三个例子完全一样。
        【解决方案5】:

        在你的代码中

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

        首先打印的是数组 firstName 的基地址,

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

        使用 %c 代替 %s 来打印字符,例如 \

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

        【讨论】:

          【解决方案6】:

          在 C 中,字符串以 NUL 结尾,即字符串“1”是字符 {'1', 0}。您没有为终止符留出足够的空间,因此您的字符串被截断并且 printf 不知道它们在哪里结束。

          最好将它们定义为

          char firstName[2] = "1";
          

          最好的做法

          char firstName[] = "1";
          

          因此,如果您应该处理一些名字超过 1 个字符的内存,编译器会为您计算出正确的内存量。

          【讨论】:

          • 修正错字。你确定 '\0' != (char)0 吗?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多