结构数据D = {0}和结构数据D = {}之间是否存在任何区别

Is there any difference between struct Data d = {0} and struct Data d = {}

本文关键字:结构 数据 区别 任何 存在 之间 是否      更新时间:2023-10-16

我在代码中有两种类型的结构变量初始化。

示例

#include<iostream>
#include<string>
using namespace std;
struct Data{
   int arr[5];
   float x;
};
int main(){
   struct Data d = {0};
   struct Data d1 = {};
   cout<<d.arr[0]<<d.x;
   cout<<d1.arr[0]<<d1.x<<endl;
   return 0;
}

我正在运行代码广告,获取0 0 0 0作为我的输出。请帮助我,初始化之间是否有任何区别。

根据汇总初始化规则,此处的效果是相同的,即结构的所有成员都将进行价值initialization(在此,对于非阶级类型的零判定)。

如果初始化器条款的数量小于成员数量and bases (since C++17)或初始化器列表的数量完全为空,则剩余的成员and bases (since C++17)是按空列表初始化的by their default initializers, if provided in the class definition, and otherwise (since C++14),按照通常的列表启动规则(该执行价值启动性限制,对于具有默认构造函数的非类型类型和非类型类,以及聚合的汇总初始化)。如果参考类型的成员是其余成员之一,则该程序的形式不佳。

更精确,

struct Data d = {0}; // initialize the 1st member of Data to 0, value-initialize(zero-initialize) the remaining members
struct Data d1 = {}; // value-initialize(zero-initialize) all the members of Data

请注意,整个故事基于Data是一种聚合类型,其成员是非类型的类型,否则该行为将根据列表初始化规则而改变。

在这种情况下,结果是相同的,但在其他情况下不一定如此。

在这种情况下,您尚未提供CTOR,因此您正在使用汇总初始化。这给空列表提供了零定位,而您为非空置提供了0,因此两个人都可以使用。

如果您提供了一个CTOR,那么从两者中获得不同的结果是微不足道的:

#include <iostream>
struct foo {
    int f;
    foo(int f = 5) : f(f) {}
    friend std::ostream &operator<<(std::ostream &os, foo const &f) { 
        return os << f.f;
    }
};
int main() { 
    foo f1{};
    foo f2{0};
    std::cout << "Empty init list: " << f1 << "n";
    std::cout << "zero init list: " << f2 << "n";
}

尽管CTOR是最明显的方法,但这不是唯一的方法。对于另一个明显的示例(C 11和较新):

struct foo { 
    int f = 5;
};

使用{} 默认初始化使用{}定义为的初始化。因此,通过做

struct Data d1 = {};

Data d1初始化为{{},{}},即{{0, 0, 0, 0, 0}, 0.0}

作为00.0intfloat的默认值

这就是您看不到任何区别的原因。在您的情况下,他们俩总是做同样的事情。

差异在这些情况下:

1。)这是在{}内提供初始化器的强制性

struct X {
    X(int);
};
X  x1 {};    // error : empty initializer. X(int) states that an int is required to construct an X.
X  x2 {0};   // OK

2。)方案当零初始化为禁止

struct Test {
    string name;
    int year;
};
Test alpha0{0}; // Error. Because name in Test fails at zero-initialization.
Test alpha{};     // OK. Because name in Test is default-initialized with empty string "".

是的,有区别。在第一种情况下,您将明确将Dataarr[0])的第一个成员初始化为零。在第二种情况下,您不会初始化任何内容,而只是阅读恰好存在的任何值。在这种情况下,它也为零,但这不能保证可行,尤其是在一个更复杂的程序中。

初始化结构的所有成员总是一个好主意。考虑您的程序的此稍微修改的版本,这应该使正在发生的事情清楚:

#include<iostream>
#include<string>
using namespace std;
struct Data{
   int arr[5];
   float x;
};
int main(){
   struct Data d = {1, 2, 3, 4, 5, 3.14f};
   struct Data d1 = {};
   cout<<d.arr[0]<<", "<<d.x<<", ";
   cout<<d1.arr[0]<<", "<<d1.x<<endl;
   return 0;
}

这将打印:

1, 3.14, 0, 0