[英]Bulk initialize the char array by “\0” instead of memset()
Usually char array bulk initialized by memset
. 通常由
memset
初始化的char数组批量。
I found in my project code the char array initialized by "\\0"
. 我在项目代码中找到了由
"\\0"
初始化的char数组。 Also I compiled and checked, it's Working fine. 我编译和检查,它的工作正常。
My question is this is a right way to bulk initialize the char array? 我的问题是这是批量初始化char数组的正确方法吗?
Eg: 例如:
char a[20]="\0";
printf("%s", a);
Yes, this is one of the correct ways. 是的,这是正确的方法之一。
Quoting C11
, chapter §6.7.9 引用
C11
,章节§6.7.9
If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.
如果括号括起的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小的数组的字符串文字中的字符数少于数组中的元素,则聚合的其余部分应为隐式初始化与具有静态存储持续时间的对象相同。
and, regarding the initialization for static
storage variables, 并且,关于
static
存储变量的初始化,
If an object that has static or thread storage duration is not initialized explicitly, then:
如果未显式初始化具有静态或线程存储持续时间的对象,则:
— if it has pointer type, it is initialized to a null pointer;
- 如果它有指针类型,则将其初始化为空指针;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
- 如果它有算术类型,则初始化为(正或无符号)零;
— if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;
- 如果它是一个聚合,则根据这些规则初始化(递归)每个成员,并将任何填充初始化为零比特;
— if it is a union, the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;
- 如果它是一个联合,则根据这些规则初始化(递归)第一个命名成员,并将任何填充初始化为零位;
Quoting C++17
, chapter § 11.6.2 引用
C++17
,第11.6.2节
If there are fewer initializers than there are array elements, each element not explicitly initialized shall be zero-initialized.
如果初始化器的数量少于数组元素,则未明确初始化的每个元素都应进行零初始化。
So, in your case, 所以,在你的情况下,
char a[20]="\0";
try to initialize the a[0]
to '\\0'
, a[1]
to '\\0'
(for null-terminator) and the remaining as 0
. 尝试将
a[0]
初始化为'\\0'
, a[1]
初始化为'\\0'
(对于空终止符),剩余为0
。 FWIW, '\\0'
has a decimal value of 0
, so in this case, all the elements in the array are going to have a value 0
. FWIW,
'\\0'
的十进制值为0
,因此在这种情况下,数组中的所有元素都将具有值0
。
Some similar initialization statements would be 一些类似的初始化语句将是
char a[20] = "";
char a[20] = {0};
char a[20] = {'\0'};
For C++
, as suggested in the other answer , including all the previous syntax, 对于
C++
,正如其他答案中所建议的 ,包括所有以前的语法,
char a[20] = {};
would also work. 也会有用。
It works almost, in a curious way, by accident and is, in my opinion, an exercise in obfuscation. 它几乎是以奇怪的方式,偶然地工作,在我看来,是一种混淆的练习。 An explanation:
一个解释:
In C++ "\\0"
is a const char[2]
literal with value '\\0'
(Octal constant with value 0) followed by a NUL-terminator, ie both 0 values. 在C ++中,
"\\0"
是一个const char[2]
文字,其值为'\\0'
(八进制常量值为0),后跟一个NUL终结符,即两个0值。 In C it's a char[2]
constant with the same value. 在C中,它是一个具有相同值的
char[2]
常量。
Initialising a
to that also causes the other elements of a
to be initialised to 0 too (by the C and C++ standards, the other elements are initialised as per static
storage duration). 初始化
a
到也导致的其它元件a
将被初始化为0太(由C和C ++标准,其它元件被初始化为每static
存储持续时间)。
In C++ writing char a[20] = {}
is sufficient, in C you need at least char a[20] = {0}
. 在C ++中编写
char a[20] = {}
就足够了,在C中你至少需要char a[20] = {0}
。
Yes. 是。 It works because using an initializer to initialize some subobjects (here you're explicitly initializing the first two) causes the rest to be zero-initialized (more precisely initialized as if they were static--namely pointers get set to the null pointer constant even if it isn't all bits zero on the given architecture).
它的工作原理是因为使用初始化器来初始化一些子对象(这里你明确地初始化前两个)导致其余部分被零初始化(更精确地初始化就像它们是静态的一样 - 即指针被设置为空指针常量甚至如果在给定的体系结构中并非所有位都为零)。
A more general versions of this is: 更通用的版本是:
any_composite_type x={0};
Compilers may and do still implement such initializations with a call to memset
编译器可能并且仍然通过调用
memset
来实现这样的初始化
Example: 例:
struct foo{
char big[1000];
};
void take_foo(struct foo*);
int main()
{
struct foo obj ={0};
take_foo(&obj);
}
compiled with clang for x86-64: 用clang for x86-64编译:
main: # @main
push rbx
sub rsp, 1008
lea rbx, [rsp + 8]
mov edx, 1000
mov rdi, rbx
xor esi, esi
call memset
mov rdi, rbx
call take_foo
xor eax, eax
add rsp, 1008
pop rbx
ret
(In a similar fashion, they may and do replace explicit calls to memset
with inlined assembly if they see the object to be memset
ted is small.) (以类似的方式,如果他们看到要设置为
memset
的对象很小,他们可以并且确实用内联汇编替换对memset
显式调用。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.