如果我在相应 char 数组的声明中为其提供额外的元素,是否会自动设置 NULL?

Is NUL set automatically, if I provide an extra element for it in the declaration of the respective char array?

本文关键字:是否 元素 NULL 设置 char 数组 声明 如果      更新时间:2023-10-16

如果我为它提供一个额外的元素,但将其保留在初始化字符串中,''会自动设置吗?

喜欢:

char a[6] = {"Hello"};   // <- Is NUL set here automatically?

我用C和C++做了一个实验:

三:

#include <stdio.h>
int main()
{
char NEWYEAR[16] = {"Happy New Year!"};
printf("%sn",NEWYEAR);
return 0;
}

输出:

Happy New Year! 

C++:

#include <iostream>
int main()
{
char NEWYEAR[16] = {"Happy New Year!"};
std::cout << NEWYEAR << std::endl;
return 0;
}

输出:

Happy New Year! 

编译器没有抛出错误或警告,结果符合预期。所以它似乎可以正常工作。但事实真的是这样吗?

  • 这样做一切都正确吗?
  • 这可能是糟糕的编程风格吗?
  • 这会导致任何问题吗?

它比这更复杂

char a[6] = "Hello";

将初始化字符数组以Hello,因为Hello有一个隐式终止零。

char a[6] = "Hello";

在 C 中有效,但在C++中无效,因为文本长度为7个字符,同时具有隐式终止符和显式嵌入的 null 字符。C 允许文本删除隐式终止符。C11 6.7.9p14:

  1. 字符类型的数组可以通过字符串文本或 UTF-8 字符串文本初始化,可以选择括在大括号中。字符串文本的连续字节(如果有空间或数组大小未知,则包括终止 null 字符(初始化数组的元素。
char a[5] = "Hello";

将是有效的 C,导致 char 数组不包含以零结尾的字符串。它在C++中无效。

(强调我的(。这意味着如果数组中有空间,可以选择添加隐式终止 null

,但不需要这样做。和

char a[4] = "Hello";

在 C 中会带来字面上的地狱,因为虽然它在 C 中是约束违规(C11 6.7.9p2(,

  1. 任何初始值设定项都不得尝试为未包含在要初始化的实体中的对象提供值。

尝试初始化的元素多于列表中的项,通常只会在许多编译器中生成警告,然后经常被程序员忽略。第14款对隐含终止符以外的任何其他内容都没有例外。

最后

char a[7] = "Hello";

在 C 和 C++ 中都会导致一个包含字符Hello7个元素的字符数组,因为在具有初始值设定项的数组中,未由初始值设定项显式初始化的元素将被默认初始化,就像通过文字0初始化一样。在这种情况下,前 6 个元素将被显式初始化,第 7 个元素将被隐式初始化。


考虑到在 C 中静默截断终止符的可能性,最好省略数组大小并写入

char a[] = "Hello";

这会将a声明为 6 个元素的数组,就像char a[6] = "Hello";一样,但您不能错误地键入数组大小。

如果有空终止符的空间,那么它将被添加。

在 C(但不是 C++(中,如果数组的大小是除 null 终止符之外的字符串长度,则不会添加 null 终止符。所以例如

char a[5] = "Hello";

有效,但数组中不会有 null 终止符。

提供小于字符串长度的大小是无效的。

相关文章: