• C++中的字节对齐


    本博客(http://blog.csdn.net/livelylittlefish)贴出作者(三二一、小鱼)相关研究、学习内容所做的笔记,欢迎广大朋友指正!

    字节对齐

    1. 基本概念
    字节对齐:计算机存储系统中以Byte为单位存储数据,不同数据类型所占的空间不同,如:整型(int)数据占4个字节,字符型(char)数据占一个字节,短整型(short)数据占两个字节,等等。计算机为了高速的读写数据,默认情况下将数据存放在某个地址的起始位置,如:整型数据(int)默认存储在地址能被4整除的起始位置,字符型数据(char)能够存放在不论什么地址位置(被1整除),短整型(short)数据存储在地址能被2整除的起始位置。这就是默认字节对齐方式。

    2. 举例说明
    非常显然默认对齐方式会浪费非常多空间,比如例如以下结构:
    struct student
    {
        char name[5];
        int num;
        short score;
    }
    本来仅仅用了11bytes(5+4+2)的空间,可是因为int型默认4字节对齐,存放在地址能被4整除的起始位置,即:假设name[5]从0開始存放,它占5bytes,而num则从第8(偏移量)个字节開始存放。所以sizeof(student)=16。于是中间空出几个字节闲置着。但这样便于计算机高速读写数据,是一种以空间换取时间的方式。其数据对齐例如以下图:

    |char|char|char|char|
    |char|----|----|----|
    |--------int--------|
    |--short--|----|----|

     

    假设我们将结构体中变量的顺序改变为:
    struct student
    {
        int num;
        char name[5];
        short score;
    }
    则,num从0開始存放,而name从第4(偏移量)个字节開始存放,连续5个字节,score从第10(偏移量)開始存放,故sizeof(student)=12。其数据对齐例如以下图: 

    |--------int--------|
    |char|char|char|char|
    |char|----|--short--| 

    假设我们将结构体中变量的顺序再次改为为:
    struct student
    {
        int num;
        short score;
        char name[5];
    }
    则,sizeof(student)=12。其数据对齐例如以下图: 

    |--------int--------|
    |--short--|char|char|
    |char|char|char|----| 

    验证代码例如以下:

    执行结果例如以下:

    3. #pragma pack()命令
    为了节省空间,我们能够在编码时通过#pragma pack()命令指定程序的对齐方式,括号里是对齐的字节数,若该命令括号里的内容为空,则为默认对齐方式。比如,对于上面第一个结构体,假设通过该命令手动设置对齐字节数例如以下:

    #pragma pack(2) //设置2字节对齐
    struct strdent
    {
        char name[5]; //本身1字节对齐,比2字节对齐小,按1字节对齐
        int num;          //本身4字节对齐,比2字节对齐大,按2字节对齐
        short score;    //本身也2字节对齐,仍然按2字节对齐
    }
    #pragma pack() //取消设置的字节对齐方式

    则,num从第6(偏移量)个字节開始存放,score从第10(偏移量)个字节開始存放,故sizeof(student)=12,其数据对齐例如以下图:
    |char|char|
    |char|char|
    |char|-----|
    |----int----|
    |----int----|
    |--short---|

    这样改变默认的字节对齐方式能够更充分地利用存储空间,可是这会减少计算机读写数据的速度,是一种以时间换取空间的方式。

    验证代码例如以下:

    执行结果例如以下:

    若该为#pragma pack(1),则执行结果例如以下:

    4. 样例

    程序例如以下:

    该样例採取默认对齐方式,执行结果例如以下:

    说明:静态变量存放在全局数据区内,而sizeof计算栈中分配的空间的大小,故不计算在内。

    若加上#pragma pack(2)命令,则执行结果例如以下:

  • 相关阅读:
    IDT 信息设计工具使用
    子查询
    分组函数
    多表查询
    单行函数
    基本的sql-select语句
    final关键字的使用
    非静态代码块(非static初始化块)&静态代码块(static初始化块)
    单例模式的饿汉式实现
    static关键字的应用
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4079794.html
Copyright © 2020-2023  润新知