通过“ \ 0”而不是memset()批量初始化char数组

时间:2019-06-03 13:58:49

标签: c++ c arrays char

通常由memset初始化的char数组批量。

我在项目代码中发现了由"\0"初始化的char数组。我也进行了编译和检查,一切正常。

我的问题是这是批量初始化char数组的正确方法吗?

例如:

char a[20]="\0";
printf("%s", a);

3 个答案:

答案 0 :(得分:7)

是的,这是正确的方法之一。

对于

引用C11,第§6.7.9章

  

如果用大括号括起来的列表中的初始化程序少于元素或成员   用来初始化已知数组的字符串文字中的总计或更少的字符   大于数组中元素的大小,余数应为   初始化与具有静态存储持续时间的对象相同。

,关于static存储变量的初始化,

  

如果具有静态或线程存储持续时间的对象未初始化   明确地,然后:

     

-如果具有指针类型,则将其初始化为空指针;

     

-如果具有算术类型,则将其初始化为(正数或无符号)零;

     

-如果是集合,则根据这些规则(递归)初始化每个成员,   并且任何填充都被初始化为零位;

     

-如果是一个联合,则根据以下内容(递归)初始化第一个命名成员   规则,并且任何填充都初始化为零位;

对于

在第{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的对象很小。)