位域(位段)

  有些信息在存储时,并不须要占用一个完整的字节,而只须要占用一个或几个二进制位。数据结构

例如: 存放一个开关量时,只有0和1二种状态,只保存一位二进制位便可。为了节省存储空间,C语言提供了数据结构:位域。测试

  位域是把字节中的二进制位划分为几个不一样的区域,并说明每一个区域的位数。每一个区域有个域名,容许在程序中按域名spa

进行操做。这样就能够把几个不一样的对象用一个字节的二进制位域来表示。code

位域的定义对象

  位域定义与结构体定义相仿,形式为:blog

struct 位域结构名内存

{编译器

  类型名  位域名: 位域长度,如 int a 8;  //位域长度不能大于8(即一个字节)域名

  ......编译

};

 

注意:

  一个位域必须存储在一个字节中,当有二个连续的位域,在一个字节中存放第一个位域后剩下的空间不足以存放第二个

位域,则第二个位域将存放在下一个字节单元中,前一个字节多余的位补0。(由于一个位域必须存储在一个字节,因此位域长度最大为8)

 

 
1 struct wy 2 { 3   unsigned int a : 4; //第一个字节前4位存放该位域 4   unsigned int b : 5; //第一个字节剩下的4位不足以存放b,位域b从下一个字节开始 5 }WY; 6 sizeof(WY) == 4;位域存储的类型是int占用4个字节,根据内存对齐规则不足4字节也占用4字节。对齐规则能够往下看

 

空域:

  无论当前字节单元剩下的位数是否足以存放下一个位域,使用空域后,下一个位域都存放到下一个类型单元,好比int就存放到下个int单元

 
1 struct wyn 2 { 3   unsigned int a : 4; //第一个字节前4位存放该位域 4   unsigned int :0; 5   unsigned int b : 2; //空域后的位域从下个单元开始 6 }WYN; 7 sizeof(WYN) == 8; 由于存储的类型是int型,空域后,从下个int开始
 
 

wyn nn;  nn.a = 6; //给a赋值为6实际上是把a占用的4位赋值为 0110

 当一个位域无位域名时,它只是用来做为填充或调整位置,不能被使用(好比 int :3 仅仅是用来占3位二进制位,但这3位无法在程序里使用)。

位域内存对齐规则

1 若是相邻位域字段的类型相同,且其位宽之和小于类型的sizeof(类型)大小,则后面的字段紧邻前一个字段存储。

2 若是相邻位域字段的类型相同,且其位宽之和大于类型的sizeof(类型)大小,则后面的字段重新的存储单元开始,其偏移量为sizeof(类型)大小的整数倍

3 若是相邻位域字段的类型不一样,则各编译器的具体实现有差别,须要在编译器上测试

 

 
1 struct wyn 2 { 3   unsigned int i : 8; 4   unsigned int j : 4; 5   unsigned int a : 3;
6   double b;
7 }WYN; 8 sizeof(WYN) == 16;
i,j,a共占用2个字节,根据规则1,紧邻的int型i,j,a共占用4字节。
b位double型,占用8字节,根据对齐规则,b的内存地址必须是8的整数倍,因此在i,j,a后会填充4个字节,再存储b。
 
 
 
1 struct wyn2 2 { 3   unsigned int i : 8; 4   unsigned int j : 4; 5   double b; 
6   unsigned int a : 3;
7 }WYN2; 8 sizeof(WYN2) == 24; 同上面WYN同样,根据规则1,2:i,j,b占用16字节位域a占用3位,类型是int应该占用4字节,可是整个结构体大小应该按照最大的类型double对齐,必须是8的整数倍。因此占用24字节
相关文章
相关标签/搜索