如果我有这样的结构:
typedef struct
{
unsigned char c1;
unsigned char c2;
} myStruct;
将此结构初始化为 0 的最简单方法是什么?以下就足够了吗?
myStruct _m1 = {0};
还是我需要将每个成员显式初始化为 0?
myStruct _m2 = {0,0};
memcmp
进行比较时,这可能很重要。在这种情况下,应该使用 memset
。
第一个是最简单的(涉及更少的输入),并且可以保证工作,所有成员都将设置为 0
[Ref 1]。
第二个更具可读性。
选择取决于用户偏好或您的编码标准要求的偏好。
[参考 1] 参考 C99 标准 6.7.8.21:
如果大括号括起来的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则聚合的其余部分应隐式初始化与具有静态存储持续时间的对象相同。
好读:
C and C++ : Partial initialization of automatic structure
如果数据是静态或全局变量,默认填零,所以声明一下myStruct _m;
如果数据是局部变量或堆分配区域,请使用 memset
清除它,例如:
memset(&m, 0, sizeof(myStruct));
当前的编译器(例如 gcc
的最新版本)在实践中对此进行了很好的优化。仅当所有零值(包括空指针和浮点零)都表示为全零位时才有效,这在我所知道的所有平台上都是正确的(但 C 标准允许实现为 false ; 我知道没有这样的实现)。
您或许可以编写 myStruct m = {};
或 myStruct m = {0};
(即使 myStruct
的第一个成员不是标量)。
我的感觉是,对局部结构使用 memset
是最好的,它更好地传达了这样一个事实,即在运行时,必须做一些事情(而通常,全局和静态数据可以理解为在编译时初始化,无需任何成本在运行时)。
0
将等同于使用 0
初始化所有结构成员。在许多平台上,这将是正确的,但不是普遍的。
{}
形式不是有效的 C,但只能在 C++ 中使用。
NULL
指针并非全部为 0
位:c-faq.com/null/machexamp.html。然后有可能该平台没有使用 IEEE 754 来表示浮点值,而是使用了一些没有全 0
位 0.0
值的其他表示 - 但我承认我知道没有这样的平台。
参见§6.7.9 初始化:
21 如果大括号括起来的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则聚合的剩余部分应隐式初始化与具有静态存储持续时间的对象相同。
所以,是的,它们都有效。请注意,在 C99 中也可以使用一种新的初始化方式,称为指定初始化:
myStruct _m1 = {.c2 = 0, .c1 = 1};
我也认为这会起作用,但它具有误导性:
myStruct _m1 = {0};
当我尝试这个时:
myStruct _m1 = {0xff};
只有第一个字节设置为 0xff
,其余字节设置为 0
。所以我不会养成使用这个的习惯。
不定期副业成功案例分享
= {};
但是我不确定这是否有效。foo = {0}
是什么意思。如果我看到foo = ZERO_FULL
,我必须使用 grep 来获取 ZERO_FULL 的定义。