位域(位段)

  有些信息在存儲時,並不須要佔用一個完整的字節,而只須要佔用一個或幾個二進制位。數據結構

例如: 存放一個開關量時,只有0和1二種狀態,只保存一位二進制位便可。爲了節省存儲空間,C語言提供了數據結構:位域。測試

  位域是把字節中的二進制位劃分爲幾個不一樣的區域,並說明每一個區域的位數。每一個區域有個域名,容許在程序中按域名spa

進行操做。這樣就能夠把幾個不一樣的對象用一個字節的二進制位域來表示。code

位域的定義對象

  位域定義與結構體定義相仿,形式爲:blog

struct 位域結構名內存

{編譯器

  類型名  位域名: 位域長度,如 int a 8;  //位域長度不能大於8(即一個字節)域名

  ......編譯

};

 

注意:

  一個位域必須存儲在一個字節中,當有二個連續的位域,在一個字節中存放第一個位域後剩下的空間不足以存放第二個

位域,則第二個位域將存放在下一個字節單元中,前一個字節多餘的位補0。(由於一個位域必須存儲在一個字節,因此位域長度最大爲8)

 

 
1 struct wy 2 { 3   unsigned int a : 4; //第一個字節前4位存放該位域 4   unsigned int b : 5; //第一個字節剩下的4位不足以存放b,位域b從下一個字節開始 5 }WY; 6 sizeof(WY) == 4;位域存儲的類型是int佔用4個字節,根據內存對齊規則不足4字節也佔用4字節。對齊規則能夠往下看

 

空域:

  無論當前字節單元剩下的位數是否足以存放下一個位域,使用空域後,下一個位域都存放到下一個類型單元,好比int就存放到下個int單元

 
1 struct wyn 2 { 3   unsigned int a : 4; //第一個字節前4位存放該位域 4   unsigned int :0; 5   unsigned int b : 2; //空域後的位域從下個單元開始 6 }WYN; 7 sizeof(WYN) == 8; 由於存儲的類型是int型,空域後,從下個int開始
 
 

wyn nn;  nn.a = 6; //給a賦值爲6實際上是把a佔用的4位賦值爲 0110

 當一個位域無位域名時,它只是用來做爲填充或調整位置,不能被使用(好比 int :3 僅僅是用來佔3位二進制位,但這3位無法在程序裏使用)。

位域內存對齊規則

1 若是相鄰位域字段的類型相同,且其位寬之和小於類型的sizeof(類型)大小,則後面的字段緊鄰前一個字段存儲。

2 若是相鄰位域字段的類型相同,且其位寬之和大於類型的sizeof(類型)大小,則後面的字段重新的存儲單元開始,其偏移量爲sizeof(類型)大小的整數倍

3 若是相鄰位域字段的類型不一樣,則各編譯器的具體實現有差別,須要在編譯器上測試

 

 
1 struct wyn 2 { 3   unsigned int i : 8; 4   unsigned int j : 4; 5   unsigned int a : 3;
6   double b;
7 }WYN; 8 sizeof(WYN) == 16;
i,j,a共佔用2個字節,根據規則1,緊鄰的int型i,j,a共佔用4字節。
b位double型,佔用8字節,根據對齊規則,b的內存地址必須是8的整數倍,因此在i,j,a後會填充4個字節,再存儲b。
 
 
 
1 struct wyn2 2 { 3   unsigned int i : 8; 4   unsigned int j : 4; 5   double b; 
6   unsigned int a : 3;
7 }WYN2; 8 sizeof(WYN2) == 24; 同上面WYN同樣,根據規則1,2:i,j,b佔用16字節位域a佔用3位,類型是int應該佔用4字節,可是整個結構體大小應該按照最大的類型double對齊,必須是8的整數倍。因此佔用24字節
相關文章
相關標籤/搜索