【问题标题】:Is an array initialized from a string literal identical to one initialized from individual characters?从字符串文字初始化的数组是否与从单个字符初始化的数组相同?
【发布时间】:2018-07-17 08:59:11
【问题描述】:

有两个数组:

char a[] = "Nice you!";     
char b[] = {'N', 'i', 'c', 'e', ' ', 'y', 'o', 'u', '!'};

我认为a[] 和b[] 完全一样。所以这是我的代码,看看每个数组的最后一个元素之后是什么:

#include <stdio.h>

int main(void)
{
    char a[] = "Nice you!";
    char b[] = {'N', 'i', 'c', 'e', ' ', 'y', 'o', 'u', '!'};

    char *pa;
    char *pb;
    pa = a;
    pb = b;
    printf("*(pa + 9)= %d\n", *(pa + 9));
    printf("*(pb + 9)= %d\n", *(pb + 9));

    return 0;
}

我的理解正确吗?我不太确定,需要确认。

【问题讨论】:

  • a 以零字符结尾,因此比b 长一个字符。
  • 通常,*(pa + 9) 使用数组索引表示法编写:pa[9]。
  • *(pb+9) 是未定义的行为,所以无论你得到什么输出都是没有意义的。

标签: c arrays string char


【解决方案1】:

几乎一样。

这个数组被NUL 终止:

char a[] = "Nice you!";

这个数组不是NUL 终止的:

char b[] = {'N', 'i', 'c', 'e', ' ', 'y', 'o', 'u', '!'};

数组a 的完全等价物是这样的:

char c[] = {'N', 'i', 'c', 'e', ' ', 'y', 'o', 'u', '!', 0};
                                                         ^ NUL terminator

在您的代码中,*(pb + 9) 访问数组之外​​的一个元素,因此您的程序的行为是未定义的。

【讨论】:

  • *NULL 终止符
  • @Alan 否定,不要混淆NULL 指针和NUL 字符,这是两个不同的东西。
  • @Alan 正如 Jabberwocky 所说,NULL 与 NUL 字符不同,但令人困惑的是,“空字符”与 NUL 相同。所以你可以说“NUL 终止符”或“空终止符”,两者都是正确的(但“NULL 终止符”不是)。 en.wikipedia.org/wiki/Null_character
【解决方案2】:

我认为 a[] 和 b[] 完全一样....

不,它们不一样。区别在于空终止字符。

这个

char a[] = "Nice you!";

等价于这个

char a[] = {'N', 'i', 'c', 'e', ' ', 'y', 'o', 'u', '!', '\0'};
                                                          ^^^ 

数组a 的最后一个元素是空字符 - '\0'。

在这

char b[] = {'N', 'i', 'c', 'e', ' ', 'y', 'o', 'u', '!'};

数组b的最后一个元素是'!'字符。

数组a 是一个字符串1),数组b 是字符数组。

当我们省略维度时,编译器会根据初始值设定项的大小为我们计算它。因此,数组a 的维度将是10,而数组b 的维度将是9。

在您的程序中,您正在使用指针pb 访问超出其大小的数组b:

printf("*(pb + 9)= %d\n", *(pb + 9));

1) C 语言没有原生的string 类型。在 C 中,字符串实际上是由空字符 '\0' 终止的一维字符数组。

【讨论】:

    【解决方案3】:

    我认为a[]和b[]完全一样

    不,它们不一样。

    char a[] = "Nice you!";
    

    是一个满足 C“字符串”所有条件的字符数组 - 它由 '\0' 字符隐式终止。您可以使用puts( a ) 等调用安全地打印它。

    char b[] = {'N', 'i', 'c', 'e', ' ', 'y', 'o', 'u', '!'};
    

    只是一个字符数组。它不以'\0' 字符隐式终止。尝试使用 puts( b ) 之类的内容打印它是未定义的行为。

    【讨论】:

      【解决方案4】:

      a 和 b 都是相同的。

      不过还是有一点点不同。数组a 将有Null Character 即\0 在它的最后一个位置。

      数组b 的最后一个索引处是!

      【讨论】:

      • NULL 和 \0 并不完全相同。 '\0' 是 int,但 NULL 通常是 (void*) 0。
      • 是的。对不起。我的意思是说空字符
      【解决方案5】:

      是的,a[] 和 b[] 几乎相同。

      这里,a[] 是一个字符串(尽管 C 中没有名为 string 的数据类型)。当您像这样声明 char a[] = "Nice you!" 并且编译器放置一个定义字符串结尾的 NUL ('\0') 时,它就像一个自动字符数组。

      但是,当您声明类似char b[] = {'N', 'i', 'c', 'e', ' ', 'y', 'o', 'u', '!'} 的内容时,这意味着您非常以自己的方式声明了一个字符数组,而不是以内置char 数组的方式。因此,它在 '!' 之后不包含 NUL ('\0')。事实上,第二个数组b[] 将打印的内容是未定义的。

      谢谢...!

      【讨论】:

      • 不是NULL,NULL是空指针常量;你的意思是NUL。
      • 你能告诉我NULL和NUL之间的区别吗?
      • NULL 是在&lt;stdlib.h&gt; 中定义的一个宏,它扩展为一个空指针常量。空字符也称为NUL。当然,标题中没有名称为 NUL 的常量 - 使用 0 或 '\0' 表示 that。
      猜你喜欢
      • 2014-08-23
      • 1970-01-01
      • 2011-12-11
      • 1970-01-01
      • 2021-04-16
      • 1970-01-01
      • 2016-03-15
      • 2013-04-29
      相关资源
      最近更新 更多