结构体大小计算

本文详细介绍了位域在C/C++中的应用,包括如何通过位域压缩存储空间,以及位域在不同类型中的布局规则。提供了具体的代码案例,展示了位域如何帮助优化内存使用。

类和结构可包含比整型类型占用更少存储空间的成员。这些成员被指定为位域。位域成员声明符规范的语法如下:

语法

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 类型的对象的概念上的内存布局如下图所示。

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)
};

则内存布局如下图中所示。

带有零长度位域的 Date 对象的布局

带有零长度位域的数据对象的布局

位域的基础类型必须是整型类型,如基本类型中所述。

总结如下

使用位域的主要目的是压缩存储,其大致规则为:

  • 1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
  • 2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
  • 3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;
  • 4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
  • 5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
案例如下:
[cpp]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. typedef struct  AA{  
  2.        unsigned char b1:5;  
  3.        unsigned char b2:5;  
  4.        unsigned char b3:5;  
  5.        unsigned char b4:5;  
  6.        unsigned char b5:5;  
  7. }AA;/*sizeof(AA) = 5*/  
  8.   
  9. typedef struct  BB {  
  10.        unsigned int b1:5;  
  11.        unsigned int b2:5;  
  12.        unsigned int b3:5;  
  13.        unsigned int b4:5;  
  14.        unsigned int b5:5;  
  15. }BB;/*sizeof(BB) = 4*/  
  16.   
  17. typedef struct  CC {  
  18.         int b1:1;  
  19.         int :2;//无影响  
  20.         int b3:3;  
  21.         int b4:2;  
  22.         int b5:3;  
  23.         short b6:4;  
  24.         int b7:1;  
  25.         
  26. }CC; /*sizeof(CC) = 12*/  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值