C++/C 位段
位段
针对类或结构中unsigned或int成员,C++/C提供了为其指定存储位数的能力,这种成员称为位段。利用位段可用最小的位数来存放数据以更好地利用内存。位段成员必须被声明为unsigned或int类型。(注:目前测试发现,位段仅支持struct,class,以及union,单独出现则编译报错)
实例
struct BitCard{
unisgned face:4;
unsigned suit:2;
unsigned color:1;
};
包括了3个unsigned型位段:face,suit和color,用于表示一副牌中的一张牌。
声明
声明位段的方式是这样的,在unsigned或int成员后加一冒号,然后再加一个标识位段宽度(即成员被存储的位数)的整形常量。
形如:
struct位结构名{
数据类型 变量名: 整型常数;
数据类型 变量名: 整型常数;
} 位结构变量;
其中:
1. 数据类型必须是整型(unsigned或signed)。
2. 整型常数必须是非负的整数, 表示二进制位的个数, 即表示有多少位,且不能超过数据类型的限制。
3. 变量名是选择项, 可以不命名, 这样规定是为了排列需要。
位段宽度必须是在0和存储一个int型值所需位数之间的一个整数常量。前面的结构定义表明face在存储中占4位,成员suit占2位,成员color占1位。这些位数基于每个结构成员取值的范围。成员face存储在0(标识牌A)与12(表示牌K)之间的一个整数,因此需要4位存储在(4位可表示在0到15之间的任一个整数)。成员suit取值范围0到3(0代表方块,1代表红桃,2代表梅花,3代表黑桃),因此只需要2位来存储这个值。成员color要么取值为0,要么为1,因此只需1位来存储。
位结构总长度(位数), 是各个位成员定义的位数之和。 因此 sizeof( struct BitCard )的值为1,占一个字节, 计算方式 (4+2+1)/8+(((4+2+1)%8==0)?0:1)
成员访问
位结构成员的访问与结构成员的访问相同。
例如: 访问上例位结构中的color成员可写成: bc.color
(struct BitCard bc; )
位段的作用
struct info{
char name[8];
int age;
struct addr address;
float pay;
unsigned state: 1;
unsigned pay: 1;
}workers;'
上例的结构定义了关于一个工从的信息。其中有两个位结构成员, 每个位结构成员只有一位, 因此只占一个字节但保存了两个信息, 该字节中第一位表示工人的状态, 第二位表示工资是否已发放。由此可见使用位结构可以节省存贮空间。
c++可以指定命名的位段,此时位段在结构中用来作“填充项”。
struct Example{
unsigned a:13;
unsigned :3;
unsigned b:4;
};
上面将3位的位段定义为“填充项”,其中不存放任何内容;成员b 成存放于另一个存储单元中。宽度为0的未命名位段通常用于将下一个位段对齐于新的存储单元。
structure Example{
unsigned a:13;
unsigned :0;
unsigned b: 4;
};
用一个未命名的0位位段来跳过a所在存储单元中剩余的位,一边在下一个存储单元中对齐成员b。
位段操作与机器有关。有些机器允许位段跨越字边界,而有些机器不允许不能访问位段中单独的位,位的数组操作符&不能用于位段,它们没有地址位段能节省空间,但它们也会导致编译器生成更慢的机器执行代码。
几个问题
1.
void main()
{
union
{
struct
{
unsigned short s1:3;
unsigned short s2:3;
unsigned short s3:3;
}x;
char c;
}v;
v.c=100;
printf("%d/n",v.x.s3);
}
A:4 B:0 C:3 D:6
答案是A 不过自己电脑运行结果是1
结构struct x,有三个成员s1,s2,s3每一个成员占3 bit,结构与char c union ;
char 一般机器占一个字节(8 bit ,100 二进制值为:01100100,
所以s1后三bit(6,7,8 bit) :100,s2为中间三位(3,4,5 bit)为100 s3为01,所以printf(“%d/n”,v.x.s3)是1,其它是4。现在大多数系统都是小端字节序,而结构体中位域的申明一般是先声明高位。
100 的二进制是 001 100 100
小端字节序 高高低低
001—-s3
100—-s2
100—-s1
所以结果应该是 1如果先申明的在低位则:
001—-s1
100—-s2
100—-s3
结果是 4
Reference
[1] 位段 http://www.cnblogs.com/vcyuyan/articles/1730426.html
[2] 位域 http://blog.csdn.net/zhangboyj/article/details/6201856