C 快速上手 十二 位域學習筆記

2021-10-09 06:38:31 字數 3116 閱讀 9240

「 位域 「 或 「 位段 「(bit field)為一種資料結構,可以把資料以位的形式緊湊的儲存,並允許程式設計師對此結構的位進行操作。這種資料結構的乙個好處是它可以使資料單元節省儲存空間,當程式需要成千上萬個資料單元時,這種方法就顯得尤為重要。第二個好處是位段可以很方便的訪問乙個整數值的部分內容從而可以簡化程式源**。而這種資料結構的缺點在於,位段實現依賴於具體的機器和系統,在不同的平台可能有不同的結果,這導致了位段在本質上是不可移植的。

位域通常使用結構體宣告, 該結構宣告為每個位域成員設定名稱,並決定其寬度:

struct bit_field_name

;

元素

描述bit_field_name

位域結構名

type

位域成員的型別,必須為 int、signed int 或者 unsigned int 型別

member_name

位域成員名

width

規定成員所佔的位數

例如宣告如下乙個位域:

struct _prcode

;struct _prcode prcode;

該定義使 prcode包含 2 個 2 bits 位域和 1 個 8 bits 位域,我們可以使用結構體的成員運算子對其進行賦值:

prcode.code1 =0;

prcode.code2 =3;

procde.code3 =

102;

賦值時要注意值的大小不能超過位域成員的容量,例如 prcode.code3 為 8 bits 的位域成員,其容量為 2^8 = 256,即賦值範圍應為 [0,255]。

例如以下位域:

struct box 

;

該位域結構體中間有乙個未命名的位域,佔據 3 bits,僅起填充作用,並無實際意義。 填充使得該結構總共使用了 8 bits。但 c 語言使用 unsigned int 作為位域的基本單位,即使乙個結構的唯一成員為 1 bit 的位域,該結構大小也和乙個 unsigned int 大小相同。 有些系統中,unsigned int 為 16 bits,在 x86 系統中為 32 bits。文章以下均預設 unsigned int 為 32 bits。

乙個位域成員不允許跨越兩個 unsigned int 的邊界,如果成員宣告的總位數超過了乙個 unsigned int 的大小, 那麼編輯器會自動移位位域成員,使其按照 unsigned int 的邊界對齊。 例如:

struct stuff 

;

field1 + field2 = 34 bits,超出 32 bits, 編譯器會將field2移位至下乙個 unsigned int 單元存放, stuff.field1 和 stuff.field2 之間會留下乙個 2 bits 的空隙, stuff.field3 緊跟在 stuff.field2 之後,該結構現在大小為 2 * 32 = 64 bits。

這個空洞可以用之前提到的未命名的位域成員填充,我們也可以使用乙個寬度為 0 的未命名位域成員令下一位域成員與下乙個整數對齊。 例如:

struct stuff 

;

這裡 stuff.field1 與 stuff.field2 之間有乙個 2 bits 的空隙,stuff.field3 則儲存在下乙個 unsigned int 中,該結構現在大小為 3 * 32 = 96 bits。

示例**如下:

#include

using

namespace std;

struct stuff

;int

main()

; cout

sizeof

(s)

}//輸出13

512

位域的初始化與普通結構體初始化的方法相同,這裡列舉兩種,如下:

struct stuff s1=

;

或者直接為位域成員賦值:

struct stuff s1;

s1.field1 =20;

s1.field2 =8;

s1.field3 =

4;

宣告乙個 大小為 32 bits 的位域

struct box b1;
利用重對映將位域歸零

int

* p =

(int*)

&b1;

// 將 "位域結構體的位址" 對映至 "整形(int*) 的位址"

*p =0;

// 清除 s1,將各成員歸零

利用聯合 (union) 將 32 bits 位域 重對映至 unsigned int 型,可以宣告以下聯合:

union u_box 

;

x86 系統中 unsigned int 和 box 都為 32 bits, 通過該聯合使 st_box 和 ui_box 共享一塊記憶體。具體位域中哪一位與 unsigned int 哪一位相對應,取決於編譯器和硬體。 利用聯合將位域歸零,**如下:

union u_box u;

u.ui_box =

0;

「聯合」 是一種特殊的類,也是一種構造型別的資料結構。在乙個 「聯合」 內可以定義多種不同的資料型別, 乙個被說明為該 「聯合」 型別的變數中,允許裝入該 「聯合」 所定義的任何一種資料,這些資料共享同一段記憶體,以達到節省空間的目的

「聯合」 與 「結構」 有一些相似之處。但兩者有本質上的不同。在結構中各成員有各自的記憶體空間, 乙個結構變數的總長度是各成員長度之和(空結構除外,同時不考慮邊界調整)。而在 「聯合」 中,各成員共享一段記憶體空間, 乙個聯合變數的長度等於各成員中最長的長度。應該說明的是, 這裡所謂的共享不是指把多個成員同時裝入乙個聯合變數內, 而是指該聯合變數可被賦予任一成員值,但每次只能賦一種值, 賦入新值則衝去舊值。

ROS學習筆記(3) 快速上手使用

虛擬機器。wheeltec 官方提供的 ubuntu 系統映象壓縮包。鍵盤控制 連線小車 wifi 開啟vmw e 開啟虛擬機器 開啟兩個終端 分別遠端登陸 ssh y wheeltec 192.168.0.100 wifi 密碼 dongguan 分別輸入 遠端登入後 roslaunch turn...

c 學習筆記十二

類的操作 1 類物件使用指標的三種情況 一 使用指標成員訪問運算子 來呼叫函式 二 作為函式的引數 三 作為類的資料成員 2 指標作為資料成員 示例 如下 package類 包含兩個資料成員乙個是box類,乙個是指向package的指標 class package get 方法 box getbox...

C 學習筆記十二

標頭檔案 utility 建立 pair p1 pair p2 v1,v2 pair p3 p2 p1 make pair v3,v4 操作 賦值 p3 p1 訪問元素 p1.first p1.second 使用tie獲取 std tie v1,v2 p1 static變數只會被初始化一次 因此,靜...