juliusun.com
第 37/50 节 冥河C语言教程
结构体定义成员时,还有一般特殊的用法。结构体的成员可以不是占用某个系统预定义类型空间大小,而是占用自定义个数二进制比特位,这样的结构体成员,称为位域,也称位段。
本节的目的是普及一下位域的基础知识,不同的编译器实现方式和限制各不相同,实际开发时以使用的编译器实际支持为准。
位域成员定义方式如下:
类型 位域成员名 : 占用二进制比特位个数
例:
注意,虽然位域成员自定义位数个数,但是也要确定位域成员类型,且位域成员占用位数不能多于类型的位数。
位域成员占用位数多少,会影响其值作用范围,使用时请注意。
例:
位域成员存放规则如下:
1、相邻位域成员类型相同,位数之和小于等于类型大小,则后面位域成员紧跟前一个,直到不能容纳为止。
2、相邻位域成员类型相同,位数之和大于类型大小,后面成员跳过类型空间,从下一个相同类型空间开始存放。
3、相邻位域成员类型不同,后一个成员跳过前一个成员类型,从下一个本成员类型空间开始存放(部分编译器优化,归类相同类型成员,不讨论)。
例:
位域成员可以没有成员名,叫空域,表示位数空闲不用。例:
空域有一种特殊用法,占用0位,表示跳过此类型空间,后面的成员从下一个类型空间开始存放,就是进行对齐,例:
注意,如果空域和上一个成员类型不同,则按两者占用空间较大的类型计算,例:
上面只按规则计算,不同的编译器规则可能有变,且可能存在优化,如开发时必须要用,请阅读所使用编译器的技术文档,本节只是初步介绍位域概念。
位域成员也可以与普通成员共同使用,普通成员总是跳过位域单元,如。
位域成员必须是基本类型,如int、char等,不能为数组、结构体等复杂类型。
不能通过取地址符获取位域成员地址,但是可以通过指向结构体的指针来引用位域成员,比如。
位域成员是编译器通过位运算计算而得,并不是真的在内存中按所说的规则存放,只不过对于开发者看来,像是真的自定义位数一样。
位域成员引用与正常成员引用方式相同,下面举一个简单的例子,定义一个结构体表示3盏不同颜色的灯的亮暗,1为亮,0为暗,代码:
效果类似如下图:
运行平台不同效果图有所差异。