结构体大小计算之位域字段

来源:互联网 发布:淘宝怎么加好友 编辑:程序博客网 时间:2024/05/19 18:47

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

语法

declarator  : constant-expression

下面的示例声明包含位域的结构:

// bit_fields1.cpp// compile with: /LDstruct 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: /LDstruct 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*/  
0 0
原创粉丝点击