根据K&R书籍记载,位段只能是signed int或者unsigned int类型,位段可以不命名,无名字段(只有一个冒号和宽度)起填充作用,宽度为0的位段用来墙纸在下一字节边界上对齐。对于字段位端的解释根据机器不同有所不同,位段不是数组,没有地址,所以不能使用&取地址。
以此文一个小例子来备忘位段的使用:
#include<stdio.h>
#include<string.h>
#include<stddef.h>
struct fbit
{
unsigned flag : 1; //符号位
unsigned ex : 7; //指数位
unsigned dec : 24; //小数位
};
int main()
{
float f = 3.1415926;
struct fbit f_bit;
f_bit = *( struct fbit *)&f;
printf("%x %x %x\n",f_bit.flag , f_bit.ex , f_bit.dec );
return 0;
}
位段在表达式中会被自动提升转换类型,例子如下:
#include<stdio.h>
#include<string.h>
#include<stddef.h>
struct fbit
{
unsigned int a:2;
int b:2;
};
int main()
{
struct fbit f_bit;
f_bit.a = 1;
//1+1=10(这里都是二进制处理,因为只是单纯的进行01填充,并没有转换成其它进制),也就 //是十进制的2,因为a是无符号类型,所以提升类型的时候是高位是用符号位0进行扩展,扩展之后为...0010
f_bit.a += 1;
f_bit.b = 1;
//1+1=10(这里都是二进制处理,因为只是单纯的进行01填充,并没有转换成其它进制),也就 //是十进制的2,因为b是有符号类型,所以提升类型的时候是高位是用符号位1进行扩展,扩展之后为...1110
f_bit.b += 1;
printf("%d %d\n",f_bit.a,f_bit.b);
return 0;
}
所以输出是2,-2