C语言的结构体位域
前面可以看到,使用unoin
共用体可以节省数据的存储空间。
同样,在结构体或者共用体中,使用位域也可以达到这个效果。
先看看什么时候可以使用位域,这个特点大多数人都不会用到,用到的大部分人都基本跟底层打交道,比如驱动开发、单片机开发等。
先看一个最简单的例子,比如我们的红绿灯系统,先定义一个结构体:
1 | typedef struct |
此时如果看一下TrafficLight结构体的大小,应该是12个字节
但是我们知道对于这几种灯而言,只有2中状态,开和关,也就是1和0,也就是1个bit其实就能表达,所以针对这种情况,有了位域的概念,先看一下位域的声明:
1 | typedef struct |
- type:整数类型
- name:为位域的名称
- width:为位域中位的数量,其值需要小于等于type指定的类型大小
所以交通灯的结构体使用位域的概念就如下所示:
1 | typedef struct |
三色红绿灯加起来一共需要3个bit,所以一个无符号整型就可以容纳这些值了,此时看一下这个结构体的长度,应该为4。
总结一下:
当结构体或共用体中有无符号整型或有符号整型成员时,C语言允许用户指定这些成员所占用的存储位数,即位域。通过将数据存储在它们所需的最小数目的存储位内,位域能够有效地提供存储空间的利用率,但是,要注意,位域成员必须被声明为有符号整型或无符号整型。
代码如下:
1 | /*beginner/struct/struct6.c*/ |
编译运行
直接输入make
就可以了。
1 | #beginner/struct/Makefile |
运行输出如下:
1 | $ ./struct6 |
扩展
既然位域指定了长度位,所以就涉及到万一赋值超过了会发生什么情况,可以通过给红绿灯赋一个大值看看。
比如复制一个2,那么会得到如下警告:
1 | warning: implicit truncation from 'int' to bit-field changes value from 2 to 0 [-Wbitfield-constant-conversion] |
编译有警告,不过还是生成了可执行文件,运行下看看结果吧。