类和结构可包含比整型类型占用更少存储空间的成员。这些成员被指定为位域。位域成员声明符规范的语法如下:
语法
declarator : constant-expression
下面的示例声明包含位域的结构:
// bit_fields1.cpp
// compile with: /LD
struct Date {
unsigned short nWeekDay : 3; // 0..7 (3 bits)
unsigned short nMonthDay : 6; // 0..31 (6 bits)
unsigned short nMonth : 5; // 0..12 (5 bits)
unsigned short nYear : 8; // 0..100 (8 bits)
};
Date 类型的对象的概念上的内存布局如下图所示。
数据对象的内容布局
请注意,nYear 的长度为 8 位,并且会溢出声明类型 unsigned short 的字边界。因此,它始于新 unsigned short 的开头。并不必使所有位域均适合基础类型的对象;根据声明中请求的位数来分配新的存储单元,因此该结构体大小为4个字节。声明为位域的数据从低位到高位进行排序,如上图所示。
如果结构的声明包含长度为 0 的未命名字段(如以下示例所示),
// bit_fields2.cpp
// compile with: /LD
struct Date {
unsigned nWeekDay : 3; // 0..7 (3 bits)
unsigned nMonthDay : 6; // 0..31 (6 bits)
unsigned : 0; // Force alignment to next boundary.
unsigned nMonth : 5; // 0..12 (5 bits)
unsigned nYear : 8; // 0..100 (8 bits)
};
则内存布局如下图中所示。
带有零长度位域的数据对象的布局
位域的基础类型必须是整型类型,如基本类型中所述。
总结如下
使用位域的主要目的是压缩存储,其大致规则为:
- 1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
- 2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
- 3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;
- 4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
- 5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
案例如下:
本文详细介绍了位域在C/C++中的应用,包括如何通过位域压缩存储空间,以及位域在不同类型中的布局规则。提供了具体的代码案例,展示了位域如何帮助优化内存使用。
2808

被折叠的 条评论
为什么被折叠?



