2016-11-23 86 views
7

我有兩種類型的結構變量初始化在我的代碼中。結構數據d = {0}和結構數據d = {}

#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作爲我的輸出。請幫助我,兩者初始化之間是否有區別。

+0

一個是初始化列表,你必須等於對方只是一個空的初始化列表。 –

+0

你期望在每個內部有什麼?你不應該像那樣初始化你的結構。你需要訪問結構中的每個東西並初始化它。可能有一個函數需要一個結構,並有一個for循環,它將數組中的所有內容都初始化爲0,並將您的x初始化爲0 –

+0

@Danh不是一個混蛋。將問題標記爲「c」,因爲它涉及到c和C++共有的語法,但這不是「垃圾郵件」。 – djechlin

回答

7

aggregate initialization規則,效果這裏同樣,即該結構的所有成員將value-initializedzero-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 

注意,整個故事是基於Dataaggregate type和它的成員都是非類類型,否則行爲將根據規則改變list initialization

+1

我認爲值得一提的是'數據'有構造函數 – Danh

+1

如果'Data'的第一個成員是類類型,那麼也會有區別 –

-2

是的,有區別。在第一種情況下,您明確將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 
+0

你的程序應該說明什麼? –

0

默認初始化使用{}定義爲每個成員初始化通過使用 {}。所以,通過做

struct Data d1 = {}; 

Data d1被初始化爲{{},{}},這是{{0, 0, 0, 0, 0}, 0.0}

00.0intfloat RESP默認值。

這就是您沒有看到任何區別的原因。他們兩個總是在你的情況下做同樣的事情。

區別在於在這種情況下:

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 "". 
0

結果在這種情況下是相同的,但在其他情況下不一定如此。

在這種情況下,您還沒有提供ctor,因此您正在使用聚合初始化。這爲empty-init-list提供了零初始化,並且你爲非空的列表提供了0,所以兩者工作相同。

如果你提供了一個構造函數,這將是微不足道的,從兩個得到不同的結果:

#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"; 
} 

雖然構造函數是最明顯的方式做到這一點,它不是唯一的一個。對於另一個明顯的例子(C++ 11和更新只):

struct foo { 
    int f = 5; 
};