C语言:结构体的大小 在C语言中结构体struct是一种用户自定义的复合数据类型它允许将不同类型的数据组合成一个整体便于管理和操作。然而结构体的内存分配并非简单的成员大小相加而是涉及**内存对齐Memory Alignment**这一关键机制。本文将系统讲解结构体的定义、内存布局、大小计算方法并深入分析内存对齐的原理与优化技巧。一、结构体的基本概念在探讨结构体的大小之前先来简单回顾一下结构体的基本概念结构体是C语言中用于组织相关数据的集合其成员可以是任意类型包括其他结构体。例如struct Student { char name[20]; // 字符串 int age; // 整型 float score; // 浮点型 };在这个例子中我们定义了一个名为Student的结构体它包含了三个成员一个字符数组name用于存储学生的姓名一个整型变量age用于存储学生的年龄以及一个浮点型变量score用于存储学生的成绩。定义好结构体后我们可以声明结构体变量并对其进行初始化。例如struct Student stu1 {Tom, 20, 85.5};结构体的访问有两种方法成员访问和指针访问1.成员访问通过.运算符如student.age2.指针访问若为结构体指针使用-运算符如p_student-age二、结构体的大小结构体的大小并不是简单地将其各个成员的大小相加这是因为存在内存对齐的机制。内存对齐是为了提高内存访问的效率用空间去换访问时间的效率编译器会在结构体成员之间插入一些填充字节。1.结构体内存对齐的规则--基本原理① 第一个成员在与结构体变量偏移量为0的地址处。② 其他成员变量要对齐到某个数字对齐数的整数倍的地址处。对齐数 编译器默认的一个对齐数 与该成员大小的较小值。VS中默认的值为8后面的结构体大小的示例均是在VS中演示的③结构体总大小为最大对齐数每个成员变量都有一个对齐数的整数倍。④ 如果嵌套了结构体的情况嵌套的结构体对齐到自己的最大对齐数的整数倍处结构体的整体大小就是所有最大对齐数含嵌套结构体的对齐数的整数倍。2.结构体大小计算演示struct stu1 { //占用的字节号 char a; //1(对齐数) 0 (1)浪费 short b;//2 2 3 b的对齐数 short: 2 8 为2 int c; //4 4 5 6 7 该结构体的最大对齐数为 4 };//0~7共8个字节 8 % 40 满足 这个结构体大小为8个字节简单解释一下这里面a为一个字节占用0号字节但是b的对齐数为2b之前所占用的字节数为1,1%20所以要对a后面再补充一个字节逻辑上使a占用0 1号字节这样b之前共占用2个字节2%20满足条件b接着占2 3号字节c的对齐数为4c之前所占用字节数为4,4%40c接着占用4 567号字节8421 所以该结构体的最大对齐数为4大小就为8了.struct stu2 {//各个成员的对齐数 所占字节编号 char a; //1 0 (1 2 3) int b; //4 4 5 6 7 short c; //2 8 9 (10 11) 该结构体的最大对齐数为4 };//0~9共10个字节 10%4!0 因为 12%40 需再补两个字节 所以该结构体大小为12字节struct stu3 { char a; //1 0 (1 2 3) float b; //4 4 5 6 7 double c; //8 8-15 int d; //4 16 17 18 19(20 21 22 23) long long e;//8 24-31 //0-31 32Byte 32%80 };接下来一点一点提升难度将详细展示结构体的大小计算含有数组的结构体​ //Type Name[Size] //对于含有数组成员的结构体只需将其看作有Size个Type成员即可 将成员大小乘以Size即可 struct stu4 { char arr[9];//1 0-8 (9 10 11) int b; //4 12 13 14 15 short c; //2 16 17 (18 19 20 21 22 23) double d[2];//8 24 - 39 };//0-39 40 struct stu5 { char arr[11]; //1 0-10 (11 - 15) struct stu4 a;//8 16 - 55 long b; //4 56 57 58 59 float c; //4 60 61 62 63 short d[7]; //2 64 - 77 };//78 % 8!0 80 ​计算嵌套结构体的大小结构体stu5和stu2均是上面计算过的结构体后面引用均是struct stu6 { char c; //1 0 (1 2 3) int d[100]; //4 4-403 (404 - 407) struct stu5 arr[7]; //8 408 - 967 //stu5的最大对齐数为8单个结构体的大小为80 结构体数组arr所占的总大小为560字节 //968%40 struct stu2 brr[21];//4 968 - 1219 //stu2的最大对齐数为4单个结构体的大小为12 结构体数组arr所占的总大小为252字节 //1220%40 float e[11];//4 1220 - 1263 };//1264 % 8 0嵌套结构体与指针结合读者若是对指针有疑惑可以参考我上篇有关指针的知识介绍相信让你对指针会有更深的理解struct stu8 { char a; //1 0 1 short b; //2 2 3 int* c; //4 4-7 double* d; //4 8-11 //cd均为指针大小为四个字节 int arr[10]; //4 12 - 51 int(*brr)[10]; //4 52 53 54 55 //brr为一个由10个int成员构成的数组的地址 大小为4个字节 struct stu6* crr[10];//4 56 - 95 //crr 是一个有10个struct stu6* 类型元素构成的数组 crr的大小为40个字节 struct stu* drr; //4 96 97 98 99 //drr 为结构体指针 大小为4个字节 //因为 8 4 所以该结构体的最大对齐数为4 };//0~99 100个字节 100%40 所以该结构体的大小为100字节在vs中将结果验证给读者3.拓展修改默认对齐数#pragma pack(n)//修改(设置)默认对齐数为指定的n对齐数 该成员大小 与 默认对齐数比较的 较小值而上述函数可以修改默认对齐数的大小​ //不修改 struct stu9 {//成员对齐数 所占字节号 int a; //4 0 1 2 3 char b; //1 4 (5 6 7) double c;//8 8 --15 };//0~15 16个字节 16%80 该结构体的大小为16字节 //修改 #pragma pack(2) //修改(设置)默认对齐数为2 struct stu7 { //成员对齐数 所占字节号 int a; //2 0 1 2 3 char b; //1 4 (5) double c; //2 6 -- 13 c的大小虽然为8字节 但是与默认对齐数 };//0~13 14个字节 14%20 该结构体的大小为14字节 2比较要大所以2是c成员的对齐数 ​在vs中向读者演示三、总结结构体是C语言中非常重要的一种数据类型它允许我们将不同类型的数据组合在一起。在计算结构体大小时需要考虑内存对齐的因素。通过合理调整结构体成员的顺序可以优化结构体的空间使用。深入理解结构体及其大小计算有助于我们编写更高效、更节省内存的C语言程序。希望通过本文的介绍读者对结构体和结构体大小计算有了更全面的理解加油