[英]value of members of unions with bit-fields
我正在嘗試學習如何為包含位字段的聯合分配內存。
我查看了與此類似的帖子和問題,並且了解到填充在大多數情況下都取決於成員在結構中聲明的順序。
1。
union Example
{ int i:2;
int j:9;
};
int main(void)
{
union Example ex;
ex.j=15;
printf("%d",ex.i);
}
輸出:-1
2。
union Example
{ unsigned int i:2;
int j:9;
};
int main(void)
{
union Example ex;
ex.j=15;
printf("%d",ex.i);
}
輸出3
有人可以解釋一下輸出結果嗎? 僅僅是這種情況下的標准輸出嗎? 我在ubuntu中使用內置的gcc編譯器
你的編譯器分配在工會位字段位的方式發生的低位重疊j
用的比特i
。 因此,當j
設置為15時, i
的兩位分別設置為1。
當i
是用int i:2
聲明的兩位帶符號整數時,編譯器會將其解釋為兩位二進制的補碼。 通過這種解釋,比特11代表-1。
當i
是由unsigned int i:2
聲明的兩位無符號整數時,它是純二進制,沒有符號位。 通過這種解釋,位11代表3。
下面的程序顯示,至少在您的C實現中,將有符號的兩位整數設置為-1或將無符號的兩位整數設置為3會在聯合中產生相同的位模式。
#include <stdio.h>
int main(void)
{
union Example
{
unsigned u;
int i : 2;
int j : 9;
unsigned int k : 2;
} ex;
ex.u = 0;
ex.i = -1;
printf("ex.i = -1: %#x.\n", ex.u);
ex.u = 0;
ex.j = 15;
printf("ex.j = 15: %#x.\n", ex.u);
ex.u = 0;
ex.k = 3;
printf("ex.k = 3: %#x.\n", ex.u);
}
輸出:
ex.i = -1: 0x3. ex.j = 15: 0xf. ex.k = 3: 0x3.
請注意,編譯器還可以從高到低而不是從低到高分配位,在這種情況下, j
的高位將與i
重疊,而不是低位。 同樣,編譯器為9位j
使用的存儲單元大小可能與為2位i
使用的存儲單元大小不同,在這種情況下,它們的位可能根本不重疊。 (例如,它可能對i
使用單個8位字節,但對j
使用32位字。這8位字節會與32位字的某些部分重疊,但不一定與j
所用的部分重疊。 )
例1
#include <stdio.h>
union Example
{ int i:2;
int j:9;
};
int main(void)
{
union Example ex;
ex.j=15;
printf("%d",ex.i);
printf("\nSize of Union : %lu\n" , sizeof(ex));
return 0;
}
輸出:
-1
Size of Union : 4
觀察結果:
從這個輸出中,我們可以推斷出,即使我們使用9位(最大值),編譯器也會分配4字節(由於填充)。 聲明union Example ex;
為聯合示例對象ex分配4字節的內存。 語句ex.j=15;
將0x0000000F分配給該4字節的內存。 因此,對於j,它為9位分配0-0-0-0-0-1-1-1-1。 語句printf("%d",ex.i);
嘗試打印ex.i(2位)。 從前面的語句中我們得到1-1。
有趣的部分到了,例如ex.i的類型為int。 因此,第一位用於分配帶符號的表示,大多數cpu以2的補碼形式表示帶符號的表示。 因此,如果我們反轉1-1的2的補數,我們將獲得值1。因此,我們得到的輸出為-1。
例2
#include <stdio.h>
union Example
{ unsigned int i:2;
int j:9;
};
int main(void)
{
union Example ex;
ex.j=15;
printf("%d",ex.i);
return 0;
}
輸出:
3
觀察結果:
聲明union Example ex;
為聯合示例對象ex分配4字節的內存。 語句ex.j=15;
將0x0000000F分配給該4字節的內存。 因此,對於j,它為9位分配0-0-0-0-0-1-1-1-1。 語句printf("%d",ex.i);
嘗試打印ex.i(2位)。 從前面的語句中我們得到1-1。
與上述示例相同,但此處ex.i的類型為unsigned int。 因此,這里沒有符號位用於表示。 因此,存儲在2位位置中的是確切值。 因此輸出為3。
希望我清除您的疑慮。 請在互聯網上檢查2和1的補碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.