位域示例

概念引入:

C语言中的位域的使用

C/C++位域

位域使用:

位域成员不能单独被取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。不压缩。




你可能感兴趣的:(struct,存储,扩展,语言,float,编译器)