• 结构体的大小的计算与空间的优化--之基本类型


    /*********************************************************************
     * Author  : Samson
     * Date    : 09/20/2013
     * Test platform:
     *               #1 SMP Debian 3.7.2-0+kali8
     *               gcc (Debian 4.7.2-5) 4.7.2

     * *******************************************************************/

    先看看从网上的查找到的关于:编译器是按照什么样的原则进行对齐的?

        先让我们看四个重要的基本概念:

    1.数据类型自身的对齐值:

      对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4单位字节。

    2.结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。

    3.指定对齐值:#pragma pack (value)时的指定对齐值value。

        4.数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。


    typedef struct Double
    {
      char c;
      double b;
      int f;
      short a;
      char e;
    }DOUBLEAREA;

    以上结构体,有人认为长度是24,理由是在double b前必须按照double的长度进行补齐前面的char c,所以在double b前的长度就应该是8个字节了。因为为8+8+4+4=24;而按照以上的四条原则中的第一条:int,float,double类型,其自身对齐值为4单位字节,那么应该为:4+8+4+4=20;

    根据第一条规则,个人理解的意思是对于每一种类型的结构体中的变量,前面的结构体字段的长度总和必须是当前类型的自身对齐的整数倍,就上面的这个结构体的定义:对于此结构体应用此规则的应用如下:

    typedef struct Double
    {
      char c;
      double b;  //前面的c的空间必须是double的对齐字节单位对齐,所以前面的要补齐到4个字节
      int f;
      short a;//而此short类型的前面所占空间(补课后的空间)只要是short的对齐单位2字节对齐即可;前面的字段的补齐后的已经是4的倍数了
      char e; //此char类型的前面的所占空间(补齐后的空间)只要是char的对齐单位1字节的整数倍即可
    }DOUBLEAREA;


    那么就以上的结构体,还有没有能够进行优化的空间呢?

    根据以上的分析,已经看到把占用对齐字节越大的放在结构体前的话,会在空间上更加优化,因为越大的空间的值在结构体的后面的话,对齐的单位更大,浪费的空间也就更大了,那么我们把上面的结构体修改一下,就能够节省4个字节了,如下:

    typedef struct Double
    {
      double b;
      int f;
      short a;
      char c;
      char e;
    }DOUBLEAREA;

    修改后的空间占用为:8+4+2+1+1=16

    为了节省空间修改结构体的原则为:

    1)按对齐单位的大小从大到小的顺序进行定义;

    2)把对齐单位相同的写在一块;


    测试代码及结果

    #include <stdio.h>
    #include <stdlib.h>

    typedef struct Double
    {
      char c;
      double b;
      int f;
      short a;
      char e;
    }DOUBLEAREA;

    typedef struct DoubleNew
    {
      double b;
      int f;
      short a;
      char c;
      char e;
    }DOUBLEAREANEW;


    int main()
    {
      int lenDouble, lenDoubleNew;
      DOUBLEAREA DoubleArea;
      DOUBLEAREANEW DoubleAreaN;
      lenDouble = sizeof(DoubleArea);
      lenDoubleNew = sizeof(DoubleAreaN);
      printf("DoubleArea len is %d DoubleAreaN len is %d ", lenDouble, lenDoubleNew);
      return 0;
    }

    root@quieter:/usr/local/samsonfile/yygytest# ./a.out
    DoubleArea len is 20 DoubleAreaN len is 16


    后续对存在 位域字段的结构体的长度的计算及优化空间的日志,地址如下

    http://blog.csdn.net/yygydjkthh/article/details/11854089

  • 相关阅读:
    软工实践总结
    Beta总结
    beta冲刺6/7
    beta冲刺5/7
    Beta冲刺4/7
    beta冲刺3/7
    beta冲刺2/7
    beta冲刺1/7
    答辩总结
    ES6中的块级作用域与函数声明
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3331342.html
Copyright © 2020-2023  润新知