C C 中的位域 bit field

2021-08-06 05:11:43 字數 1211 閱讀 4559

位域是c/c++中常用的資料結構。 在某些情況下合理的使用位域可以節省儲存空間,提高執行效率並提高程式的可讀行。

按照我以往的程式設計經驗來看,通常以下情況下會優先考慮使用位域。1)有很多的狀態標記,需要集中儲存,比如tcp鏈結

的狀態 2)協議棧相關的資料結構,尤其是底層通訊協議中很多情況使用乙個或者幾個bit來表示某種狀態,資料長度等等。

這時候就會使用到位域。

struct snfield;   

struct stfield;       

這裡要注意的位域為單位的成員和其他的struct的成員, 都是按照從低位址到高位址的方式分配記憶體的。

這裡seq 按照記憶體位址從低到高分配,獲得0~6個bit. 而startbit獲得最高位記憶體的1個bit. 所以位域完全是從記憶體位址解釋每乙個bit。

注意位域與聯合的區別,前兩天剛犯的乙個錯誤拿出來自省一下。 在解析某個協議字段,低0~7bit, 是序列號,最高的1個bit說明是否是

開始幀。 我想賦值的時候直接以byte賦值,而在解析的時候才按照bit去解析。 這樣賦值操作就會很簡單,因為從網路讀出來資料也是按照

位元組流接收的。感覺應該是用乙個聯合union, 於是呼有了如下的結構

union snflag;

然後給flag賦值 0x80,

all is 128

seq 7 is 0

startbit 1 bit is 0

然後給flag賦值 0x81,

all is 129

seq 7 is 1

startbit 1 bit is 1

然後給flag賦值 0x82,

all is 129

seq 7 is 2

startbit 1 bit is 0

發現沒有,seq和 startbit 都是從第0個bit開始解析,而不是預想的startbit從第7個bit開始解析。重新查了乙個union的定義

struct和union的重要區別:

struct為每個欄位在不同的偏移處分配儲存空間,而聯合則將所有的字段重疊在記憶體中的相同偏移處。

所以乙個union中所有的字段都是嘗試在同乙個位址,也就是低位址開始解釋變數。

那麼怎麼辦呢,可能您已經想到了。先把位域放在乙個結構體中,然後和乙個位元組在放在聯合體中。

struct snfield;          

union snflag;          

C struct中的位域 bitfield

結構體的成員可以限制其位域,每個成員可以使用用比位元組還小的取值範圍,下面的結構體s1中,四個成員每個成員都是2bit的值 0 3 整個結構體佔據的空間依然是4個位元組,但是第乙個位元組中表示了四個成員,後續三個位元組沒有用到。struct s1 s1.a 1 s1.b 1 s1.c 1 s1.d ...

C C 位域定義

有些資訊在儲存時,並不需要占用乙個完整的位元組,而只需佔幾個或乙個二進位制位。例如在存放乙個開關量時,只有0和1 兩種狀態,用一位二進位即可。為了節省儲存空間,並使處理簡便,c語言又提供了一種資料結構,稱為 位域 或 位段 所謂 位域 是把乙個位元組中的二進位劃分為幾個不同的區域,並說明每個區域的位...

C C 位域總結

最近接觸到了位域這個概念,大家都知道位元組是記憶體定址的最小單元,但有時我們僅需要幾位的二進位制空間來儲存資料,c語言定義了位域幫助更加接近底層,按照需求來分配空間,將1bit 分為更小的空間。一 位域的使用方法 1 定義 struct 位域結構名 其中位域列表的形式為 型別說明符 位網域名稱 位域...