C语言当中结构体、联合体与枚举属于自定义的数据类型内存排布、参数传递等方面存在不少容易混淆的知识点。本文就结构体、联合体、枚举的基础概念、内存特征以及基本用法展开整理记录学习当中的理解。文章目录结构体struct什么是结构体结构体内存对齐结构体传参联合体共同体union什么是联合体联合体大小及与结构体的区别枚举enum什么是枚举枚举的使用结构体struct什么是结构体struct可以把多种不同类型的数据打包在一起用来描述一个对象。示例一结构体定义、创建变量、初始化访问成员#includestdio.h// 定义结构体模版只是描述格式不开辟内存structStu{charname[20];// 名字intage;// 年龄charsex[5];// 性别charid[20];// 学号};intmain(){// 按顺序给成员赋值初始化structStus1{张三,20,男,202308001};// C99写法指定成员赋值顺序可以随便写structStus2{.age18,.namelist,id202308001,sex女};// 普遍结构体变量用. 访问成员s1.age21;// 结构体指针用 - 访问成员structStu*pss1;ps-age22;return0;}示例二typedef 给结构体起别名#includestdio.h// typedef 给结构体起别名以后不用重复写structtypedefstructStu{charname{20};intage;}Student;intmain(){Student s;s.age19;return0;}结构体内存对齐计算结构体占用内存大小需要遵守三条对齐规则目的是方便CPU读取数据。1. 每个成员存放地址必须是自身类型大小的倍数。2. 结构体总大小必须等于内部最大成员大小的倍数。3. 不满足上面编译器自动补空余字节空余字节不能存数据。特殊#pragma pack预处理指令可以修改编译器默认对齐方式。#includestdio.h// 设置结构体的最大对齐数为1取消内存填充#pragmapack(1)structS{charc1;// 1 1 1inti;// 4 1 4charc2;// 1 1 1};// 恢复编译器原本默认对齐数后面代码不受pack(1)影响#pragmapack()intmain(){// 总大小1 4 1 6字节printf(sizeof(struct S)%d\n,sizeof(structS));return0;}结构体传参两种传参方式值传递、地址传递。函数传参时参数是压栈处理会占用栈空间。如果结构体对象本身规模很大参数压栈的系统开销就会比较大容易导致栈溢出。结论结构体传参优先传结构体的地址。#includestdio.hstructS{intdata[5];intnum;};// 值传递把整个结构体复制一份传给函数// 函数修改的是复制出来的副本不会改外面原数据结构体大的时候开销大存在栈溢出风险voidPrint1(structSs){inti0;for(i0;i5;i){printf(%d ,s.data[i]);}printf(\n%d\n,s.num);}// 地址传递只传结构体地址不复制全部数据开销小规避栈溢出问题// const限制函数不让修改外面原始数据去掉const就可以修改原结构体voidPrint2(conststructS*ps){inti0;for(i0;i5;i){printf(%d ,ps-data[i]);}printf(\n%d\n,ps-num);}intmain(){structSs{{1,2,3,4,5},100};Print1(s);Print2(s);return0;}联合体共同体union什么是联合体关键字union里面可以放多种不同类型变量全部共用同一块内存。改其中一个成员别个成员就会被覆盖。#includestdio.h// 定义联合体类型unionUn{charc;inti;};intmain(){unionUn un{0};// 创建联合体变量un.i0x11223344;// 给int成员赋值printf(修改前 i %#x\n,un.i);un.c0x55;// 修改char会覆盖 int 的低字节共用内存printf(修改后 i %#x\n,un.i)printf(联合体大小%d\n,sizeof(un));return0;}联合体大小及与结构体的区别计算规则联合体最少要等于最大那个成员的字节。联合体的最大对齐数 联合体中最大基础类型成员的字节数如果这个大小不满足最大对齐数的倍数后面补空字节凑够倍数。与结构体的区别核心对比内存结构体每个成员各占一块内存联合体全部成员共用一块内存大小结构体所有成员字节相加再补对齐空位联合体取最大成员大小再补对齐空位使用结构体所有成员可以同时用联合体同一时间只能用其中一个成员枚举enum什么是枚举枚举用关键字enum表示顾名思义就是一 一列举把变量所有可能的取值全部罗列出来。像星期性别三原色取值有限适合使用枚举。规则不给常量写数值第一个默认是0后面依次1。枚举本质是整型常量底层占4字节。枚举常量不可以被赋值修改。示例//星期enumDay{Mon,Tues,Wed,Thur,Fri,Sat,Sun};//性别enumSex{MALE,FEMALE,SECRET};//三原色enumColor{RED,GREEN,BLUE};枚举的使用作用替代程序中含义模糊的魔法数字提升代码可读性同时限制变量只能使用列举出来的合法值减少程序出错。示例