2017-10-05 61 views
0

我聽說過的工會是它將爲其中最大的變量分配內存空間。在這裏,我試圖用兩種不同的方式分配「相同」的價值,但結果是有問題的。工會內部的變量分配差異

首先,

union h { 
    int a; 
    char b; 
}; 

int main() 
{ 
    union h h1; 
    h1.b = 'X'; 
    printf("%d %c\n",h1.a, h1.b); 
    return 0; 
} 

的輸出將是一個大的隨機數後跟 'X'

-1674402216 X 

當我試圖分配h1.a也成多個,

union h { 
    int a; 
    char b; 
}; 

int main() 
{ 
    union h h1; 
    h1.a = 1; 
    h1.b = 'X'; 
    printf("%d %c\n",h1.a, h1.b); 
    return 0; 
} 

Th是給出輸出

88 X 

有人可以幫我找出究竟發生了什麼嗎?

Thankyou :)

+3

一個'union'可以保存其**成員**,* *成員*(這是最近寫到的成員)的價值。訪問不活動的成員通常是*未定義的行爲*(在C標準中描述了例外情況)。由於兩個成員共享存儲空間,你期望什麼? –

+0

感謝您的回覆。我預計它會顯示爲'88 X'本身。原因:h1.b被賦值爲'X',我預計變量h1.a也會反映相同的變化。 – sasebot

回答

4

聯盟成員在內存中佔據相同的空間。 所以你的工會看起來像這樣:(假設有32位整數系統)

N-1 ... 
    -------- 
N ||X||a|| 
N+1 | |a|| 
N+2 | |a|| 
N+3 | |a|| 
... |  | 
    -------- 
    ... 

通過assiging X你還修改了你的一個字節未初始化的。您的值(-1674402216)可以解釋爲基於16的9C32A658。您的最低有效字節是58 HEX,這是X的ASCII代碼,您的其他三個字節保持其初始未初始化值。

在第二種情況下,您首先將int初始化爲1(它將除最低有效字節以外的所有字符都設置爲0),然後您已將覆蓋最低有效字節的X取爲88(ASCII代碼爲X)原來的'X',當時看着char成員的 。

不要忘記提及:這樣的佈局是實現定義的。標準確實會說,正如您在評論中提到的那樣,您不應該實際訪問最後同時寫入的成員,但通常會使用它來完成此操作(請參閱此線程:Why do we need C Unions?,What is the strict aliasing rule?)。