1 什么是位段
位段的声明和结构是类似的,有两个不同:
1.
位段的成员必须是
int
、
unsigned int
或
signed int 或者char
。
2.
位段的成员名后边有一个冒号和一个数字。
位段的位其实指的是“二进制位”
我们通过一个例子来理解一下“位”
struct A
{
//开辟4byte==>32bit
int _a : 2;//占2bit 剩下30bit
int _b : 5;//占5bit 继续使用,剩下25bit
int _c : 10;//占10bit 继续使用,剩下15bit
//不能满足使用,再开辟4byte
int _d : 30;//占30bit
//存在未知:剩下的15个bit不清楚是否还会继续使用
};
int main()
{
printf("%d\n", sizeof(struct A));//8
return 0;
}
结论:
位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
下面这个例子可以帮助我们更好的理解这种不确定性
struct S
{
//1byte
char a : 3;//剩下 5bit
char b : 4;//剩下 1bit
//会不会使用这个bit
//+1byte
char c : 5;//1. 剩下 4bit 2.剩下3bit
char d : 4;//1. 刚好 2.再+1 byte
//所以第一种需要2byte
//第二种需要3byte
};
int main()
{
printf("%d\n", sizeof(struct S));//8
return 0;
}
vs下结果是这样的,我们能确定的是 vs下是第二种方式。
但我们不能确定其他的操作系统也是。
2 位段的内存分配
1.
位段的成员可以是
int unsigned int signed int
或者是
char
(属于整形家族)类型
2.
位段的空间上是按照需要以
4
个字节(
int
)或者
1
个字节(
char
)的方式来开辟的。
图1
ps:内存的放置是从低位到高位放置
经过内存中的验证,我们发现vs中的空间使用是按照图1所示
3 位段的跨平台问题
1. int
位段被当成有符号数还是无符号数是不确定的。
2.
位段中最大位的数目不能确定。(
16
位机器最大
16
,
32
位机器最大
32
,写成
27
,在
16
位机
器会出问题。
3.
位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
4.
当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是
舍弃剩余的位还是利用,这是不确定的。
总结:
跟结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。