2011-05-28 104 views
7

我試圖在全球範圍內初始化工會如下面的例子:工會初始化

#include <cstdio> 

typedef union { 
    char t[4]; 
    int i; 
} a; 

enum { 
    w = 5000, 
    x, 
    y, 
    z 
}; 

a temp = {w}; 
int main() { 
    printf("%d %d %d %d %d\n", temp.t[0],temp.t[1],temp.t[2],temp.t[3],temp.i); 
    return 0; 
} 

然而,如果你運行代碼,你會注意到,無論是temp.i或temp.t [中...]實際上給我正確的項目我初始化工會。我想可以避免,如果我可以手動初始化整數成員,但不幸的是我不能。我也無法更改結構中元素的順序(交換int和char順序會正確初始化所有內容) - 它們實際上是由外部庫提供的。 我的問題是:我怎樣才能設置結構全局,而不是char [4]成員(或在這種情況下,只是char [])的第一個元素)的整數成員?

編輯:另外,有沒有一個嚴格的C++解決這個問題?即命名結構初始化不起作用的地方(因爲它在語言中不存在)?

回答

7

你會想這樣做:

a temp = {i: w}; 

應爲gccg++工作。

+0

啊,美;這是我正在尋找的。歡呼 – 2011-05-28 10:37:10

+3

請注意,這是一種非標準的語言擴展,如果您轉移到其他編譯器,將會失敗。 – 2011-05-28 13:25:38

+0

是的,這就是我提到gcc/g ++的原因。似乎沒有一個有效的C++方法來初始化聯合成員。 – evgeny 2011-05-28 23:33:15

11

在C99,你可以這樣做:

a temp = { .i=w }; 
6

您可以初始化整數成員如下:

a temp = { 
    .i = w 
}; 
7

在C99,你可以做一個名爲初始化用作:

a x = { .i = 10 }; 

有一些建議使用非標準的gcc的擴展,但我會避免它,如果編碼C:

a x = { i : 10 }; 

您可以使用函數來初始化:

inline a initialize(int value) { // probably choose a better name 
    a tmp; 
    tmp.i = value; 
    return a; 
} 

,然後使用:

a x = initialize(10); 

編譯器會優化副本。

如果你是做C++,你可以爲你的工會類型提供一個構造函數:

/*typedef*/ union u {   // typedef is not required in general in C++ 
    char bytes[sizeof(int)]; 
    int i; 
    u(int i = 0) : i(i) {} 
} /*u*/; 

u x(5); 
+0

問題是我無法修改聯盟本身,否則我只是重新排列元素並完成它。不過,我喜歡內聯方法。 – 2011-05-28 11:31:35