如何在C中将结构初始化为0

新手上路,请多包涵

这是一个在 C++ 中不起作用的相关 C 答案(作为结构的零初始值设定项): Initializing a struct to 0 。提出的解决方案之一是:

 myStruct _m1 = {0};

这在 C 中工作正常,但在 C++ 中不起作用。 :( :

错误:无法使用“int”类型的右值初始化“myScope::MyStruct”类型的成员子对象。

如何在 C++ 中对结构进行零初始化?

有关的:

  1. 在 C 中将结构初始化为 0: 将结构初始化为 0
  2. 更新:(一个相邻但不重复的问题,结果也非常有用) 使用空花括号进行初始化

也可以看看:

  1. [相邻相关,但适用于 C 样式数组, 而不是 结构] 如何将数组的所有成员初始化为相同的值?

对于投票结束这个问题的人:

我的问题不是这个其他问题的重复( 使用空花括号初始化),因为这个其他问题不是询问在 C++ 中初始化结构的各种方法以及为什么 C 方式不起作用,而是它们是问 为什么 C++ 关键字 explicit 破坏他们的初始化技术之一。两个截然不同的问题。不重复。

我问的后续问题:

  1. 为什么不将 C++ 结构初始化为 = {0} 将其所有成员设置为 0?

原文由 Gabriel Staples 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
1 个回答

在我们开始之前:

  1. 让我指出,围绕这种语法的很多混淆是因为在 C 和 C++ 中,您 可以 使用 = {0} 语法将 C 样式 数组 的所有成员初始化为零! 见这里: https ://en.cppreference.com/w/c/language/array_initialization。这有效:
   >  // z has type int[3] and holds all zeroes, as: `{0, 0, 0}`
   > int z[3] = {0};
   >
   > ```


   但是,这种语法对于 _structs_ 的工作方式 _并不_ 相同,它是与 C 样式数组完全不同的动物。

2. 另请参阅我在下面写下此答案后提出的后续问题: [为什么不将 C++ 结构初始化为 `= {0}` 将其所有成员设置为 0?](https://stackoverflow.com/q/61531928/4561887)


* * *

回到答案:

我想通了:要编译它,只需删除零:

# does NOT work myStruct _m1 = {0};

works!

myStruct _m1 = {};


它现在编译。但是,我运行了一堆测试来检查我的 [eRCaGuy_hello_world](https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world) 存储库中的 [struct_initialization.cpp](https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/cpp/struct_initialization.cpp) 文件中的一些内容,但这并没有将结构的所有元素初始化 _为零_!相反,它将结构初始化为其 _默认值_。要运行我的测试并亲自查看,请在上面克隆我的存储库并运行 [`eRCaGuy_hello_world/cpp/run_struct_initialization.sh`](https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/cpp/run_struct_initialization.sh) 。

假设你有这个结构:

typedef struct { int num1 = 100; int num2 = -100; int num3; int num4 = 150; } data_t;


_注意:上面的 `typedef` 是我在 C 而不是 C++ 中测试这些东西时遗留下来的(当然,默认的结构值在 C 中是不允许的)。对于 C++,这是首选:_

struct data_t { int num1 = 100; int num2 = -100; int num3; int num4 = 150; };


_所以请在我不必要地使用 `typedef` 来定义下面的结构的地方忽略它。_

无论如何,如果我声明上述之一 `data_t` 结构,然后执行以下操作:

data_t d2 = {}; printf(“d2.num1 = %i\nd2.num2 = %i\nd2.num3 = %i\nd2.num4 = %i\n\n”, d2.num1, d2.num2, d2.num3, d2.num4);


...输出将是:

d2.num1 = 100 d2.num2 = -100 d2.num3 = 0 d2.num4 = 150


而且我什至不确定 `d2.num3` 是否为零,因为它已初始化为零或未初始化,并且该内存位置恰好包含零。

如此处所述: [https](https://en.cppreference.com/w/cpp/language/zero_initialization) ://en.cppreference.com/w/cpp/language/zero_initialization ,您也可以这样做:

myStruct _m1{};


在上面的示例中,此代码:

data_t d2{}; printf(“d2.num1 = %i\nd2.num2 = %i\nd2.num3 = %i\nd2.num4 = %i\n\n”, d2.num1, d2.num2, d2.num3, d2.num4);


...会产生与我上面显示的相同的输出。

即使在将结构设置为 `= {0}` 的情况下也可以工作,例如:

// Does NOT do what I expected! Only sets the FIRST value in the struct to zero! // The rest seem to use default values. data_t d3 = {0}; printf(“d3.num1 = %i\nd3.num2 = %i\nd3.num3 = %i\nd3.num4 = %i\n\n”, d3.num1, d3.num2, d3.num3, d3.num4);


...输出仍然不是我的预期,因为它只将第 _一个_ 值设置为零! (我不明白为什么):

d3.num1 = 0 d3.num2 = -100 d3.num3 = 0 d3.num4 = 150


然而,在 C 风格的 **数组**(不是结构)上,这些语义可以正常工作。请在此处参考此答案( [如何将数组的所有成员初始化为相同的值?](https://stackoverflow.com/questions/201101/how-to-initialize-all-members-of-an-array-to-the-same-value/201116#201116) )。因此,在使用 C++ 时,以下几行都将 C 样式数组的所有元素都设置为零:

uint8_t buffer[100] = {0}; // sets all elements to 0 in C OR C++ uint8_t buffer[100] = {}; // sets all elements to 0 in C++ only (won’t compile in C)


_因此, [经过大量实验](https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/cpp/struct_initialization.cpp),看起来以下几种方法是零初始化结构 PERIOD 的唯一方法。如果您有不同的认识,请在此处发表评论和/或留下您自己的答案。_

## 在 C++ 中对结构进行零初始化的唯一方法是:

1. 明确:


 // C-style typedef'ed struct
typedef struct
{
    int num1 = 100;
    int num2 = -100;
    int num3;
    int num4 = 150;
} data_t;

// EXPLICITLY set every value to what you want!
data_t d1 = {0, 0, 0, 0};
// OR (using gcc or C++20 only)
data_t d2 = {.num1 = 0, .num2 = 0, .num3 = 0, .num4 = 0};

2. 使用 `memset()` 强制所有字节为零:


 data_t d3;
memset(&d3, 0, sizeof(d3));

3. 首先将所有默认值设置为零:


 // C-style typedef'ed struct
typedef struct
{
    int num1 = 0;
    int num2 = 0;
    int num3 = 0;
    int num4 = 0;
} data_t;

// Set all values to their defaults, which are zero in
// this case
data_t d4 = {};
// OR
data_t d5{}; // same thing as above in C++

// Set the FIRST value only to zero, and all the rest
// to their defaults, which are also zero in this case
data_t d6 = {0};

4. 为 C++ 结构编写构造函数


// 1. Using an initializer list
struct data
{
    int num1;
    int num2;
    int num3;
    int num4;

    data() :
        num1(0),
        num2(0),
        num3(0),
        num4(0) {}
};

data d7; // all values are zero

// OR: 2. manually setting the values inside the constructor
struct data
{
    int num1;
    int num2;
    int num3;
    int num4;

    data()
    {
        num1 = 0;
        num2 = 0;
        num3 = 0;
        num4 = 0;
    }
};

data d8; // all values are zero

5. 使用没有默认值的结构,并使用它创建您的对象 `static`


 typedef struct
{
    int num1;
    int num2;
    int num3;
    int num4;
} data_t;

// `static` forces a default initialization of zero for each
// value when no other default values are set
static data_t d9;

6. 因此,如果您有一个具有 _非零_ 默认值的结构,并且您想将所有值归零,您必须明确地这样做!这里还有一些方法:


 // 1. Have a `constexpr` copy of the struct that you use to
// reset other struct objects. Ex:

struct data
{
    int num1 = 1;
    int num2 = 7;
    int num3 = -10;
    int num4 = 55;
};

constexpr data DATA_ALL_ZEROS = {0, 0, 0, 0};

// Now initialize d13 to all zeros using the above `constexpr` struct
// object
data d13 = DATA_ALL_ZEROS;


// OR 2. Use a `zero()` member function to zero the values:

struct data
{
    int num1 = 1;
    int num2 = 7;
    int num3 = -10;
    int num4 = 55;

    zero()
    {
        num1 = 0;
        num2 = 0;
        num3 = 0;
        num4 = 0;
    }
};

data d14;
d14.zero();

”`

这里最大的收获是: data_t d{}data_t d = {}data_t d = {0} ,实际上将结构的所有成员设置为零!

  1. data_t d{} 将所有值设置为结构中定义的默认值。
  2. data_t d = {} 还将所有值设置为默认值。
  3. 并且 data_t d = {0} 仅将 FIRST 值设置为零,而将所有其他值设置为其默认值。

所以, 要明确

请注意,我写的上述关键要点似乎与 cppreference.com 上的此文档 相矛盾,因此我提出了下面列出 的后续问题,这对我的理解非常有帮助!

走得更远

  1. _最有用_: 我的后续问题: 为什么不将 C++ 结构初始化为 = {0} 将其所有成员设置为 0?

参考:

  1. 很有用:
    1. https://en.cppreference.com/w/cpp/language/zero_initialization
    2. https://en.cppreference.com/w/cpp/language/aggregate_initialization
    3. https://en.cppreference.com/w/cpp/language/value_initialization
  2. 非常有用:将 数组(不是结构)的所有成员初始化为相同的值:
    1. 如何将数组的所有成员初始化为相同的值?
    2. [仅限 gcc] 如何将数组的所有成员初始化为相同的值?
  3. https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/cpp/struct_initialization.cpp
    1. 克隆这个 repo 并自己运行代码 cpp/run_struct_initialization.sh

有关的:

  1. 初始化结构中的默认值
  2. *****[我自己的答案,它演示了任何函数中的这种结构修改/聚合成员重新分配: leds[0] = {10, 20, 30, 40, 50}; ] Arduino Stack Exchange:初始化结构数组

原文由 Gabriel Staples 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题