位域
C语言可以在一个结构体中以二进制位位单位来指定其成员所占内存长度,这种以位为单位的成员就称为位域(bit field)。
更高效使用存储空间,一个字节中分别存放多个信息。
struct data{
unsigned n1:6;/*n1占6个位*/
unsigned n2:4;/*n2占4个位*/
unsigned n3:4;/*n3占4个位*/
unsigned n4:2;/*n4占2个位*/
}mydata;
注意:
(1) 一个位域必须存储在同一个存储单元中,不能跨两个单元。可以闲置没有使用的存储单元,定义的每个位域长度不能超过存储的单元。比如有一个字节去使用,总共8位,却申请一个位域是9位的,就是错误的。
(2) 位域名默认时称做无名位域。
struct date{
unsigned a:2;
unsigned :2;/*空两个位*/
unsigned b:1;
}mydata;
第2次申请的2个空间的位域是闲置不用的,因为没有位域名称。
需要注意的是:同样是无名的位域,存储空间是0,有特殊的含义,它指的是这个字节剩余的不再使用,从下个新字节开始存储。例
struct date{
unsigned a:2;
unsigned :0;/*从下一个新字节开始存储*/
unsigned b:1;
}mydata;
(3) 一个结构体中既可以定义位域成员,也可以同时定义一般的结构体成员。
struct date{
unsigned a:2;
unsigned b:1;
int k;
}mydata;
(4) 不能定义以位域结构为元素的数组。关于位域的引用与结构体相同。
mydata a = 2;
mydata b = 1;
注意:a只占两位,在上面的结构体有声明,就是说,a最大存储的二进制数是11,如果写成:mydata.a = 10,并不错,但结果不是期望的10,变成了2,因为10的二进制码是1010,只截取右边两位10,故结果为2.
(5) 位域也可以参与算术表达式的运算,系统自动将其转换为整型数。
printf("%d
",mydata.a);
printf("%u
",mydata.a);
/*键入一个十进制正整数,按二进制位输出*/
int main(){
unsigned short a,b,i;
printf("输入一个整型数:");
scanf("%u",&a);
b = 1 << 15; /*构造一个最高位为1,其余各位为0的整数*/
printf("%u=",a);
for(i = 1;i <= 16;i++){
putchar(a&b?'1':'0'); /*输出最高位*/
a <<= 1; /*将次高位移到最高位*/
if(i%4 == 0)putchar(',');
}
printf("B
");
return 0;
}