ChatGPT解决这个技术问题 Extra ChatGPT

将结构初始化为 0

如果我有这样的结构:

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

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

myStruct _m1 = {0};

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

myStruct _m2 = {0,0};
注意:如果结构有填充字节(由于对齐),那么这些都不能保证它们被初始化。在将结构写入外部存储、网络或与 memcmp 进行比较时,这可能很重要。在这种情况下,应该使用 memset

C
Community

第一个是最简单的(涉及更少的输入),并且可以保证工作,所有成员都将设置为 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 的定义。
B
Basile Starynkevitch

如果数据是静态或全局变量,默认填零,所以声明一下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 常见问题解答有一个平台列表,这些平台的 NULL 指针并非全部为 0 位:c-faq.com/null/machexamp.html。然后有可能该平台没有使用 IEEE 754 来表示浮点值,而是使用了一些没有全 00.0 值的其他表示 - 但我承认我知道没有这样的平台。
C
Cœur

参见§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。
D
DuDa

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

myStruct _m1 = {0};

当我尝试这个时:

myStruct _m1 = {0xff};

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


该问题明确询问将结构元素初始化为0,以及最快的方法。因此,要使用其他值初始化元素,您必须使用传统方法
谢谢你说的很明显。它仍然具有误导性,因为当有人查找 assignment 时,他们可能不想将某些内容设置为 0 而是设置为其他内容,他们会看到此方法并可能会尝试使用它。我不确定你是否完全理解我来自哪里,但我试图解释它。