对于我来说,位字段这个概念非常陌生。故,以下内容不能保证正确性。
位字段是C语言中一种存储结构,不同于一般结构体的是它在定义成员的时候需要指定成员所占的位数。
位字段(bit field)是一个 signed int 或 unsigned int 类型变量中的一组相邻的位(C99和C11新增了_Bool类型的位字段)。位字段通过一个结构声明来建立,该声明为每个字段提供标签,并确定该字段的宽度。
例如:声明了一个 4 个 1 位的字段:
struct{
unsigned int autfd : 1;
unsigned int bldfc : 1;
unsigned int undln : 1;
unsigned int itals : 1;
} prnt;
根据该声明,prnt 包含 4 个 1 位的字段。可赋值:
prnt.itals = 0;
prnt.undln = 1;
由于每个字段都为 1 位,所以只能赋值 1 或 0 。变量 prnt 被存储在 int 大小的内存单元中,但是在本例中只使用了其中 4 位。
使用位字段时,要确保赋值不超过字段所能容纳的范围。
超出了怎么办?
(尽量别超出就完了,超出的不想看)
超出了会用到下一个 unsigned int 类型的存储位置。一个字段不允许跨越两个 unsigned int 之间的边界。编译器回自动移动跨界的字段,保持 unsigned int 的边界对齐。一旦发生这种情况,第一个 unsigned int 中会留下一个未命名的“洞”。
使用未命名的字段宽度“填充”未命名的“洞”。使用一个宽度为 0 的未命名字段迫使下一个字段与下一个整数对齐:
struct
{
unsigned int field1 : 1;
unsigned int : 2;
unsigned int field2 : 1;
unsigned int : 0;
unsigned int field1 : 1;
}stuff;
stuff.field1 和 stuff.field2 之间有一个 2 位的空隙, stuff.field3 将存储在下一个unsigned int 中。
位字段也挺好用的!
可以按位操作!
假设定义
struct box_props
{
bool opaque : 1;
unsigned int fill_color : 3;
unsigned int : 4;
bool show_border : 1;
unsigned int border_color : 3;
unsigned int border_style : 2;
unsigned int : 2;
}
struct box_props UsView = {true,YELLOW,true,GREEN,DASHED};
UsView位示意图:
1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 |
可直接进行 UsView | AAAA 这样的形式更改参数!!
就这样的位操作方法。
读的时候还是 UsView.fill_color 这种形式读。
OK,剩下的就需要编程体会了