通常由memset
初始化的char数组批量。
我在项目代码中发现了由"\0"
初始化的char数组。我也进行了编译和检查,一切正常。
我的问题是这是批量初始化char数组的正确方法吗?
例如:
char a[20]="\0";
printf("%s", a);
答案 0 :(得分:7)
是的,这是正确的方法之一。
对于c
引用C11
,第§6.7.9章
如果用大括号括起来的列表中的初始化程序少于元素或成员 用来初始化已知数组的字符串文字中的总计或更少的字符 大于数组中元素的大小,余数应为 初始化与具有静态存储持续时间的对象相同。
,关于static
存储变量的初始化,
如果具有静态或线程存储持续时间的对象未初始化 明确地,然后:
-如果具有指针类型,则将其初始化为空指针;
-如果具有算术类型,则将其初始化为(正数或无符号)零;
-如果是集合,则根据这些规则(递归)初始化每个成员, 并且任何填充都被初始化为零位;
-如果是一个联合,则根据以下内容(递归)初始化第一个命名成员 规则,并且任何填充都初始化为零位;
对于c++
在第{11.6.2章”中引用C++17
如果初始化程序少于数组元素,则每个未显式初始化的元素应为 零初始化。
所以,就您而言,
char a[20]="\0";
尝试将a[0]
初始化为'\0'
,将a[1]
初始化为'\0'
(对于空终止符),其余初始化为0
。 FWIW,'\0'
的十进制值为0
,因此,在这种情况下,数组中的所有元素都将具有值0
。
一些类似的初始化语句将会
char a[20] = "";
char a[20] = {0};
char a[20] = {'\0'};
对于C++
,如建议的in the other answer一样,包括所有以前的语法,
char a[20] = {};
也可以。
答案 1 :(得分:6)
它几乎以一种奇怪的方式偶然地起作用,我认为这是一种迷惑性的练习。解释:
在C ++中,"\0"
是一个const char[2]
文字,其值为'\0'
(八进制常量,值为0),后跟NUL终止符,即均为0值。在C语言中,它是一个char[2]
常量,具有相同的值。
初始化a
也会导致a
的其他元素也被初始化为0(根据C和C ++标准,其他元素按照static
的存储持续时间进行初始化。 )。
在C ++中编写char a[20] = {}
就足够了,在C中至少需要char a[20] = {0}
。
答案 2 :(得分:1)
是的。之所以有效,是因为使用初始化程序来初始化一些子对象 (这里您明确地初始化了前两个)使其余部分被零初始化(更精确地初始化为好像它们是静态的)-即即使指针不是全部为零,也将其设置为null指针常量。给定的架构)。
一个更通用的版本是:
any_composite_type x={0};
编译器可以并且仍然通过调用memset
示例:
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:
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
(以类似的方式,它们可以并且确实将对memset
的显式调用替换为
内联程序集,如果他们看到要memset
的对象很小。)