簡體   English   中英

具有位域的工會成員的價值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM