位域使用:
位域成员不能单独被取sizeof值(编译报错),我们这里要讨论的是含有位域的结构体的sizeof,只是考虑到其特殊性而将其专门列了出来。
C99规定int、unsigned int和bool可以作为位域类型,但编译器几乎都对此作了扩展,允许其它类型类型的存在。使用位域的主要目的是压缩存储,其大致规则为:
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;
4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
和结构体一样,位结构体也是按照成员的最大长度字节来对齐分配空间的。
实验范例:
例1:对位域的赋值不能超过其允许的范围,整个结构体的总大小为最宽基本类型成员大小的整数倍。如下为int(即4字节)的整数倍。
#include<iostream>
using namespace std;
struct bs
{
int a:23;//如果24则sizeof(bs)=8;
int b:3;//限定了b的范围只能是000-111。
int c:6;
};
int main()
{
struct bs b;
b.a=64;
b.b=3;//011,第一位表示正负号,0正1负 ,0后面的11表示3。
b.c=10;
cout<<sizeof(b)<<endl;
cout<<b.a<<" "<<b.b<<" "<<b.c<<endl;//sizeof: int 4、unsigned int 4、short int 2、unsigned short 2、long int 4、unsigned long 4、float 4、double 8、long double 12、char 1 、unsigned char 1
getchar();
}

如果把int a:23->24,b.b=3-->4。则结果如下:
#include<iostream>
using namespace std;
struct bs
{
int a:24;//如果24则sizeof(bs)=8;
int b:3;//限定了b的范围只能是000-111。
int c:6;
};
int main()
{
struct bs b;
b.a=64;
b.b=4;//100,第一位表示正负号,0正1负 .
b.c=10;
cout<<sizeof(b)<<endl;
cout<<b.a<<" "<<b.b<<" "<<b.c<<endl;//sizeof: int 4、unsigned int 4、short int 2、unsigned short 2、long int 4、unsigned long 4、float 4、double 8、long double 12、char 1 、unsigned char 1
getchar();
}

如果b.b=13,即1101,超过了000-111的范围。数据就会被截断。cout<<b.b<<endl的结果-3。说明留下了101。前面多出的部分被截断。
如果b.b=9,即1001,超过了000-111的范围。数据就会被截断。cout<<b.b<<endl的结果1。说明留下了001。前面多出的部分被截断。
例2:相邻的位域字段的类型不同
#include<iostream>
using namespace std;
struct test
{
char a:1;
int b:3;
char c:2;
};
int main()
{
test t1;
cout<< sizeof(t1)<<endl;
getchar();
return 0;
}
在devc++下,结果为4。压缩。
在vc6.0下,结果为12。不压缩。