一、概念
位域是指信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几 个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。
二、定义
位域定义格式与结构体类似,形式如下:
struct 位域结构名{
类型说明符 位域名 : 位域长度;
.
.
.
};
注:
1.位域是可以先定义后说明,也能定义和说明同是操作,也能直接说明;
2.不一定要写位域名,不写的这种是匿名的,我们不能使用它,
但是它的作用是拿来调整格式的(拿0补齐);
3.在C语言中, 规定的位域类型只能是ints,
应该是包括了signed和unsigned的char、short和int。
最好标注好是signed 还是unsigned类型;
eg:
struct mybitfields{
int a : 4;
int : 4; //匿名位域,不能调用
int b : 5;
} test;
分析:例子中test为mybitfields变量,共占两个字节,
其中a占四位,匿名的占四位(补0调整格式),b占6位。
三、位域操作
位域压缩
压缩概念:如果相邻位字段的位域类型相同,各个位域只占定义时对的bit长度。
压缩规则:
如果相邻位域字段的位域类型相等的时候,且其位域宽之后小于该类的的字节大小(sizeof()计算),则后面的字段会储存在相邻前的一个字段中储存,直到不能容纳;另语:相邻的字段中的前一个字段的字节的剩余空间足够储存下一个位域,则将下一个位域的内容储存在该字节中;
如果相邻位域字段的位域类型相等的时候,且其位域宽之后大于该类的的字节大小(sizeof()计算),则后面的字段会储存在一个新的字段中,如果前一个字段有空余的位,则拿0补齐;另语:如果相邻字段中前一个字段的字节剩余的空间不足以储存下一个位域字段的位域的时候,则从下一个字节中储存后面的位域,前一个位域的剩余空间以0补齐。
如果相邻位域字段的位域类型不相等,则根据编译器有不同的结果;
如果位域之间穿插着非位域字段,则不 进行压缩(终止压缩)
位域类型对齐
如果相邻的位域字段的类型不同,在不同的位域类型间,按通用的对齐规则进行不同数据类型间的对齐;同时在相同位域类型的字段间按以上两条规则对齐。整个位域结构的总大小为其中位域字段的最宽基本类型成员大小的整数倍,即小于它的大小的按最大的计算。
四、例题分析
20170513203948343.png
20170513211521706.png