结构体联合体sizeof内存求值 - 对齐数

讲解下struct和union的内存求值和对齐
以题目讲解

结构体联合体sizeof内存求值 - 对齐数

  • 不同位数下类型字节大小
  • 内存对齐规则
  • struct 内存对齐求值
  • 嵌套struct内存对齐求值
  • union的内存大小求值
    • union大小计算准则
  • struct嵌套union内存对齐求值

不同位数下类型字节大小

一定要搞清楚编辑器,一般编辑器中的类型字节如图:

类型 16位平台 32位平台 64位平台
char 1个字节 1个字节 1个字节
short 2个字节 2个字节 2个字节
int 2个字节 4个字节 4个字节
unsigned int 2个字节 4个字节 4个字节
float 4个字节 4个字节 4个字节
double 8个字节 8个字节 8个字节
long 4个字节 4个字节 8个字节
long long 8个字节 8个字节 8个字节
unsigned long 4个字节 4个字节 8个字节
指针 2个字节 4个字节 8个字节

一般我使用的是64位的编译器,下面来看看对齐规则

 

内存对齐规则

规则

  • 结构体的第一个成员直接对齐到相对于结构体变量起始位置为0处偏移。
  • 从第二个成员开始,要对齐到某个【对齐数】的整数倍的偏移处。
  • 结构体的总大小,必须是最大对齐数的整数倍。每个结构体成员都有一个对齐数,其中最大的对齐数就是最大对齐数
  • 如果嵌套了结构体的情况。嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

 

struct 内存对齐求值

  • 举例:struct内存求值
#include 
#pragma pack(16)
struct BBB {
    long num;
    char ha;
    short ba[5];
}b;

int main() {
    printf("%d\n", sizeof(b.num));//8
    printf("%d\n", sizeof(b.ha)); //1
    printf("%d\n", sizeof(b.ba)); //10 ,short大小是2
    //最大对齐数是8

    printf("%d\n", sizeof(BBB));
    return 0;
}

//这里ba数组的最大对齐数是2,因为short大小2小于定义的对齐数16

//sizeof(BBB)=8+1+1+(2*5)=20,这里的1是为了让ba数组对齐到2的倍数
//但是对齐规则里面有个结构体的总大小,必须是最大对齐数的整数倍
//这里最大对齐数是8,也就是结果需要是8的倍数,最终等于sizeof(BBB)=24

在这里插入图片描述

 

嵌套struct内存对齐求值

  • 如果有嵌套结构体呢 :
#include 
#pragma pack(16)
struct BBB {
    long num;
    char ha;
    short ba[5];
    struct BBB2
    {
        int s; //4
        int ba2[5]; //20 
        char ha2[2]; //2
    }b2;  //4+20+2=26。对齐=4的倍数=28 
}b;

int main() {
    printf("%d\n", sizeof(b.num));//8
    printf("%d\n", sizeof(b.ha)); //1
    printf("%d\n", sizeof(b.ba)); //10 ,short大小是2
    printf("%d\n",sizeof(b.b2));//28,见上面
    //最大对齐数是8

    printf("%d\n", sizeof(BBB));
    return 0;
}
//sizeof(BBB)=8+1+1+(2*5)=20,后面嵌套的BBB2最大对齐数是4,对齐大小是28,所以从4的倍数出发,这里是20开始,正好,sizeof(BBB)=20+28=48,正好是8的倍数

 

union的内存大小求值

解释下union的内存大小求值

union大小计算准则

1、至少要容纳最大的成员变量
2、必须是所有成员变量类型大小的整数倍 —— 记住是成员变量类型 char c[7]算 1

  • 举例:求sizeof(union)
#include
 
//联合体
union u2  
{
    char a;  //1
    int b; //4
    short c; //2
    double d; //8
    int e[5]; //20
}U3;
 
//主函数
int main(){ 
    printf("%d\n",sizeof(U3));//输出24
    return 0;
}

 

struct嵌套union内存对齐求值

#include 
#pragma pack(16)
struct BBB {
    int num;//4
    char ch; //1
    char pa[3]; //3
    union {
        int a; //4
        float b; //4
    } myUnion;//这个union内存大小等于4
}b;

int main() {
    printf("%d\n", sizeof(b));
    //4+1+3+4=12 ; 到char pa[3]时候这时候正好到地址8,然后union的内存是4,对齐数,要求是它的整数倍所以正好从8开始,最终结果12。满足是对齐数4,1,4的倍数
    return 0;
}

 

其他内容见专栏的结构体和联合体的文章
如果有啥补充的后续更新

你可能感兴趣的:(C语言程序设计,c语言,算法)