目录
一、什么是位段?
二、位段的内存分配
三、位段的应用
一、什么是位段?
C 语言允许一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为"位段"或"位域"(bit field)。含有位段的结构体称为位段结构。利用位段能够用较少的位数存储数据。
位段的定义格式:
type [var] : digits;
-
其中
type
只能是整型或枚举类型(通常是无符号类型)。 -
位段名称
var
是可选参数,即可以省略,如果省略,这就是一个无名位段。 -
digits
则表示该位段所占的二进制位数,但不能超过type
所能表示的最大位数。
例如:
struct S
{
unsigned int a : 8; // 位段 a,占 8 位
unsigned int b : 16; // 位段 b,占 16 位
unsigned int : 0; // 无名位段,占 0 位
int c : 8; // 位段 c,占 8 位
};
紧接着产生的问题就是,sizeof(struct S) 是多少?
二、位段的内存分配
-
位段结构的所有成员实际上存储在一个或多个整型变量中。如果一个整型变量能够存储得下位段结构中的所有成员,那么位段结构中的所有成员就放在这个整型变量当中。
-
如果一个整型变量容纳不下位段结构中的所有成员,对于剩余的位,是舍去,还是利用,这是不确定的。
-
通常在大端序系统(如 PowerPC),安排位段从最重要字节(most-significant byte)到最不重要字节(least-significant byte),在一个字节内部从最高有效位(most-significant bit)到最低有效位(least-significant bit)。
而在小端系统(如 x86),安排位段从最不重要字节(least-significant byte)到最重要字节(most-significant byte),在一个字节内部从最低有效位(least-significant bit)到最高有效位(most-significant bit)。
最低有效位(Least Significant Bit, lsb)是指一个二进制数中的第 0 位(即最低位),权值为 2^0。
最高有效位(Most Significant Bit, msb)是指一个 n 位二进制数字中的 n - 1 位,具有最高的权值 2^(n -1)。
- 无名位段用来填充(padding)内存布局,只有无名位段的二进制位数可以为 0,这种占 0 比特位的无名位段用来强迫下一个位段从下一个位段存储单元开始存放。
所以 sizeof(struct S) == 8。
位段内存分配与内存对齐的实现方式依赖于具体的机器和系统,在不同的平台可能有不同的结果,这导致了位段在本质上是不可移植的。
例如(测试环境为 vs2019 x86):
#include <stdio.h>
struct S
{
char a : 3;
char b : 4;
char c : 5;
char d : 4;
};
int main()
{
struct S s = { 0 };
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;
return 0;
}