与字符串文字不同,为什么具有单独字符的字符数组不以空终止符结尾?

Why don't char arrays with separate chars end with a null-terminator unlike string literals?

我在 C++ 中使用 char 数组并编写了这个程序:

int main()
{

char text[] = { 'h', 'e', 'l', 'l', 'o' };  //arrays initialised like this 
                                            //will have a size of the number 
                                            //of elements that you see

char text2[] = "hello"; //arrays initialised like this will have a size of 
                        //the number of elements that you see + 1 (0 on the 
                        //end to show where the end is

cout << endl;

cout << "The size of the first array is: " << sizeof(text) << endl;

cout << endl;

for (int i = 0; i < sizeof(text); i++)
{
    cout << i << ":" << text[i] << endl;
}
cout << endl;

cout << "The size of the first array is: " << sizeof(text2) << endl;

cout << endl;

for (int i = 0; i < sizeof(text2); i++)
{
    cout << i << ":" << text2[i] << endl;
}
cout << endl;

cin.get();

return 0;
}

这个程序给我输出:

The size of the first array is: 5

0:h
1:e
2:l
3:l
4:o

The size of the first array is: 6

0:h
1:e
2:l
3:l
4:o
5:

我的问题是:与使用字符串文字初始化 char 数组不同,使用单独的字符初始化 char 数组末尾没有空终止符 (0) 是否有特殊原因?

花括号初始化器只是为一个数组提供指定的值(或者如果数组更大,其余的项目都是默认的)。即使项目是 char 值,它也不是字符串。 char只是最小的整数类型。

字符串文字表示 zero-terminated 值序列。

就这些了。

非正式地,它是 "foo" 形式的字符串文字中的第二个引号字符,它添加了 NUL-terminator.

在 C++ 中,"foo" 是一种 const char[4] 类型,在某些情况下 衰减 const char*

这就是语言的工作原理,仅此而已。它非常有用,因为它与所有将字符串建模为指向 char 数组 NUL-terminated 数组中第一个元素的指针的标准库函数很好地吻合。

char text[] = { 'h', 'e', 'l', 'l', 'o' }; 之类的东西拼接一个额外的元素会 真的 很烦人,它可能会在语言中引入不一致。例如,您会为 signed charunsigned char 做同样的事情吗?那么 int8_t 呢?

您可以通过多种方式自行终止它:

char text1[6] = { 'h', 'e', 'l', 'l', 'o' };
char text2[sizeof "hello"] = { 'h', 'e', 'l', 'l', 'o' };
char text3[] = "hello"; // <--- my personal favourite

当您指定一组用双引号分隔的相邻字符(字符串文字)时,假定您想要的是一个字符串。 C 中的字符串表示 null-terminated 的字符数组,因为这是对字符串(printfstrcpy 等)进行操作的函数所期望的。所以编译器会自动为您添加空终止符。

当您提供由大括号分隔、逗号分隔的单引号分隔字符列表时,假设您不需要字符串,但您需要一个包含您指定的确切字符的数组。所以没有添加空终止符。

C++ 继承了这个行为。

像这样的字符串文字 "hello" 具有常量字符数组类型,并按以下方式初始化

const char string_literal_hello[] = { 'h', 'e', 'l', 'l', 'o', '[=10=]' };

可以看出字符串文字的类型是const char[6]。它包含六个字符。

因此声明

char text2[] = "hello"; 

也可以这样写

char text2[] = { "hello" }; 

实际上是代替下面的声明

char text2[] = { 'h', 'e', 'l', 'l', 'o', '[=13=]' };

也就是说,一个字符串文字被用作字符数组的初始化器,它的所有字符都被用来初始化数组。

Is there a particular reason that initializing a char array with separate chars will not have a null terminator (0)

原因是因为语法...

Type name[] = { comma separated list };

...用于初始化数组任意类型。不只是 char.

"quoted string" 语法是 shorthand 用于假定需要空终止符的非常特定类型的数组。