在C语言中,位段是一种数据体成员,其意义是自己指定成员占用的位数(不是字节数),具体声明格式如下:
struct 结构体名{
类型 成员名: 位数;
......
};
-其中类型通常是int类型(包括unsigned int和signed int),表示位段成员类型。(为什么是通常呢?有些编译器环境下char也可以指定位数,可能因为都属于整型)。
-成员名:位段的名称。
-位数:指定该成员的位数。
我们简单举例说明:
struct NUM{
int a:5;
int b:10;
int c:15;
int d:20;
}
这个例子中,struct NUM 有4个成员,正常来说这四个字节各占32位宽,但是我们指定占位,将其位宽分别指定为5,10,15,20。所以它整个结构体所占的字节空间也发生改变,并不是原来的16个字节,而是8个字节。我们来解析一下为什么。
//开始系统根据int 类型开辟32位宽
//随后a 又指定了它值用5个位宽
32-5=27位宽
//b指定10个位宽
27-10=17位宽
//c指定15位宽
17-15=2位宽
//d指定20位宽,因为位宽不够所以得重新开辟一个32位宽(int)。
这里我们又会产生疑问,剩余2位宽,那么d会不会使用这剩余的2位宽呢?我们举例说明
我们假设浪费了那个2位宽
struct EG{
char a:3;
char b:4;
char c:5;
char d:6;
}
int main()
{
struct EG eg={0};//有8位宽往里面存a,b,c,d,不够会开辟新的8位宽
eg.a=10;//1010------指定3位宽-取010;
eg.b=11;//1011------指定4位宽-取1011;
eg.c=12;//1100------指定5位宽-取01100;
eg.d=13;//1101------指定6位宽-取001101;
return 0
}
//010(a)->00000000=00000010;(五位宽暂时空余)
//1011(b)->00000010=01011010;(1位宽暂时空余浪费开辟新的8位宽)
//01100(c)->00000000=00001100;(3位宽暂时空余浪费开辟新的8位宽)
//001101(d)->00000000=00001101;(完成不必开辟)
//我们总结一下 01011010(5A) 00001100(0C) 00001101(0D)
我是用vs2019运行的,我们用它监视,查看s的地址如果是5A 0C 0D,这就是在位宽不足下个数的情况下会浪费空余位宽,这个留给大家自己运行了。