如果我在相应的 char 数组的声明中为其提供额外的元素,是否会自动设置 NUL?
Is NUL set automatically, if I provide an extra element for it in the declaration of the respective char array?
如果我为它提供一个额外的元素,但将它留在初始化字符串中,'[=15=]'
会自动设置吗?
喜欢:
char a[6] = {"Hello"}; // <- Is NUL set here automatically?
我用 C 和 C++ 做了一个实验:`
C:
#include <stdio.h>
int main()
{
char NEWYEAR[16] = {"Happy New Year!"};
printf("%s\n",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!
编译器没有抛出错误或警告,结果符合预期。所以它似乎可以正常工作。但这是真的吗?
- 这样做是否一切正确?
- 这可能是糟糕的编程风格吗?
- 这会导致任何问题吗?
如果空终止符有 space,则将添加它。
在C(但不是C++)中,如果数组的大小是除空终止符之外的字符串的长度,则不会添加空终止符。例如
char a[5] = "Hello";
有效,但数组中不会有空终止符。
提供小于字符串长度的大小是无效的。
比那个更复杂
char a[6] = "Hello";
会将字符数组初始化为 Hello[=16=]
,因为 Hello
有一个隐含的终止零。
char a[6] = "Hello[=11=]";
在 C 中有效,但在 C++ 中无效,因为文字长度为 7 个字符,同时具有隐式终止符和显式嵌入的空字符。 C 允许文字删除 implicit 终止符。 C11 6.7.9p14:
- An array of character type may be initialized by a character string literal or UTF-8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.
char a[5] = "Hello";
将是有效的 C,导致 不 包含零终止字符串的 char 数组。在C++中无效。
(强调我的)。这意味着如果数组中有空间,则可选择添加隐式终止 null,但不需要。
和
char a[4] = "Hello";
在 C 中会带来字面上的地狱,因为虽然在 C 中它是 约束违规 (C11 6.7.9p2),
- No initializer shall attempt to provide a value for an object not contained within the entity being initialized.
尝试初始化比列表中的项目更多的元素通常只会在许多编译器中生成 警告,然后经常被程序员忽略。第 14 段除了隐式终止符之外没有任何其他例外。
最后
char a[7] = "Hello";
在 C 和 C++ 中将导致包含字符 Hello[=18=][=18=]
的 7 个元素的字符数组,因为在具有初始值设定项的数组中,元素未明确初始化的 将被默认初始化,就好像由文字 0
初始化一样。在这种情况下,前 6 个元素将被显式初始化,第 7 个元素将被隐式初始化。
考虑到在 C 中静默截断终止符的可能性,最好省略数组大小并写入
char a[] = "Hello";
这会将 a
声明为包含 6 个元素的数组,就像 char a[6] = "Hello";
一样,但您不能输入错误的数组大小。
如果我为它提供一个额外的元素,但将它留在初始化字符串中,'[=15=]'
会自动设置吗?
喜欢:
char a[6] = {"Hello"}; // <- Is NUL set here automatically?
我用 C 和 C++ 做了一个实验:`
C:
#include <stdio.h>
int main()
{
char NEWYEAR[16] = {"Happy New Year!"};
printf("%s\n",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!
编译器没有抛出错误或警告,结果符合预期。所以它似乎可以正常工作。但这是真的吗?
- 这样做是否一切正确?
- 这可能是糟糕的编程风格吗?
- 这会导致任何问题吗?
如果空终止符有 space,则将添加它。
在C(但不是C++)中,如果数组的大小是除空终止符之外的字符串的长度,则不会添加空终止符。例如
char a[5] = "Hello";
有效,但数组中不会有空终止符。
提供小于字符串长度的大小是无效的。
比那个更复杂
char a[6] = "Hello";
会将字符数组初始化为 Hello[=16=]
,因为 Hello
有一个隐含的终止零。
char a[6] = "Hello[=11=]";
在 C 中有效,但在 C++ 中无效,因为文字长度为 7 个字符,同时具有隐式终止符和显式嵌入的空字符。 C 允许文字删除 implicit 终止符。 C11 6.7.9p14:
- An array of character type may be initialized by a character string literal or UTF-8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.
char a[5] = "Hello";
将是有效的 C,导致 不 包含零终止字符串的 char 数组。在C++中无效。
(强调我的)。这意味着如果数组中有空间,则可选择添加隐式终止 null,但不需要。
和
char a[4] = "Hello";
在 C 中会带来字面上的地狱,因为虽然在 C 中它是 约束违规 (C11 6.7.9p2),
- No initializer shall attempt to provide a value for an object not contained within the entity being initialized.
尝试初始化比列表中的项目更多的元素通常只会在许多编译器中生成 警告,然后经常被程序员忽略。第 14 段除了隐式终止符之外没有任何其他例外。
最后
char a[7] = "Hello";
在 C 和 C++ 中将导致包含字符 Hello[=18=][=18=]
的 7 个元素的字符数组,因为在具有初始值设定项的数组中,元素未明确初始化的 将被默认初始化,就好像由文字 0
初始化一样。在这种情况下,前 6 个元素将被显式初始化,第 7 个元素将被隐式初始化。
考虑到在 C 中静默截断终止符的可能性,最好省略数组大小并写入
char a[] = "Hello";
这会将 a
声明为包含 6 个元素的数组,就像 char a[6] = "Hello";
一样,但您不能输入错误的数组大小。