位段
一.简介
位段和结构体很相似。不同的是:
- 位段的成员:成员名 : 数字
- 且其成员必须是整型(char、int、unsigned int……)
示例:
struct S
{
char a : 3;
char b : 2;
char c : 7;
};
S就是一个位段类型,其成员
a
为占3个比特位的char类型变量(即有效范围为000~111),相同的,b
为占2个比特位的char类型变量,c
为占7个比特位的char类型变量。
由此可见,位段的设计初衷就是为了节约空间的。
二.不易移植性
不同平台下对于位段的处理不同,因此使用位段可能存在跨平台问题
- 位段的空间以1个字节1个字节(或4个字节4个字节)的方式开辟
- int类型的成员变量被当成有符号还是无符号数是不确定的
- 给变量所占(比特位)大小的数字范围不能确定,(比如在16位机器中,一个int占2个字节,如果是int a : 17的话就超出范围就会出错的)
- 位段的大小不确定:位段中成员在内存中从左向右或从右向左左分配;如果第二个成员需要的比特位空间大于上一个成员使用某个字节后的剩余空间,那么这些剩余空间是否被利用不确定。
三.内存分配
下面代码主要是为了展现不同编译器对于位段的处理,代码本身无实际意义(非位段使用场景示例)
1.在vs下测试
可以发现在vs下,对于位段S,是按4个字节4个字节开辟了8个字节的空间。
成员a
的3个比特位空间分配在第1个字节并且按照从右向左(←)分配;
成员b
的2个比特位空间被分配在第1个字节的剩余位且按照从右向左分配;
第1个字节剩余3个比特空间 < 成员c所需要的7个比特,舍弃剩余的3个比特空间,c
的5个比特的空间被分配在第2个字节处;
对于int类型的成员d
,其被分配在后4个字节处。
对位段成员进行赋值时,超出给位段的二进制数值会被舍弃
2. 在gcc下测试
可以发现在gcc下,位段S所占的空间更小,只有4个字节大小。
在gdb调试下,位段S的内存内存分配如上图。
所以在不同平台下,对位段的编译处理是不同的。
🦀🦀观看~