• 关于结构体的对齐


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

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

      在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。你明白了吗?

  • 相关阅读:
    shell 脚本——第五节课 交互输入read与for语句
    shell 脚本——第四节课 Linux grep命令与正则表达
    shell 脚本——第三节课 编程原理
    shell脚本练习:一个添加用户test1到test10的脚本程序
    ARM设备树
    Ubuntu18.04 设置wifi热点
    二、卷积神经网络概念
    一、神经网络构建八股搭建
    边缘计算
    2.7 usb摄像头之usb摄像头描述符打印
  • 原文地址:https://www.cnblogs.com/tobealion/p/3633295.html
Copyright © 2020-2023  润新知