与字符串文字不同,为什么具有单独字符的字符数组不以空终止符结尾?
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 char
和 unsigned 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 的字符数组,因为这是对字符串(printf
、strcpy
等)进行操作的函数所期望的。所以编译器会自动为您添加空终止符。
当您提供由大括号分隔、逗号分隔的单引号分隔字符列表时,假设您不需要字符串,但您需要一个包含您指定的确切字符的数组。所以没有添加空终止符。
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 用于假定需要空终止符的非常特定类型的数组。
我在 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 char
和 unsigned 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 的字符数组,因为这是对字符串(printf
、strcpy
等)进行操作的函数所期望的。所以编译器会自动为您添加空终止符。
当您提供由大括号分隔、逗号分隔的单引号分隔字符列表时,假设您不需要字符串,但您需要一个包含您指定的确切字符的数组。所以没有添加空终止符。
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 用于假定需要空终止符的非常特定类型的数组。