《C语言参悟之旅》新鲜试读连载8

9.1.11   位域

1. 什么叫位域

有些信息在存储时,并不需要占用一个完整的字节,而只需占一个或几个二进制位。例如,在存放一个开关量时,只有01 两种状态,用一个二进制位表示即可。而在使用C语言开发程序,特别是一些系统级或嵌入式程序时,内存往往是特别宝贵的。为了节省存储空间,并使处理简便,C语言提供了一种数据结构,称为“位域”或“位段”。

所谓“位域”是把一个字节中的二进制位划分为几个不同的区域,并说明每个区域的位数。每个区域有一个域名,允许在程序中按域名进行操作。这样一个字节的二进制位就可以表示几个不同的量。

这有点类似于时下流行的两截裤,如果把一整条裤子看作一个字节,两截裤就是把一条裤子分成两截,而位域则是把一个字节分成几截,每截独立的表示一个量。如图9.12所示:

9.12 两截裤与位域

2. 位域及位域变量的定义

位域的定义与结构定义相仿,其形式为:

struct 位域结构名

{

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

……

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

};

同样的,位域变量的定义与结构体变量定义的方式相同。可采用先定义位域后定义位域变量,同时定义或者直接定义位域变量三种方式。具体的形式此处就不再叙述。

例如,下面采用同时定义的方式定义一个位域变量field

struct byte_struct

{

int x:8;

int y:2;

int z:6;

} field;

其表明fieldbyte_struct类型变量,共占2个字节。其中位域x8位,位域y2位,位域z6位。如图9.13所示:

9.13 位域变量的内存表示

3. 位域定义时注意事项

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

struct byte_struct

{

unsigned a:6;

unsigned :0;    //空域

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

unsigned c:4;

} two_byte;

其中,a占第一字节的6位,后2位填0表示不使用,称为空域;b从第二字节开始,占用4位,c占用4位。如图9.14所示:

9.14 位域变量的内存表示

l         位域的长度不能大于一个字节的长度,即不能超过8位。

例如,下面的定义是非法的:

struct bs

{

unsigned a:2;

unsigned b:10;  //位域长度不能大于8

};

l         位域可以无位域名,这时其只用来做填充或调整位置,而不能使用。例如:

struct bs

{

unsigned a:4;

unsigned:4;     //4位不能使用

};

4. 位域的使用

位域从本质上说就是一种结构类型,不过其成员是按二进位分配的。所以位域的使用和结构成员的使用相同。

下面的程序清单演示了普通位域变量和指针位域变量的使用。

#include <stdio.h>

 

//位域声明

struct byte_struct

{

unsigned a:4;

unsigned b:2;  

unsigned c:1;

};

 

void main()

{

struct byte_struct bit; //定义普通位域变量

struct byte_struct *pbit; //定义指针位域变量

//普通位域变量的使用

bit.a=1;

bit.b=7;

bit.c=15;

printf("%d,%d,%d/n",bit.a,bit.b,bit.c);

//指针位域变量的使用

pbit=&bit;

pbit->a=0;

pbit->b&=3;

pbit->c|=1;

printf("%d,%d,%d/n",pbit->a,pbit->b,pbit->c);

}

可以看出,位域变量的使用和结构体变量从形式上完全相同,只不过成员都是用二进制位来表示,所以会经常使用一些位操作。

 

最新作品《C语言参悟之旅》全新上市,敬请关注!
官方网站:
http://www.tqbooks.net/product/gb/product_detail.asp?catalogid=10&productid=1474
China-pub有售:
http://www.china-pub.com/49980

如果你想同我交流,欢迎点击链接http://student.csdn.net/space.php?uid=113770和我成为好友
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值