字节对齐 练习

Posted pureyes-cyl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字节对齐 练习相关的知识,希望对你有一定的参考价值。

http://m.nowcoder.com/questions?uuid=a1f3b90249ff4666879e8f695915ed7f

在32位cpu上选择缺省对齐的情况下,有如下结构体定义:

#include "iostream"
using namespace std;

struct Zijie
{
    unsigned a : 19;
    unsigned b : 11;
    unsigned c : 4;
    unsigned d : 29;
    char index;
};
int main()
{
        int t = sizeof(struct Zijie);
        cout << t << endl;

    system("pause");
    return 0;
}

在64位windows上运行是16

分析:
由于在32位cpu上选择缺省对齐的情况下,所以每行支持4个字节即32bit
于是a和b公用一行19+11 = 30bit还剩2bit,又因为c为4bit,无法全部占据该行,故其重新开始一行,第一行空出2bit;
对于第二行,c占据前4bit,同理由于d占据29bit, 无法全部占据该行的剩余空间,所以其处于第三行,第二行中剩余28bit空出;
同理可分析第三行和第四行的空间,由于第四行占据1个直接,为了保持对其需要把剩余空间补齐
综上该结构体的大小为4*4个字节 = 16 
 
对于这道题,首先需要知道位域的概念。
位域是指信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几 个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。
位域的定义和位域变量的说明
位域定义
与结构定义相仿,其形式为:
struct 位域结构名
{ 位域列表 };
其中位域列表的形式为: 类型说明符 位域名:位域长度
 
位域表示法
C99规定int、unsigned int和bool可以作为位域类型,但编译器几乎都对此作了扩展, 
允许其它类型类型的存在。 
使用位域的主要目的是压缩存储,其大致规则为: 
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字 
段将紧邻前一个字段存储,直到不能容纳为止; 
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字 
段将从新的存储单元开始,其偏移量为其类型大小的整数倍;(经测试此条好像仅限于char型,整型可以跨域存储) 
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方 
式,Dev-C++采取压缩方式; 
4) 如果位域字段之间穿插着非位域字段,则不进行压缩; 
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
 

以上是关于字节对齐 练习的主要内容,如果未能解决你的问题,请参考以下文章

“现在打包强制记录的字节对齐”是啥意思?

Visual Studio2008 C++结构体成员需要内存对齐吗?

关于字节对齐的理解

结构体字节对齐问题探究

结构体字节对齐问题探究

什么是 Core Animation 的字节对齐(缓存行对齐)?为什么重要?