您的位置:首页 > 其它

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

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


语法

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*/  

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: