2016-10-12 70 views
0
#include <stdio.h> 

union mix { 
    unsigned char a1:1; 
    unsigned char a2:4; 
    unsigned char a3:4;  
    unsigned char a4:1; 
    unsigned char a5:4; 
    unsigned char a6:4;  
    unsigned char a7:1; 
    unsigned char a8:4; 
    unsigned char a9:4;  
    unsigned char a10:1; 
    unsigned char a11:4; 
    unsigned char a12:4;  
}; 

int main() { 

    printf("Sizeof mix = %d bytes\n", sizeof(union mix)); 

    return 0; 
} 

輸出是1字節具有比其大小更多成員的比特場聯合的大小

位字段成員超過8位會發生什麼?顯然我仍然可以爲任何位域成員設置並獲取正確的值。

UPDATE

感謝您對我的清理混亂。一方面的問題:這些位以什麼順序存儲在內存中?假設它是小端存儲器,所以0xabcd將作爲0xd,0xc,0xb,0xa存儲在內存中。

  1. m.a1是否會成爲0xd或oxa的一部分?
  2. 它是第3位還是第0位0xd(或0xa)?
+4

沒有超過8位的成員。 'union'!='struct'。 – tkausl

+0

@tkausl明白了..我混淆了struct/union/bit-fields .. :)謝謝。 – justanotherguy

+1

你似乎把工會的規模與工會成員的規模混爲一談。通常,聯合的大小等於其最大成員的大小 - 在這種情況下,它是一個字節,因爲所有成員都是字符(四捨五入爲字節大小,因爲它是實際大小的最小單位) – SomeWittyUsername

回答

5

@tkausl是正確的。在union中,每個成員與內存中的所有其他成員重疊。因此,根據每個字段中的比特數和平臺的字節順序,位字段中的每個字段與其他字段重疊。例如,a1a10可能始終具有相同的值。由於所有的字段在內存中都是重疊的,因此只需要保存最長的9字段所需的字節數。由於一個字節可以做到這一點,這就是union的大小。

3

這些位以什麼順序存儲在內存中?

那就是實現定義的。

6.7.2.1結構和聯合說明,第11段the C Standard的:

實現可分配任何可尋址存儲單元大 到足以容納一個比特字段。如果剩餘足夠的空間,緊接在結構中的另一個比特字段之後的比特字段 應該被打包到相同單元的相鄰比特中 。如果剩餘空間不足 ,則將不匹配的位字段放入 ,則下一單元或與相鄰單元重疊的位是 實現定義的。 單位內的位域 的分配順序是由實現定義的(從高位到低位或從低位到高位)。未指定可尋址的 存儲單元的對齊方式。

不同的編譯器可以不同地實現位域。請注意,高階和低階與大端或小端並不相同。 8位unsigned char的低位是在打開和關閉時增加1的值。相同的8位unsigned char的高位是在其翻轉時增加128的值。所以位字段有兩個級別的實現定義的順序:平臺/硬件定義的字節順序和編譯器定義的高位或低位賦值。您還可以在位字段之間填充以及是否將相鄰單元跨越到實現定義的位字段細節。