位段(bit-field)是以位為單位來定義結構體(或聯合體)中的成員變量所占的空間。含有位段的結構體(聯合體)稱為位段結構。采用位段結構既能夠節省空間,又方便於操作。
位段的定義格式為:
type [var]: digits
其中:
type只能為int,unsigned int,signed int,char, unsigned char 五種類型之一,digits表示該位段所占的二進制位數
位段長度digits不能超過類型type對應的數據類型占用的大小,如若type為char,則digits不能超過8,為int則digits不能超過32
位段名稱var是可選參數,可以省略
一、位域的定義
位域定義與結構體定義相仿,其形式為:
struct 位域結構名
{
位域列表
};
其中位域列表的形式為: type [var]: digits
例如:
1 struct data{ 2 3 int a : 32; //位段a,占32位 4 5 char b : 5; //位段b,占5位 6 7 char c : 2; //位段c,占2位,和b存儲在同一個字節 8 9 unsigned char : 6; //無名位段,占6位 10 11 };
注:位域可以無位域名,這時它只用來作填充或調整位置,無名的位域不能被訪問
二、位段的使用
位域的使用和結構成員的使用相同,其一般形式為:位域變量名·位段名,也可定義一個指向位域的指針p,然后p->位段名使用,使用時需要注意:
①不能對位段進行取地址操作
②若位段占的二進制位數為0,則這個位段必須是無名位段,下一個位段從下一個位段存儲單元開始存放
③若位段出現在表達式中,則會自動進行整型升級,自動轉換為int型或者unsigned int
④對位段賦值時,最好不要超過位段所能表示的最大范圍,否則可能會造成意想不到的結果
三、位段在內存中的存儲模式
使用位域的主要目的是壓縮存儲,其大致規則為:
1) 如果相鄰位域字段的類型相同,且其位寬之和小於類型的sizeof大小,則后面的字段將緊鄰前一個字段存儲,直到不能容納為止;
2) 如果相鄰位域字段的類型相同,但其位寬之和大於類型的sizeof大小,則后面的字段將從新的存儲單元開始,其偏移量為其類型大小的整數倍;
3) 如果相鄰的位域字段的類型不同,則各編譯器的具體實現有差異,經實驗VC采取不壓縮方式,即即使前一個字段有空余位足夠容納后一個字段,后一個字段也當前一個字段 沒有空余位,從前一個字段類型大小之后的新字節開始存儲;
4) 如果位域字段之間穿插着非位域字段,則不進行壓縮;
5) 整個結構體的總大小為最寬基本類型成員大小的整數倍。:
測試程序如下,環境vs3013,cfree 5.0
#include <stdio.h> #include <stdlib.h> struct data{ int a : 20; //位段a,占20位 char b : 3; //位段b,占3位,不會和a壓縮存儲 char : 0; //無名位段 unsigned char c : 5; //位段c,占5位 }; int main() { data test; data *ptest; ptest = &test; //兩種方式訪問位段 test.a = 20; ptest->b = 5; //vc不壓縮存儲,占用8個字節,為其最寬基本類型成員大小的整數倍 printf("sizeof(data): %d\n",sizeof(data)); //test.b在輸出時自動轉化為整型,5(101)高位為1,擴展時高位連續補1,值為-3 printf("test.a = %d\t test.b = %d\n",test.a, ptest->b); system("pause"); return 0; }
運行結果為:
sizeof(data): 8
test.a = 20 test.b = -3
參考:
http://www.cnblogs.com/dolphin0520/archive/2011/10/14/2212590.html