在存储空间很宝贵的状况下,有可能须要将多个对象保存在一个机器字中,一种经常使用的方法是:使用相似于编译器符号表的单个二进制位标志集合,外部强加的数据格式(如设备接口等寄存器)常常须要从字的分值中读取数值.
一般采用的方法是:定义一个于相关位的位置对应的"屏蔽码"集合,如:数组
#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