测试环境 : Windows 7旗舰版,Microsoft Visual Studio 2010。
由于信息存储时,可能只占一位或者几位二进制位,比如开关量,只需要占据一位即可。为了节省存储空间,并且处理简单,C语言提供了一种数据结构,称为“位域”。
所谓“位域”是把一个字节的二进制位划分为不同区域,并指明每个域的名称和长度,允许程序按照域名来进行数据的操作。这样就使的利用一个字节的二进制位表示几个不同的数据对象成为可能。
位域声明形式与结构声明形式相似,位域声明形式:
Struct 位域结构名
{
类型说明符 位域名:位域长度;
……
}
注:位域长度不应该大于该类型说明符对应的数据类型的位长度。
位域赋值:
typedef struct{ unsigned int a:1; unsigned int b:3; }M; //位域声明 M m; //位域变量声明 m.a=7; //位域赋值 m.b=11;
每个包含N位的位域的值等于程序所赋值的二进制表示法的后N位所对应的值。
比如位域a的N=1,而7=111B,那么经过赋值后a=1.那么m.a=7与m.a=1的效果相同。
同理m.b经过赋值后b=3.
内存量的计算:
一个位域必须存储在同一个字节中,不能跨两个字节,前一个字节剩下的位数不足以下一个域时,下一个域会从下一个字节从新开始,但是前一字节剩下的位无法再使用。
#include<iostream> using namespace std; typedef struct{ unsigned int a:1; unsigned int b:31; //(1) }M; typedef struct{ unsigned int a:1; unsigned int b:32; //(2) }N; int _tmain(int argc, _TCHAR* argv[]) { M m; N n; cout<<"size of unsigned int :"<<sizeof(unsigned int)<<endl; cout<<"size of M :"<<sizeof(M)<<endl; cout<<"size of N :"<<sizeof(N)<<endl; return 0; }
说明:在我的环境中unsigned int是4个字节的。
在(1)处和(2)出的位数是不同的。在M中由于声明一个Unsigned int后有32个位,正好满足M内部域声明的需要。但是N共33位,声明一个unsigned int不足够使用,所以又再次扩展了一个32位。
补充一:在位域说明中,位域可以有意的使下一个位域从下一字节开始。
struct BitRegion { unsigned int a:4 unsigned int :0 /*空域*/ unsigned int b:4 /*从下一单元开始存放*/ unsigned int c:4 };
也可以有意的使下一个位域从与前一个位域间隔若干字节后开始。
struct BitRegin { unsigned int a:1 unsigned int :2 /*该2位不能使用*/ unsigned int b:3 unsigned int c:2 };