struct Data d = 0 和 struct Data d = 之间有啥区别吗

Posted

技术标签:

【中文标题】struct Data d = 0 和 struct Data d = 之间有啥区别吗【英文标题】:Is there any difference between struct Data d = 0 and struct Data d = struct Data d = 0 和 struct Data d = 之间有什么区别吗 【发布时间】:2017-04-07 00:44:02 【问题描述】:

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

例子

#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 作为我的输出。请帮帮我,这两种初始化有什么区别。

【问题讨论】:

一个是你拥有的初始化列表,另一个只是一个空的初始化列表。 你希望每个里面有什么?你不应该这样初始化你的结构。您需要访问结构中的每一件事并对其进行初始化。可能有一个函数,它接受一个结构并有一个 for 循环,将数组中的所有内容初始化为 0,将 x 初始化为 0 @Danh 不要混蛋。将问题标记为c,因为它涉及 c 和 c++ 共有的语法是不正确的,但它不是“垃圾邮件”。 Proper way to initialize C++ structs的可能重复 【参考方案1】:

根据aggregate initialization的规则,这里的效果是一样的,即struct的所有成员都是value-initialized(这里zero-initialized是非类类型)。

如果初始化子句的数量小于成员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是一个aggregate type并且它的成员是非类类型,否则行为会根据list initialization的规则改变。

【讨论】:

我觉得Data有构造函数时的效果值得一提 如果Data的第一个成员是类类型也会有所不同【参考方案2】:

是的,有区别。在第一种情况下,您将Data (arr[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

【讨论】:

你的程序应该说明什么?【参考方案3】:

使用的默认初始化定义为使用初始化每个成员。所以,通过做

struct Data d1 = ;

Data d1被初始化为,,也就是0, 0, 0, 0, 0, 0.0

00.0 分别是 intfloat 的默认值。

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

不同之处在于:

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 alpha00; // Error. Because name in Test fails at zero-initialization.
Test alpha;     // OK. Because name in Test is default-initialized with empty string "".

【讨论】:

【参考方案4】:

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

在这种情况下,您没有提供 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 f20;

    std::cout << "Empty init list: " << f1 << "\n";
    std::cout << "zero init list: " << f2 << "\n";

虽然 ctor 是最明显的方法,但它并不是唯一的方法。另一个明显的例子(仅限 C++11 和更新版本):

struct foo  
    int f = 5;
;

【讨论】:

以上是关于struct Data d = 0 和 struct Data d = 之间有啥区别吗的主要内容,如果未能解决你的问题,请参考以下文章

Linux 内核 内存管理内存映射相关数据结构 ① ( vm_area_struct 结构体 | task_structmm_structvm_area_struct 3 个结构体之间的关系)

Linux - PBC - task-struct结构体

在 Swift 中将实例变量的属性保存到 Struct 的静态变量数组中

c++ struct与class

Golang中结构体Struct

Golang中结构体Struct