問答中關於C語言中共同體(聯合體)的問題
原問答是這樣的:
“ #include
main()
{ union data { long w; float x; char c; };
執行下列語句後a的十進位制值是多少?
union data a;
a.x=3.1416;
a.w=123456;
a.c='x'; ”
我的回答:
共同體的最大特點就是多個數據共享一個記憶體。而記憶體的大小是看共同體裡面最大成員而定。
問題中的共同體,long 和 float 所佔的位元組大小一樣也是最大(char只佔一個位元組),為4個位元組。
union data a;
a.x=3.1416;//這時記憶體中的值為0011.0010 0100 0011 1111 1111 1111 1111(這並不影響下面的結果)
a.w=123456;//這是記憶體中的值被覆蓋,變為0000 0000 0000 0001 1110 0010 0100 0000
a.c='x';//因為'x'的在二進位制中為0111 1000 所以覆蓋部分只有最後一個位元組,這時a的值為0000 0000 0000 0001 1110 0010 0111 1000
而這時a的十進位制值對應為123512.
使用編譯器編譯後也是這個答案。
說實話,我一開始看到這道題時還是還是要想挺久的,因為最近一直在用Java,C語言有些忘了。
還有一點這道題目沒有反應的還有一個問題,舉個例子來說明吧。
union un{
char a[10]; //佔10位元組
double m; //佔8位元組
int n; //佔4位元組
}
在這裡面的共同體中,大家是不是以為這個共同體un是佔10個位元組?但是,用編譯器使用運算子sizeof來測試大小結果為:16。
按照正常來說是這樣的,但是在這裡有個位元組對齊問題(C語言中的規定共同體中的對齊方式要適合其中的所有成員)。所以上面佔的位元組數分別是10、8、4。從這裡可以看出共同體所佔的空間不僅取決於最大成員,還和所有成員有關係,大小必須滿足兩個條件:(1)大小足夠容納最寬的成員;(2)大小能被其包含的所有基本資料型別的大小所整除。所以,位元組數就被補充到16。
最後還有一點,就是共同體中的所有成員相對於基地址的偏移量都為0,每個成員的基地址就是共同體變數的首地址。(這一點使用指標時有用共同體要特別注意)