将结构初始化为 0
Posted
技术标签:
【中文标题】将结构初始化为 0【英文标题】:Initializing a struct to 0 【发布时间】:2012-06-24 12:20:24 【问题描述】:如果我有这样的结构:
typedef struct
unsigned char c1;
unsigned char c2;
myStruct;
将此结构初始化为 0 的最简单方法是什么? 以下就够了吗?
myStruct _m1 = 0;
或者我是否需要将每个成员显式初始化为 0?
myStruct _m2 = 0,0;
【问题讨论】:
注意:如果结构有填充字节(由于对齐),那么这些都不能保证它们被初始化。在将结构写入外部存储、网络或与memcmp
进行比较时,这可能很重要。在这种情况下,应该使用memset
。
【参考方案1】:
第一个是最简单的(涉及更少的输入),并且保证可以工作,所有成员都将设置为0
[Ref 1]。
第二个更具可读性。
选择取决于用户偏好或您的编码标准要求的偏好。
[参考 1]参考 C99 标准 6.7.8.21:
如果大括号括起来的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则剩余的聚合应隐式初始化,与具有静态存储持续时间的对象相同。
好读:C and C++ : Partial initialization of automatic structure
【讨论】:
另外,我正在使用= ;
但是我不确定这是否有效。
@FullDecent 用于初始化的空大括号是 GNU 扩展。
@alias65536 问题标记为 C 而不是 C++。
我收到一个错误:“初始化器周围缺少大括号 [-Werror=missing-braces]”可能是因为成员数组:/
@Edenia。我不同意。我已经知道foo = 0
是什么意思。如果我看到foo = ZERO_FULL
,我必须用 grep 查找 ZERO_FULL 的定义。【参考方案2】:
如果数据是静态或全局变量,默认填零,所以声明myStruct _m;
如果数据是局部变量或堆分配区域,则使用memset
清除它,例如:
memset(&m, 0, sizeof(myStruct));
当前的编译器(例如 gcc
的最新版本)在实践中对其进行了很好的优化。仅当所有零值(包括空指针和浮点零)都表示为全零位时才有效,这在我所知道的所有平台上都是正确的(但 C 标准允许实现为 false ; 我不知道这样的实现)。
您或许可以编码myStruct m = ;
或myStruct m = 0;
(即使myStruct
的第一个成员不是标量)。
我的感觉是对局部结构使用memset
是最好的,它更好地传达了一个事实,即在运行时,必须做一些事情(而通常,全局和静态数据可以理解为在编译时初始化,运行时无需任何费用)。
【讨论】:
虽然不能保证将结构的所有字节设置为0
将等同于使用0
初始化所有结构成员。在许多平台上都是如此,但并非普遍适用。
你能分享一个例子吗,桑德?真正的好奇心。 (显然,并非普遍正确并不一定意味着存在易于解释的异常,但如果存在......)
C 标准允许空指针(或零浮点数)在内存中由非全零位表示。很少和奇怪的实现这样做(我不能说出任何名字)。
-1,您可能会发现 OP 要求的初始化很丑陋,但这正是标准所预见的,并且所有编译器都可以轻松优化。那么,
形式不是有效的 C,但只能在 C++ 中使用。
@Steven :我只能想到晦涩和/或旧的平台。 C FAQ 有一个平台列表,这些平台有一个NULL
指针,不是所有0
位:c-faq.com/null/machexamp.html。然后有可能该平台没有使用 IEEE 754 来表示浮点值,而是使用了一些其他的表示,这些表示不具有全部 0
位 0.0
值 - 但我承认我知道没有这样的平台。跨度>
【参考方案3】:
参见 §6.7.9 初始化:
21 如果大括号括起来的列表中的初始值设定项少于元素或成员的数量 用于初始化已知数组的字符串文字中的聚合或更少字符 大小超过数组中的元素,聚合的其余部分应为 隐式初始化与具有静态存储持续时间的对象相同。
所以,是的,它们都有效。请注意,在 C99 中也可以使用一种新的初始化方式,称为指定初始化:
myStruct _m1 = .c2 = 0, .c1 = 1;
【讨论】:
最值得注意的是这已经是 C89:open-std.org/JTC1/SC22/WG14/www/docs/n1124.pdf#page=139(对特定信号处理目标很重要) 但请注意,它直观地适用于 0,但如果您执行 1,则不太清楚。很容易认为它将所有内容都设置为 1,但它只会将第一个设置为 1,并隐式初始化其余部分,因此您最终可能会得到 1,0。【参考方案4】:我也认为这会起作用,但它具有误导性:
myStruct _m1 = 0;
当我尝试这个时:
myStruct _m1 = 0xff;
只有第一个字节被设置为0xff
,其余的被设置为0
。所以我不会养成使用这个的习惯。
【讨论】:
该问题明确询问将结构元素初始化为 0,以及最快的方法。因此,要使用其他值初始化元素,您必须使用传统方法 感谢您的陈述。它仍然具有误导性,因为当有人查找 assignment 时,他们可能不想将某些内容设置为 0 而是设置为其他内容,他们会看到此方法并可能尝试使用它。我不确定你是否完全理解我来自哪里,但我试图解释一下。以上是关于将结构初始化为 0的主要内容,如果未能解决你的问题,请参考以下文章