C语言关于位域的概念和使用小结

LWH China shenzhen C 语言关于位

LWH China shenzhen C 语言关于位域的概念和使用小结

--------------- 2013.05

有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1两种状态,用一位二进位即可。为了节省存储空间,并使处理简便,C 语言提供了一种数据结构,称为“位域”。

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

一、位域的定义和位域变量,其形式为:

struct 位域结构名

{

位域列表

} 位域变量名;

位域列表的形式为: 类型说明符 位域名 :位域长度;

位域变量的说明与结构变量说明的方式相同。可采用先定义后说明,同时定义说明或者直接说明这三种方式。

例如: 定义bits 的位域结构,位域变量名为data :

struct bits

{

int a:4;

int b:6;

int c:4;

int d:4;

int e:14;

} data;

在上例中data 为bits 变量,共占4个字节。其中位域a 占4位,位域b 占

,

LWH China shenzhen 6位,位域c 占4位, 位域d 占4位,位域e 占14位。

二、位域的定义规则

位域的定义大致具有如下规则:

1. 一个位域可以存储在同一个字节中,也可以跨不同但相邻的几个个字节。

例如:

struct bits

{

int a:4;

int b:6;

int c:4;

int d:4;

int e:14;

} data;

,

LWH China shenzhen

位域的使用和结构体的使用相同,其一般形式为:

位域变量名·位域名

位域允许用各种格式输出。

例如:

Int main(void)

{

struct bits

{

unsigned a:1;

unsigned b:3;

unsigned c:4;

} bit,*pbit;

bit.a=1; bit.b=7; bit.c=15;

printf( "d,d,dn ",bit.a,bit.b,bit.c);

pbit=&bit;

pbit-> a=0; pbit-> b&=3; pbit-> c|=1;

printf( "d,d,dn ",pbit-> a,pbit-> b,pbit-> c);

return 0;

}

上例程序中定义了位域结构bsit ,三个位域为a,b,c 。说明了bits 类型的变量bit 和指向bits 类型的指针变量pbit 。这表示位域也是可以使用指针的。

四、位域的作用以及位域结构体的存储

位域成员不能单独被取sizeof 值。C99规定int 、unsigned int和bool 可以作为位域类型,但编译器几乎都对此作了扩展,允许其它类型类型的存在。

使用位域的主要目的是压缩存储,其大致规则为:

1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof 大小,

,

LWH China shenzhen 则后面的字段将紧邻前一个字段存储,直到不能容纳为止;

2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof 大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;

3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C 采取压缩方式;

4) 如果位域字段之间穿插着非位域字段,则不进行压缩;

5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。

五、位域结构的位域存储顺序问题

我们知道字节存储顺序有高字节优先的big-endian 大端存储法(高字节数据放在低字节地址处)和低字节优先的little-endian 小端存储法,无论使用大端法还是小端法,都不存在技术原因,只是涉及到处理器厂商的立场和习惯。INTEL 的X86平台使用小端法,IBM 、 Motorola 、Sun Microsystem的大多数微处理器则使用大端法,还有部分微处理器可以由用户自己设置是使用大端法还是小端法,如ARM 、MIPS 、PowerPC 等。

位域在存储时的顺序和它的编译器有关,一般是先申请的放在低位。

程序举例如下:

#include

void main()

{

} data; struct bits { int a :4; int b :6; int c :4; int d :4; int e :14;

,

LWH China shenzhen

} data.a=1; data.b=19; data.c=1; data.d=2; data.e=0; printf("xn",data); printf("dn",sizeof(data));

其输出结果为:

即结构体成员申请是按照顺序从低地址开始。所以上边结构体在内存中数据的排列顺序为

高地址 低地址

data.e=0; data.d=2; data.c=1; data.b=19; data.a=1;

限于个人知识有限,如有纰漏敬请见谅与斧正。

标签: