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
,
0
和 0.0
分别是 int
和 float
的默认值。
这就是您看不到任何差异的原因。在你的情况下,他们俩总是做同样的事情。
不同之处在于:
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 个结构体之间的关系)