142

如果我有这样的结构:

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

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

myStruct _m1 = {0};

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

myStruct _m2 = {0,0};
4

4 回答 4

164

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

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

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

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

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

于 2012-06-22T07:51:25.030 回答
40

如果数据是静态或全局变量,默认填零,所以声明一下即可myStruct _m;

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

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

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

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

我的感觉是使用memset本地结构是最好的,它更好地传达了这样一个事实,即在运行时,必须做一些事情(而通常,全局和静态数据可以理解为在编译时初始化,在运行时没有任何成本) .

于 2012-06-22T07:51:59.040 回答
23

参见§6.7.9 初始化:

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

所以,是的,它们都有效。请注意,在 C99 中也可以使用一种新的初始化方式,称为指定初始化:

myStruct _m1 = {.c2 = 0, .c1 = 1};
于 2012-06-22T07:54:53.890 回答
9

我也认为这会起作用,但它具有误导性:

myStruct _m1 = {0};

当我尝试这个时:

myStruct _m1 = {0xff};

只有第一个字节设置为0xff,其余字节设置为0。所以我不会养成使用这个的习惯。

于 2020-11-18T02:18:26.713 回答