将结构初始化为0

Daa*_*mer 104 c struct initialization

如果我有这样的结构:

typedef struct
{
    unsigned char c1;
    unsigned char c2;
} myStruct;
Run Code Online (Sandbox Code Playgroud)

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

myStruct _m1 = {0};
Run Code Online (Sandbox Code Playgroud)

或者我需要将每个成员显式初始化为0吗?

myStruct _m2 = {0,0};
Run Code Online (Sandbox Code Playgroud)

Alo*_*ave 128

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

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

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

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

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

  • 用于初始化的@FullDecent空大括号是GNU扩展. (12认同)
  • @艾德尼亚。我不同意。我已经知道 `foo = {0}` 是什么意思。如果我看到`foo = ZERO_FULL`,我就必须grep 以获取ZERO_FULL 的定义。 (11认同)
  • 另外,我使用`= {};`但是我不确定这是否有效. (8认同)
  • @alias65536 问题被标记为 C 而不是 C++。 (4认同)
  • 我认为为了在你的答案中明确,你应该添加**“并且‘具有静态存储持续时间的对象’被初始化为零。因此,大括号括起来的列表中未提及的结构的任何成员应自动初始化为零."** (3认同)
  • 这不仅仅是一个偏好问题——可维护性也很重要。如果结构发生变化(添加或删除成员),则“_m2”示例在有更多成员时意义不大,并且如果成员数量减少则必须更新。 (2认同)
  • 我收到一个错误:“缺少初始化程序[-Werror = missing-braces]的花括号”可能是由于成员数组所致:/ (2认同)

Bas*_*tch 28

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

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

memset(&m, 0, sizeof(myStruct));
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • @Steven:我只能想到晦涩难懂的平台.C FAQ有一个平台列表,其中有一个"NULL"指针并非全是"0"位:http://c-faq.com/null/machexamp.html.然后有可能平台没有使用IEEE 754来表示浮点值,但是使用了一些其他没有全"0"位"0.0"值的表示 - 但不可否认我知道没有这样的平台. (6认同)
  • 不能保证将结构的所有字节设置为"0"将等同于使用"0"初始化所有struct成员.在许多平台上,这将是真实的,但不是普遍的. (5认同)
  • 桑德,你能举个例子吗?真正的好奇心。(显然,不普遍正确并不一定意味着存在易于解释的例外,但如果存在......) (3认同)
  • *C*标准允许空指针(或零浮点数)在内存中由除了所有零位之外的其他内容表示.很少和奇怪的实现正在这样做(我不能说出任何名称). (2认同)
  • -1,您可能会发现OP要求的初始化很难看,但这正是标准所预见的,并且所有编译器都可以轻松优化。那么,形式“{}”在 C 语言中无效,只能在 C++ 中使用。 (2认同)

dir*_*tly 18

见§6.7.9初始化:

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

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

myStruct _m1 = {.c2 = 0, .c1 = 1};
Run Code Online (Sandbox Code Playgroud)


小智 6

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

myStruct _m1 = {0};
Run Code Online (Sandbox Code Playgroud)

当我尝试这个时:

myStruct _m1 = {0xff};
Run Code Online (Sandbox Code Playgroud)

仅第 1 个字节设置为0xff,其余字节设置为0。所以我不会养成使用它的习惯。

  • 该问题明确询问将结构元素初始化为 0,以及最快的方法。因此,要使用其他值初始化元素,您必须使用传统方法 (3认同)