详解下c语言中struct和union的对齐规则

接触过c语言的同学应该都知道字节对齐。有些时候我们很容易弄错字节对齐的方式,特别是涉及到struct(结构体)和union(联合体)时。今天我们通过详细例子来说明下struct和union的对齐规则,以便了解各种struct和union所占字节具体计算方式。

一、基础环境信息

我本地计算机系统各类基础类型所占字节如下:

cpp 复制代码
int main() {
    printf("the sizeof char      is %d\n",sizeof(char));
    printf("the sizeof int       is %d\n",sizeof(int));
    printf("the sizeof unsigned  is %d\n",sizeof(unsigned));
    printf("the sizeof short     is %d\n",sizeof(short));
    printf("the sizeof long      is %d\n",sizeof(long));
    printf("the sizeof float     is %d\n",sizeof(float));
    printf("the sizeof double    is %d\n",sizeof(double));
    printf("the sizeof longlong  is %d\n",sizeof(long long));

}

二、结构体字节对齐

2.1,结构体对齐规则

结构体中寻找所有成员中占字节数最大成员,其余成员根据占字节数最大成员拼凑或者插入空位构成n个(n>=1)最大成员字节。

2.2,实例

上图例子实测:

cpp 复制代码
int main() {
    struct stu{
        char a;
        int b;
        short c;
        char d;
    };

    struct  stu s;

    printf("the sizeof s is %d\n", sizeof s);
    printf("the address a is %x\n", &s.a);
    printf("the address b is %x\n", &s.b);
    printf("the address c is %x\n", &s.c);
    printf("the address d is %x\n", &s.d);
}

对于如下结构体:最大类型为b,占4字节,c,d,a拼凑占4字节,总共8字节

复制代码
struct stu{
    int b;
    short c;
    char d;
    char a;
};
cpp 复制代码
int main() {
    struct stu{
        int b;
        short c;
        char d;
        char a;
    };

    struct  stu s;

    printf("the sizeof s is %d\n", sizeof s);
    printf("the address b is %x\n", &s.b);
    printf("the address c is %x\n", &s.c);
    printf("the address d is %x\n", &s.d);
    printf("the address a is %x\n", &s.a);
}

对于如下结构体: f为最大类型,占8字节,成员e需要以8字节对齐,所以stu1占16字节;成员b,c,d拼凑占8字节;成员a分配8字节进行对齐;总共占32字节

复制代码
struct stu{
    int b;
    short c;
    char d;
    struct stu1{
        char e;
        double f;
    } stu1;
    char a;
};
cpp 复制代码
int main() {
    struct stu{
        int b;
        short c;
        char d;
        struct stu1{
            char e;
            double f;
        } stu1;
        char a;
    };

    struct  stu s;

    printf("the sizeof s     is %d\n", sizeof s);
    printf("the address b    is %x\n", &s.b);
    printf("the address c    is %x\n", &s.c);
    printf("the address d    is %x\n", &s.d);
    printf("the address stu1 is %x\n", &s.stu1);
    printf("the address e    is %x\n", &s.stu1.e);
    printf("the address f    is %x\n", &s.stu1.f);
    printf("the address a    is %x\n", &s.a);
}

三、联合体字节对齐

3.1,联合体对齐规则

联合体字节对齐计算非常简单,为所有成员中所占字节最大成员的字节数。

3.2,实例

上图例子实测:

cpp 复制代码
int main() {
    union stu{
        char a;
        int b;
        short c;
        char d;
    };

    union  stu s;

    printf("the sizeof s     is %d\n", sizeof s);
    printf("the address b    is %x\n", &s.b);
    printf("the address c    is %x\n", &s.c);
    printf("the address d    is %x\n", &s.d);
    printf("the address a    is %x\n", &s.a);
    s.b = 0b00000011000000110000001100000011;
    printf("the value of b    is %d\n", s.b);
    printf("the value of c    is %d\n", s.c);
    printf("the value of d    is %d\n", s.d);
    printf("the value of a    is %d\n", s.a);
}

对于如下联合体:stu中成员stu1按照struct对齐规则占8字节,所以联合体stu占8字节。

复制代码
union stu{
    char a;
    int b;
    short c;
    struct stu1{
        char e;
        int f;
    }stu1;
    char d;
};
cpp 复制代码
int main() {
    union stu{
        char a;
        int b;
        short c;
        struct stu1{
            char e;
            int f;
        }stu1;
        char d;
    };

    union  stu s;

    printf("the sizeof s     is %d\n", sizeof s);
    printf("the address a    is %x\n", &s.a);
    printf("the address b    is %x\n", &s.b);
    printf("the address c    is %x\n", &s.c);
    printf("the address e    is %x\n", &s.stu1.e);
    printf("the address f    is %x\n", &s.stu1.f);
    printf("the address d    is %x\n", &s.d);


}
相关推荐
小小de风呀11 小时前
de风——【从零开始学C++】(五):内存管理
开发语言·c++
ooseabiscuit11 小时前
Laravel6.x核心优化与特性全解析
android·开发语言·javascript
折哥的程序人生 · 物流技术专研11 小时前
Java面试85题图解版(一):基础核心篇
java·开发语言·后端·面试
Hello.Reader11 小时前
算法基础(十)——分治思想把大问题拆成小问题
java·开发语言·算法
一只大袋鼠12 小时前
JavaWeb四种文件上传方式(下篇)
java·开发语言·springmvc·javaweb
TE-茶叶蛋12 小时前
深入研究 yudao-framework 模块:Java 编程能力提升指南
java·开发语言
CHANG_THE_WORLD12 小时前
C语言中的 %*s 和 %.*s 和C++的字符串格式化输出
c语言·c++·c#
逻辑驱动的ken12 小时前
Java高频考点场景题24
java·开发语言·面试·职场和发展·求职招聘
兔小盈12 小时前
多线程-(五)线程安全之内存可见性
java·开发语言·多线程
消失的旧时光-194312 小时前
C语言对象模型系列(四)《Linux 内核里的 container_of 到底是什么黑魔法?》—— 一篇讲透 Linux 内核的“对象模型”核心技巧
linux·c语言·算法