目录
一、位段
位段的声明和结构是类似的,有两个不同的:
位段的成员必须是int,unsigned int 或 signed int
位段的成员名后边有一个冒号和一个数字
#include <stdio.h>
struct S
{
int a : 2;
int b : 5;
int c : 10;
int d : 30;
};
int main()
{
struct S s = { 0 };
printf("%d\n", sizeof(s));
return 0;
}
结果是8个字节
冒号后面的空间表示需要多少个比特位,所以加起来总共就是47个bit,也就是6个字节就够了,但是这不是结果。位段也有自己的内存分配特点
二、内存分配
位代表二进制位
位段的成员可以是int,unsigned int,signed int 或者是char(属于整形家族)类型
位段的空间上是按照需要以4个字节(int)或1个字节(char)的方式来开辟的
位段涉及很多不确定因素,位段是不跨平台的,注意可移植的程序应该避免 使用位段
因为是int类型,所以开辟4个字节空间,也就是32个bit,然后依次放置,放到d时,一开始开辟的空间不够了,还剩15个bit,所以只能在开辟4个字节放d,所以最终8个字节。这里面最大的数字也不会超过32。
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 = 20;
s.c = 3;
s.d = 4;
return 0;
}
开辟空间后,变量从左还是右开始占领空间这无标准,每个编译器都按照自己的来做。全部放好需要3个字节。
现在我们输入这些数字,10的二进制位是1010,但是a只有3bit,所以只能存放010。20的二进制位是10100,但是b只有4bit,所以存放0100。3的二进制位是011,但是c有5bit,所以前面补0,放进去后就是00011。4的二进制位是0100,所以直接可以放。内存中是以16进制为展示,那么把每个字节的内容转换为16进制即可,空出来的空间用0填补。
三、跨平台问题
int位段不确定按照有符号还是无符号数处理
位段最大位的数目不确定(不知道几位机器)
位段成员在内存中从左向右分配还是右向左分配未定义
当一个结构包含两个位段,第二个位段成员无法容纳第一个位段剩余的位时,舍弃剩余的位还是利用,不确定
总结:相比于结构体,位段可以达到同样的效果,且更节省空间,但有跨平台问题存在
结束。