结构体大小计算之位域字段
2016-10-05 18:54
218 查看
类和结构可包含比整型类型占用更少存储空间的成员。这些成员被指定为位域。位域成员声明符规范的语法如下:
语法
下面的示例声明包含位域的结构:
Date 类型的对象的概念上的内存布局如下图所示。
数据对象的内容布局
请注意,nYear 的长度为 8 位,并且会溢出声明类型 unsigned short 的字边界。因此,它始于新 unsigned
short 的开头。并不必使所有位域均适合基础类型的对象;根据声明中请求的位数来分配新的存储单元,因此该结构体大小为4个字节。声明为位域的数据从低位到高位进行排序,如上图所示。
如果结构的声明包含长度为 0 的未命名字段(如以下示例所示),
则内存布局如下图中所示。
带有零长度位域的数据对象的布局
位域的基础类型必须是整型类型,如基本类型中所述。
总结如下
使用位域的主要目的是压缩存储,其大致规则为:
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;
4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
案例如下:
[cpp] view
plain copy
typedef struct AA{
unsigned char b1:5;
unsigned char b2:5;
unsigned char b3:5;
unsigned char b4:5;
unsigned char b5:5;
}AA;/*sizeof(AA) = 5*/
typedef struct BB {
unsigned int b1:5;
unsigned int b2:5;
unsigned int b3:5;
unsigned int b4:5;
unsigned int b5:5;
}BB;/*sizeof(BB) = 4*/
typedef struct CC {
int b1:1;
int :2;//无影响
int b3:3;
int b4:2;
int b5:3;
short b6:4;
int b7:1;
}CC; /*sizeof(CC) = 12*/
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) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
案例如下:
[cpp] view
plain copy
typedef struct AA{
unsigned char b1:5;
unsigned char b2:5;
unsigned char b3:5;
unsigned char b4:5;
unsigned char b5:5;
}AA;/*sizeof(AA) = 5*/
typedef struct BB {
unsigned int b1:5;
unsigned int b2:5;
unsigned int b3:5;
unsigned int b4:5;
unsigned int b5:5;
}BB;/*sizeof(BB) = 4*/
typedef struct CC {
int b1:1;
int :2;//无影响
int b3:3;
int b4:2;
int b5:3;
short b6:4;
int b7:1;
}CC; /*sizeof(CC) = 12*/
相关文章推荐
- 结构体大小计算之位域字段
- 结构体大小计算之位域字段
- C中含位域结构体大小的计算
- 结构体的大小的计算与空间的优化--之位域字段
- 结构体的大小的计算与空间的优化--之位域字段
- 数据结构大小的计算-sizeof
- sizeof 计算结构体大小
- Oracle查询数据表结构(字段,类型,大小,备注)
- Oracle查询数据表结构(字段,类型,大小,备注)
- 结构体的内存对齐方式(结构体大小计算 sizeof)(
- Oracle查询数据表结构/字段/类型/大小
- C中结构体大小的计算
- 结构体大小的计算
- 如何计算结构体大小和结构体中成员的内存偏移
- 如何计算结构体大小
- 计算结构体大小
- C语言中结构体大小计算即存储分配
- Oracle查询数据表结构(字段,类型,大小,备注)
- 一个有关计算结构体数组大小的问题
- 画图计算-- 结构体大小的计算