结构体和联合体大小的计算


结构体的大小计算

1、没有定义 #pragma pack(value)

计算规则:整体的大小在满足为最大数据类型所占字节的倍数下达到所占内存最小

? 根据上述规则,由于没有指定对齐字节,则在结构体中 成员a 占5字节,成员b 占4字节,成员c 占8字节,这样的话就是5+4+8=17 字节.但是这里整体大小17字节 不是 8 的最小倍数,因此,成员a 需要补 3个空字节 进行对齐,成员b 需要补 4个空字节 进行对齐,即该结构体的大小为:5+3(空字节) +4+4(空字节)+8=24 字节,总大小是8的最小倍数且占用内存最小。

#include "stdio.h"
 
typedef struct
{
    char a[5];
    int b;
    double c;
}Test;
 
int main(void)
{
    printf("sizeof(Test) = %d\n",sizeof(Test));
 
    system("pause");
}

/*
24
*/
2、当定义了 #pragma pack(value)

就算规则:整体的大小必须为value的最小整数倍

? 根据上述例子,这里以 4字节 对齐计算,则成员a 占5字节,成员b 占4字节,成员c 占8字节,整体大小为:5+4+8=17 字节,但是不满足是 4字节 的最小倍数这一规则,因此成员a 后应补 3个空字节进行对齐,因此,该结构体大小为:5+3+4+8=20字节。

#include "stdio.h"
 
#pragma pack(4)
typedef struct
{
    char a[5];
    int b;
    double c;
}Test;
 
int main(void)
{
    printf("sizeof(Test) = %d\n",sizeof(Test));
 
    system("pause");
}

/*
20
*/

联合体的大小计算

1、没有定义 #pragma pack(value)

计算规则:联合体中最大成员所占内存的大小且必须为最大类型所占字节的最小倍数。

? 该联合体,成员a 占7字节,成员b 占 4*2=8 字节,成员c 占8字节,最大字节数8同时也满足是 8(double型所对应的字节数)因此,根据计算规则,该联合体的大小为 8字节。

#include "stdio.h"
 
union
{
    char a[7];
    int b[2];
    double c;
}Test;
 
int main(void)
{
    printf("sizeof(Test) = %d\n",sizeof(Test));
 
    system("pause");
}

/*8*/
2、当定义了 #pragma pack(value)

计算规则:联合体中最大成员所占字节且必须为value的最小倍数。

? 定义以2字节对齐进行计算,则最大成员b 占12字节,同时也是2的最小倍数,满足上述规则,因此该联合体的大小为 12字节。

#include "stdio.h"
 
#pragma pack(2)
union
{
    char a[7];
    int b[3];
    double c;
}Test;
 
int main(void)
{
    printf("sizeof(Test) = %d\n",sizeof(Test));
 
    system("pause");
}

/*12*/

3、结构体嵌套联合体的大小计算

1、没有定义 #pragma pack(value)

计算规则:联合体按照最大成员所占字节且为最大数据类型所对应的字节的最小整数倍的原则进行计算,它所占的字节数与结构体中其他成员所占字节的总和应为结构体中最大数据类型所对应的字节的最小倍数。

? 联合体中,最大占10字节,但又要为8的最小倍数,因此联合体占16字节,然后 16+5+4+8=33 字节,不是结构体中最大数据类型 double 所对应的字节数 8的最小倍数,根据规则故结构体的大小为:16(联合体所占字节)+5+3(空字节)+4+4(空字节)+8=40 字节。

#include "stdio.h"
 
typedef struct
{
    union 
    {
        char a[10];
        int b[2];
        double c;
    }test;
    char d[5];
    int e;
    double f;
}Test;
 
int main(void)
{
    printf("sizeof(Test) = %d\n",sizeof(Test));
 
    system("pause");
}

/*40*/
2、当定义了 #pragma pack(value)

计算规则:联合体中最大成员所占字节且为value的最小整数倍,它所占的字节数与结构体其他成员所占字节数的总和为value的最小整数倍。

? 在上述嵌套中,联合体最大占10字节,且为2的最小倍数,因此联合体占10字节,然后10+5+4+8=27字节,但不是 2的最小倍数,因此如需满足上述规则,该结构体的大小应为:10(联合体所占字节) +5+1(空字节)+4+8=28 字节。

#include "stdio.h"
 
#pragma pack(2)
typedef struct
{
    union 
    {
        char a[10];
        int b[2];
        double c;
    }test;
    char d[5];
    int e;
    double f;
}Test;
 
int main(void)
{
    printf("sizeof(Test) = %d\n",sizeof(Test));
 
    system("pause");
}

/*28*/