将结构初始化为0


116

如果我有这样的结构:

typedef struct
{
    unsigned char c1;
    unsigned char c2;
} myStruct;

将此结构初始化为0的最简单方法是什么?以下足够吗?

myStruct _m1 = {0};

还是我需要将每个成员显式初始化为0?

myStruct _m2 = {0,0};

Answers:


142

第一个是最简单的(涉及较少的键入),并且保证可以工作,所有成员都将设置为0[Ref 1]
第二个更具可读性。

选择取决于用户喜好或您的编码标准要求的。

[参考1] 参考C99标准6.7.8.21:

如果用大括号括起来的列表中的初始化程序少于集合中的元素或成员,或者用于初始化已知大小的数组的字符串文字中的字符少于该数组中的元素,则该集合的其余部分应与具有静态存储持续时间的对象一样隐式初始化。

阅读:
C和C ++:自动结构的部分初始化


9
另外,我正在使用,= {};但是我不确定这是否有效。
William Entriken

15
@FullDecent用于初始化的空括号是GNU扩展。
a3f

2
@ alias65536这个问题被标记为C而不是C ++。
a3f

3
我收到一个错误:“在初始化程序[-Werror = missing-braces]周围缺少括号”可能是由于成员数组引起的:/
DrumM

3
@Edenia。我不同意。我已经知道是什么foo = {0}意思 如果看到foo = ZERO_FULL,则必须grep定义ZERO_FULL。
安德鲁·班布里奇

32

如果数据是静态或全局变量,则默认情况下为零填充,因此只需声明它 myStruct _m;

如果数据是局部变量或堆分配的区域,请使用以下命令清除它memset

memset(&m, 0, sizeof(myStruct));

当前的编译器(例如的最新版本gcc)在实践中对此进行了很好的优化。仅当所有零值(包括空指针和浮点零)都表示为全零位时才有效,这在我所知道的所有平台上都是正确的(但C标准允许在其中为false的实现;我不知道这种实现) 。

您也许可以编写myStruct m = {};myStruct m = {0};(即使的第一个成员myStruct不是标量)也可以。

我的感觉是,使用memset局部结构是最好的,它更好地传达了以下事实:在运行时必须要做一些事情(通常,可以将全局和静态数据理解为在编译时进行了初始化,而在运行时没有任何花费) 。


7
不能保证将struct的所有字节都设置0为等同于初始化所有struct成员0。在许多平台上,这都是正确的,但并非普遍如此。
Sander De Dycker 2012年

1
你能分享一个例子,桑德吗?真正的好奇心。(显然,并非普遍正确,不一定意味着存在易于解释的例外,但如果存在……)
Steven Fisher

2
所述Ç标准允许空指针(或零浮点数)在存储器由一些比全零位其他表示。很少有怪异的实现(我不能说任何)。
Basile Starynkevitch 2012年

-1,您可能会发现OP要求的初始化很丑陋,但这正是标准所预见的,并且所有编译器都可以轻松地对其进行优化。然后,该表格{}不是有效的C语言,仅在C ++中可用。
詹斯·古斯特

7
@Steven:我只能想到晦涩和/或旧的平台。C FAQ中有一个平台列表,该平台的NULL指针并不是全部0c-faq.com/null/machexamp.html。然后,该平台有可能没有使用IEEE 754来表示浮点值,而是使用了其他一些没有全0比特0.0值的表示形式-但我承认我不知道这种平台。
桑德·戴克

19

参见§6.7.9初始化:

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

所以,是的,他们两个都工作。请注意,在C99中,也可以使用一种称为指定初始化的新初始化方式:

myStruct _m1 = {.c2 = 0, .c1 = 1};

最值得注意的是,它已经是C89:open-std.org/JTC1/SC22/WG14/www/docs/n1124.pdf#page=139(特定信号处理目标的重要性)
Tobias
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.