5.6 C51的位域

位域型数据结构,也称为“位段”。位域也是聚合型数据的一种。在内存中存储一些信息时,有时并不需要占用一个完整的字节空间,而只需占一个或几个二进制位即可。例如,存放一个开关量时,只有0或1两种状态,用1位二进制位即可满足。因此采用位域可以节省存储空间,加快程序执行速度。

5.6.1 位域和位域变量的声明

位域类型是把一个字节中的二进制位划分为若干个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名对位进行操作。这样就可以把几个不同的对象用一个字节的二进制位来表示。下面分别介绍位域和位域变量的声明方法。

1.位域的声明

声明位域与结构定义十分相似,声明位域的一般形式如下。


struct位域结构名

{

类型说明符位域名:位域长度;

……

};


其中,struct为关键字,和结构的类型关键字相同。在位域结构体中,说明了位域名的类型及其长度。声明位域的示例如下。


struct btest

{

int a:4;

int b:1;

int c:3;

};


本例中,定义了位域结构btest,其中包含3个位域a、b和c,长度分别为4、1和3。

2.位域变量的声明

位域变量的声明与结构变量、联合变量、枚举变量的说明方式相似,可以采用如下3种方式。

❑声明位域时,同时声明位域变量,示例如下。


struct btest

{

int a:4;

int b:1;

int c:3;

}data;


本例中,声明的变量data为btest位域变量,位域变量data的总长度为一个字节。其中位域a占4位,位域b占1位,位域c占3位。

❑先声明位域,再声明位域变量,示例如下。


struct btest

{

int a:4;

int b:1;

int c:3;

};

btest data;


❑直接进行声明位域变量,示例如下。


struct

{

int a:4;

int b:1;

int c:3;

}data;


在声明位域的时候,需要注意如下几点。

❑声明位域时,在位域体内可以省略一个或一些位域名,即为空域。这种空域只能用来作填充或调整位置,而不能在程序中使用,示例如下。


struct btest

{

int a:1;

int:3;//该3位不能使用,为空域

int b:2;

int c:2;

};


❑一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应采用空位域避开,而从下一单元起存放该位域。有时也可以有意使某位域从下一单元开始,示例如下。


struct btest

{

unsigned a:4;

unsigned:0;//空域,避开不够的空间

unsigned b:6;//从下一单元开始存放

unsigned c:2;

}


本例中,位域a占第一字节的4位,而后4位填0表示不使用;位域b从第二字节开始,占用6位,c占用2位。即位域b和c重新占用一个字节。

❑由于位域不允许跨两个字节,因此每个位域的长度不能大于一个字节,即不能超过8位二进制位。

从以上分析可以看出,位域在本质上就是一种结构类型,不过其成员是按二进制位进行分配存储的。在单片机程序设计中,位域特别适合于需要位操作的程序中。