深度C理解位域
深度C 理解位域(fylxaut 著) 有些信息在存儲時,并不需要占用一個完整的字節(jié), 而只需占幾個或一個二進制位。例如在存放一個開關量時,只有0和1 兩種狀態(tài),用一位二進位即可。為了節(jié)省存儲空間,并
深度C 理解位域(fylxaut 著) 有些信息在存儲時,并不需要占用一個完整的字節(jié), 而只需占幾個或一個二進制位。例如在存放一個開關量時,只有0和1 兩種狀態(tài),用一位二進位即可。為了節(jié)省存儲空間,并使處理簡便,C語言又提供了一種數據結構,稱為“位域”或“位段”。所謂“位域”是把一個字節(jié)中的二進位劃分為幾個不同的區(qū)域,并說明每個區(qū)域的位數。每個域有一個域名,允許在程序中按域名進行操作。 這樣就可以把幾個不同的對象用一個字節(jié)的二進制位域來表示。
一、位域的定義和位域變量的說明位域定義與結構定義相仿,其形式為: struct 位域結構名
{ 位域列表 };
其中位域列表的形式為: 類型說明符 位域名:位域長度
例如:
struct bs
{
int a:8;
int b:2;
int c:6;
};
//////////////////////////////////////////////////////////////////////////////////////////////////////
struct foo1 {
int a : 1;
int : 2;/空域
short c : 1;
};
在foo 結構體的定義中,成員a 雖然類型為int ,但是它僅僅占據著4個字節(jié)中的一個bit 的空間;類似b 占據2個bit 空間,但是b 到底是占據第一個int 的2個bit 空間呢還是第二個int 的2個bit 空間呢?這里實際上也涉及到如何對齊帶有' 位域' 的結構體這樣一個問題。我們來分析一下。
struct foo2 {
char a : 2;
,char b : 3;
char c : 1;
};
struct foo3 {
char a : 2;
char b : 3;
char c : 7;
};
顯然都不是我們期望的,如果按照正常的內存對齊規(guī)則,這兩個結構體大小均應該為3才對,那么問題出在哪了呢?首先通過這種現象我們可以肯定的是:帶有' 位域' 的結構體并不是按照每個域對齊的,而是將一些位域成員' 捆綁' 在一起做對齊的。
1) 以foo2為例,這個結構體中所有的成員都是char 型的,而且三個位域占用的總空間為6 bit < 8 bit(1 byte),這時編譯器會將這三個成員' 捆綁' 在一起做對齊,并且以最小空間作代價,這就是為什么我們得到sizeof(struct foo2) = 1這樣的結果的原因了。
2) 再看看foo3這個結構體,同foo2一樣,三個成員類型也都是char 型,但是三個成員位域所占空間之和為9 bit > 8 bit(1 byte),這里位域是不能跨越兩個成員基本類型空間的,這時編譯器將a 和b 兩個成員' 捆綁' 按照char 做對齊,而c 單獨拿出來以char 類型做對齊,這樣實際上在b 和c 之間出現了空隙,但這也是最節(jié)省空間的方法了。我們再看一種結構體定義:
struct foo4 {
char a : 2;
char b : 3;
int c : 1;
};
在foo4中雖然三個位域所占用空間之和為6 bit < 8 bit(1 byte) ,但是由于char 和int 的對齊系數是不同的,是不能捆綁在一起,那是不是a 、b 捆綁在一起按照char 對齊,c 單獨按照int 對齊呢。