什么是位段
位段的声明和结构体是类似的,但有两个不同:1.位段的成员必须是int、unsigned int、signed int或char。2.位段的成员名后面有一个冒号和一个数字。
比如
struct S { int a : 2; int b : 5; int c : 10; int d : 30;
S就是一个位段类型
冒号后面的数字代表的是成员变量占多少个bit位
接下来将详细探究一下“占多少个bit位”的意思,以及位段的意义
位段的内存分配
1.位段的成员可以是int unsigned int signed int 或char(属于整型家族)类型
2.位段的空间上是按照需要,以4个字节(int)或1个字节(char)的方式来开辟的。
3.位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
回过头看上面的位段S,计算它的大小
struct S { int a : 2; //成员占2个bit位 int b : 5; //成员占5个bit位 int c : 10; //成员占10个bit位 int d : 30; //成员占30个bit位 }s; int main() { printf("s = %u\n", sizeof(s)); return 0; }
例子
struct X { char a : 3; char b : 4; char c : 5; char d : 4; }; int main() { struct X x = { 0 }; x.a = 10; x.b = 12; x.c = 3; x.d = 4; return 0; }
我们调试程序,看看在内存中的分配情况:
VS编译器是怎样分配位段的内存的?我们看看分配过程
位段的跨平台问题
1.int位段被当成有符号数还是无符号数是不确定的。
2.位段中的最大位的数目不能确定。(16位机器最大为16,32位机器最大为32.如果写成27,在16位机器运行就会出现问题)
3.位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
4.当一个结构包含两个位段,第二个位段成员比较大,无法容纳第一个位段剩余的位时,是舍弃剩余的位还是利用,这也是不确定的。
位段的意义以及应用
位段的意义在于节省空间,比如说:
在实际生活中,某一些数据的取值,它所有的可能性可能并不能占用满每一个int类型。我们给出一个性别,那么性别有3中取值的可能:男、女和保密。
男-00女-01保密-10
这个时候我们发现两个比特位可以有4种情况:00、 01、 10、 11.但是实际问题只有3种情况。
以此种情况的思路借用来表达位段的意义
位段的应用
上图是网络上IP数据包的格式,当你想要在网络上发一条消息给你的好友,信息是需要进行分装的,消息作为数据只是传输的一部分,还有一部分传输的是分装中的其他信息。比如4位版本号,4位首部长度,这些信息只需要4个bit,如若不使用位段,直接每个部分一个整形的给空间,就会造成空间的大量浪费。
总结
跟结构相比,位段可以达到同样效果,但是可以很好的节省空间,但是有跨平台的问题存在。如果需要跨平台使用位段,就要研究透各个平台的位段定义标准。