结构体One

$$ \begin{array}{|c|c|c|c|}\hline a&c&-&-\\\hline b&b&b&b \\\hline \end{array} $$

结构体Two

$$ \begin{array}{|c|c|c|c|}\hline a&-&-&-\\\hline b&b&b&b \\\hline c&-&-&- \\\hline \end{array} $$

#include <stdio.h>
#include <windows.h>

/**
 * 
 * 64位系统,默认8字节对齐
 * 结构体One的最大成员int占4个字节
 * 故实际对齐字节为两者最小,即4字节
 * One中a放在结构体的起始位置
 * One中c占1个字节,小于实际对齐字节4,故c的起始地址相对a的起始地址的偏移量为1的整数倍个字节,即可以挨着a后占1个字节
 * One中b占4个字节,等于实际对齐字节4,故b的起始地址相对a的起始地址的偏移量为4的整数倍个字节,即从第4个字节开始,到第8个字节结束。
 * One总共占8个字节。
 * 
 * 结构体Two的最大成员int占4个字节
 * 故实际对齐字节为4个字节
 * Two中a放在结构体的起始位置
 * Two中b占4个字节,等于实际对齐字节4,故b的起始地址相对a的起始地址的偏移量为4的整数倍个字节,即从第4个字节开始,到第8个字节结束。
 * Two中c占1个字节,小于实际对齐字节4,故c的起始地址相对a的起始地址的偏移量为1的整数倍个字节,即从第9个字节开始,到第9个字节结束。
 * 由于结构体的整体大小必须为实际对齐单位的整数倍,则最后需补3个字节,总共12个字节。
 */ 

// 空间结构划分: [char1字节][char1字节][补2字节][int4字节]
struct One {
    char a; //1
    char c; //1
    int b; //4+2 char占4字节,对齐需空出2字节
};

// 空间结构划分: [char1字节][补3字节][int4字节][char1字节][补3字节]
struct Two {
    char a; //1
    int b; //4+3 int占4字节,对齐需空出3字节
    char c; //1+3 char占1字节,末尾补3字节
};

int main() {
    printf("int size: %d\\n",sizeof(int));
    printf("char size: %d\\n",sizeof(char));

    printf("struct One size: %d\\n",sizeof(struct One));
    printf("struct Two size: %d\\n",sizeof(struct Two));

    system("pause");
    return 0;
}