1、为什么使用位域
(1) 节省空间,可以把几个变量压缩到一个存储空间; (2) 处理位操作;
(1) C99规定int、unsigned int和bool可以作为位域类型,但编译器几乎都对此作了扩展,允许其它类型类型的存在。
(2) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
(3) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
(4) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;
(5) 如果位域字段之间穿插着非位域字段,则不进行压缩;
(6) 位域可以是无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。无名位域后面的变量存储在一个新的存储区。
3、示例
#include <iostream>
struct T
{
unsigned int a : 3;
unsigned int b : 4;
unsigned int c : 25;
};
int main()
{
T t;
t.a = 5;
t.b = 3;
t.c = 16;
std::cout << "a = " << t.a << std::endl;
std::cout << "b = " << t.b << std::endl;
std::cout << "c = " << t.c << std::endl;
t.a = 9;
std::cout << "a = " << t.a << std::endl;
}
输出结果:
说明:
(1)位域的值不会超过其所能表示的最大值(第二次给a赋值,a只取了后面三位,前面的被丢弃了);
(2)位域排列顺序:先声明的占存储单元的低位,根据打印的t的值可以判断;
a : 101
b : 0011
c : 0 000 0000 0000 0000 0001 0000
0x0000081d : 0000 0000 0000 0000 0000 1000 0001 1101
4、位域的符号问题
把数据类型改为 int
#include <iostream>
struct T
{
int a : 3;
int b : 4;
int c : 25;
};
int main()
{
T t;
t.a = 5;
t.b = 3;
t.c = 16;
std::cout << "a = " << t.a << std::endl;
std::cout << "b = " << t.b << std::endl;
std::cout << "c = " << t.c << std::endl;
t.a = 9;
std::cout << "a = " << t.a << std::endl;
}
输出结果:
a的最高位被当作符号位来处理了