问题
Is '\0'
set automatically if I provide an extra element for it, but left it in the initialization string?
Like:
char a[6] = {"Hello"}; // <- Is NUL set here automatically?
I´ve did one experiment with C and C++:`
C:
#include <stdio.h>
int main()
{
char NEWYEAR[16] = {"Happy New Year!"};
printf("%s\n",NEWYEAR);
return 0;
}
Output:
Happy New Year!
C++:
#include <iostream>
int main()
{
char NEWYEAR[16] = {"Happy New Year!"};
std::cout << NEWYEAR << std::endl;
return 0;
}
Output:
Happy New Year!
The compilers did not threw an error or warning and the result is as desired. So it might seem to work correctly. But is that really true?
- Is everything correct by doing so?
- Is this maybe bad programming style?
- Does this cause any issues?
回答1:
It is more complex than that
char a[6] = "Hello";
will initialize the array of characters to Hello\0
, because Hello
has an implicit terminating zero.
char a[6] = "Hello\0";
would be valid in C, but invalid in C++ because the literal is 7 characters long, having both an implicit terminator and explicit embedded null character. C allows the literal to drop the implicit terminator. 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";
would be valid C, resulting in a char array that does not contain a zero-terminated string. It is invalid in C++.
(emphasis mine). It means that the implicit terminating null is optionally added, if there is room in the array, but it does not need to.
And
char a[4] = "Hello";
in C would bring the literal Hell, because while it is a constraint violation in C (C11 6.7.9p2),
- No initializer shall attempt to provide a value for an object not contained within the entity being initialized.
attempting to initialize more elements than there are items in a list usually just generates a warning in many compilers and is then often ignored by programmers. The paragraph 14 does not have an exception for anything other besides the implicit terminator.
And lastly
char a[7] = "Hello";
in both C and C++ would result in a character array of 7 elements containing the characters Hello\0\0
, because in an array having an initializer, the elements not explicitly initialized by the initializer will be default-initialized as if initialized by literal 0
. In this case the first 6 elements will be initialized explicitly and the 7th implicitly.
Given the possibility of silently truncating the terminator in C, it is better to just omit the array size and write
char a[] = "Hello";
This will declare a
as array of 6 elements, just like char a[6] = "Hello";
, but you cannot mistype the array size.
回答2:
If there's space for the null-terminator then it will be added.
In C (but not C++) if the size of the array is the length of the string except the null-terminator, then the null-terminator will not be added. So e.g.
char a[5] = "Hello";
is valid, but there won't be a null-terminator in the array.
It's not valid to provide a smaller size than the string length.
来源:https://stackoverflow.com/questions/59551879/is-nul-set-automatically-if-i-provide-an-extra-element-for-it-in-the-declaratio