在存儲空間很寶貴的狀況下,有可能須要將多個對象保存在一個機器字中,一種經常使用的方法是:使用相似於編譯器符號表的單個二進制位標誌集合,外部強加的數據格式(如設備接口等寄存器)常常須要從字的分值中讀取數值.
一般採用的方法是:定義一個於相關位的位置對應的"屏蔽碼"集合,如:數組
#define KEYWORD (1<<0) #define EXTRENAL (1<<2) #define STATIC (1<<3)
或者測試
enum{ KEYWORD = 01, EXTRENAL = 02, STATIC = 04 };
這些數字必須是2的冪,這樣就能夠用移位運算,屏蔽運算以及補碼運算進行簡單的操做.好比:code
flags |= EXTEERNAL | STATIC;//置1 flags &= ~(EXTEERNAL | STATIC);//置0
儘管這樣的方法容易掌握,可是C語言提供了一種能夠替代的方法,即直接定義和方位一個位字段的能力,沒必要經過以上的邏輯運算符,即位字段.經過位字段,以上的#define定義能夠用如下的語句替代:對象
struct { unsigned int is_keyword : 1; unsigned int is_extern : 1; unsigned int is_static : 1; }flafs;
這裏定義一個變量flags,它包含3個1位的字段,冒號後的數字表示字段的寬度(用二進制位數表示),字段被聲明爲unsigned int,以保證它們的無符號量.
單個字段的引用方式與其餘結構成員相同,例如:接口
flags.is_keyword, flags.is_extern
等;字段的做用與小整數類似,同其餘整數同樣,字段能夠出如今算數表達式中,所以,能夠表示爲:編譯器
flags.is_extern = flags.is_static = 1;//置1 flags.is_extern = flags.is_static = 0;//置0 if(flags.is_extern == 0 && flags.is_static == 0) ...//用於對is_extern和is_static的測試
字段的全部屬性幾乎都同具體的實現有關,字段能夠不命名,無名字段(只有冒號和寬度)起填充做用,特殊寬度0能夠用來強制在下一邊界上對齊.字段不是數組,沒有地址,不能作&取地址操做.it