一、前言
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。
二、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:
struct 位域结构名
{ 位域列表 };
其中位域列表的形式为: 类型说明符 位域名:位域长度
例如:
struct sa
{
char a:3;
char b:4;
char c:1;
};
三、位域的内存分配
看了些网上的资料和C关于位域的书籍,然后动手在编译器上测试,发现网上和书上的关于位域内存分配的内容和我的测试结果有偏差(姑且认为那些内容是错误 的);包括前言对位域的说明也不够严谨!
(1) 位域必须存放在一个字节里面,不能跨越两个字节;(这句有误)
例如:
struct s
{
short a:5;
short b:5;
short c:5;
}sa;
在TC2.0/VC6.0/gcc上sizeof(sa)得到的大小一致为2;
可 见,位域可以跨越两个字节,位域可以跨越sizeof(定义位域的类型)个字节!如上例可以跨越sizeof(short)=2个字节。
(2) 位域的长度不能大于1个字节,即不能大于8;(这句也有误)
例如:
struct s
{
short a:9;
short b:3;
short c:4;
}sa;
同样,在TC2.0/VC6.0/gcc上编译通过,且sizeof(sa)= 2;因此同1,位域的长度大小应该是不超过8*sizeof(定义为域的类型)
(3) 关于空域
struct s
{
short a:5;
short :0; //空域
short b:5;
}sa;
测试结果:sizeof(sa) = 4;空域后面的位域从新的存储单元开始;一个存储单元包括sizeof(定义位域的类型)个字节;
(4) 关于无名域
struct s
{
short a:5
short :5; //无名域
short c:5;
}sa;
在VC6.0/GCC上测试结果:sizeof(sa) = 2;填充5位,总位数小于16,所以大小为2。
注:把无名域也看成是位域;因此它也必须满足(1)和(2)。
四、位域的使用
对于位域的使用,同其他结构体成员使用一样;如可以这样引用上面定义的位域:s.a; s.c ;空域和无名域不可访问!对位域赋值不能超过位域所能表示的最大范围,超过了将会被截短。
五、位域的效率
大家都知道,结构体成员的对齐是为了提高访问数据的效率;而位域成员显然没有进行结构体对齐,这样对数据访问的效率存在影响吗?
理所当然 (应该是我想当然)这样会降低效率;然而,我看了一些网页上的资料(我没有进行仔细的分析,只是借用别人的结论);对位域成员的访问在编译阶段进行了优化;从生成的汇编源代码看出效率是一样的,并没有降低!
阅读(1486) | 评论(0) | 转发(0) |