结构体补充:位段
1.什么是位段
位段的声明和结构体是类似的,有两个不同:
1.位段的成员必须是int、unsigned int 或 signed int 和 char,在C99中位段成员的类型也可以选择其他类型。
2.位段的成员后面有一个冒号和一个数字。
比如:
struct A
{
int _a:2;//2个比特位
int _b:5;//5个比特位
int _c:10;//10个比特位
int _d:30;//30个比特位
};//其中int——4个字节——32个比特位,所以int类型的成员后面的数字不能超过32
2.位段的内存分配
1.位段的成员可以是int unsigned int signed int char等类型
2.位段的空间上是按照需要以4个字节(int) 或者1个字节(char)的方式来开辟的
3.位段涉及很多不确定因素,位段是不垮平台的,注重可移植的程序应该避免使用位段
struct S
{
char a:3;
char b:4;
char c:5;
char d:4;
};
struct S s = {0};
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;
3.位段的跨平台问题
总结:
跟结构相比,位段可以达到相同的效果,并且可以很好的节省空间,但是有跨平台的问题存在。
4.位段的应用
下图是网络协议中,IP数据报的格式,我们可以看到其中很多的属性只需要⼏个bit位就能描述,这里使用位段,能够实现想要的效果,也节省了空间,这样网络传输的数据报大小也会较小⼀些,对网络的畅通是有帮助的。
5.位段使用的注意事项
位段的几个成员共有同⼀个字节,这样有些成员的起始位置并不是某个字节的起始位置,那么这些位置处是没有地址的。内存中每个字节分配⼀个地址,⼀个字节内部的bit位是没有地址的。
所以不能对位段的成员使用&操作符,这样就不能使用scanf直接给位段的成员输入值,只能是先输入放在⼀个变量中,然后赋值给位段的成员。
struct A
{
int _a:2;
int _b:5;
int _c:10;
int _d:30;
};
int main()
{
struct A sa = {0};
scanf("%d",&sa._b);//这是错误的
//正确的示范
int b = 0;
scanf("%d",&b);
sa._b = b;
return 0;
}