繁体   English   中英

Bulk用“\\ 0”而不是memset()初始化char数组

[英]Bulk initialize the char array by “\0” instead of memset()

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

我在项目代码中找到了由"\\0"初始化的char数组。 我编译和检查,它的工作正常。

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

例如:

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

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

对于

引用C11 ,章节§6.7.9

如果括号括起的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小的数组的字符串文字中的字符数少于数组中的元素,则聚合的其余部分应为隐式初始化与具有静态存储持续时间的对象相同。

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

如果未显式初始化具有静态或线程存储持续时间的对象,则:

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

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

- 如果它是一个聚合,则根据这些规则初始化(递归)每个成员,并将任何填充初始化为零比特;

- 如果它是一个联合,则根据这些规则初始化(递归)第一个命名成员,并将任何填充初始化为零位;

对于

引用C++17 ,第11.6.2节

如果初始化器的数量少于数组元素,则未明确初始化的每个元素都应进行零初始化。


所以,在你的情况下,

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++ ,正如其他答案中所建议 ,包括所有以前的语法,

char a[20] = {};

也会有用。

它几乎是以奇怪的方式,偶然地工作,在我看来,是一种混淆的练习。 一个解释:

在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}

是。 它的工作原理是因为使用初始化器来初始化一些子对象(这里你明确地初始化前两个)导致其余部分被零初始化(更精确地初始化就像它们是静态的一样 - 即指针被设置为空指针常量甚至如果在给定的体系结构中并非所有位都为零)。

更通用的版本是:

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);
}

用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显式调用。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM