• 关于结构体的对齐


      这一类型的题目经常在笔试、面试中问到,而很多人虽然答对了,但却了解的不够彻底,所以在此总结下。有错请帮忙指出。

      对齐的原因不多讲了,相信大家都知道。这里只谈它的机制。

      在c里,每种数据类型都有自己的对齐方式,包括基本数据类型以及其他的复杂数据类型。对于标准数据类型,它的地址只要是它的长度的整数倍就行了,而非基本数据类型按下面的原则对齐:
        数组:按照基本数据类型对齐,第一个对齐了后面的自然也就对齐了。 
        联合:按其包含的长度最大的数据类型对齐。 
        结构体:结构体中每个数据类型都要对齐,结构体本身也要对齐。

      这里主要讨论结构体的对齐方式。(vs 2012下,编译器默认对齐是8字节)

      考虑这样一个结构体:

      

    struct A
    {
      float f;
      char c;
      short s;
      int i;
    }

      它的大小是多少呢?答案是12。要搞清楚这一点,需要了解几个概念:

        1. 数据类型的自身对齐大小。比如float,它是4字节的,它自身的对齐大小也是4字节。

        2. 编译器指定的对齐大小。 可以通过#pragma pack (N)来指定,vs下默认是8。

        3. 有效对齐大小。前两者的最小值。有效对齐大小是最终采用的对齐大小,如果其值为N,则该数据的首地址能被N整除。

        4. 结构体本身的有效对齐大小是其数据成员有效对齐大小的最大值。

      在上题中,float自身对齐大小是4字节,而默认对齐大小是8,所以有效对齐大小是4。float是结构体中最大的数据类型,所以结构体自身的有效对齐大小是4,结构体的首地址能被4整除,比如说0x0004.float的首地址与之相同,所以是自然对齐的。数据c自身对齐大小是1,小于指定大小,所以其有效对齐大小是1,由于结构体是顺序连续摆放的,所以其地址是0x0008。s的有效对齐大小是2,其地址要能被2整除,所以他应该放在0x0010,而数据i有效对齐大小是4,应该在0x000C。所以总共是12。

      如果其中有数组怎么办呢?

    struct A
    {
      float f;
      char c;
      int i;
      char a[10];
    };

      上面说过了,数组按照第一个元素对齐。所以这个结构体的大小是4+1+3+4+10=22,还要加上2,结构体的大小要能被其有效对齐大小整除,这里也就是f或者i的有效对齐大小4,所以最终结果是24。

      

    #pragma pack (16)
    
    struct A
    {
        float f;
        char c;
        int i;
        double a[10];
    }; 

      这个结构体的大小呢?答案是96。你明白了吗?

  • 相关阅读:
    Python笔记:日期时间获取与转换
    算法笔记:递归、动态规划
    容器技术介绍:Docker Dockerfile语法与指令
    Netdiscover网络扫描工具
    持续集成:jenkins + pytest + selenium + Git + Allure自动化测试
    MySQL数据库基础入门
    Parameters 至少一个参数没有指定
    C/C++ 延时函数 (标准库)
    TabController控件测试
    contentEditable
  • 原文地址:https://www.cnblogs.com/tobealion/p/3633295.html
Copyright © 2020-2023  润新知