【C语言】自定义类型:联合体与枚举 文章目录一、联合体Union1.1 什么是联合体1.2 联合体的特点1.3 联合体与结构体的对比1.4 联合体大小的计算规则1.5 联合体的典型应用应用1节省内存应用2判断机器字节序二、枚举Enum2.1 什么是枚举2.2 枚举的优势对比#define2.3 枚举的使用方法一、联合体Union1.1 什么是联合体联合体是一种特殊的自定义类型它由多个不同类型的成员组成但所有成员共用同一块内存空间。这意味着联合体的大小仅需满足最大成员的存储需求相比结构体能显著节省内存。声明方式与结构体类似关键字为union// 联合体类型声明unionUn{charc;// 字符型成员inti;// 整型成员};// 联合体变量定义unionUn un;1.2 联合体的特点内存共用所有成员共享同一块内存起始地址相同。#includestdio.hunionUn{charc;inti;};intmain(){unionUn un;printf(un %p\n,un);// 输出001AF85Cprintf(un.i %p\n,un.i);// 输出001AF85Cprintf(un.c %p\n,un.c);// 输出001AF85Creturn0;}上述代码中联合体变量un及其成员i、c的地址完全相同证明它们共用内存。成员值相互影响修改一个成员的值会影响其他成员。#includestdio.hunionUn{charc;inti;};intmain(){unionUn un;un.i0x11223344;// 赋值整型成员un.c0x55;// 修改字符型成员printf(%x\n,un.i);// 输出11223355return0;}原理int类型占4字节char占1字节。un.c修改的是un.i的第一个字节低地址位导致un.i的原值0x11223344变为0x11223355。1.3 联合体与结构体的对比类型内存布局特点大小计算方式结构体struct成员占用独立内存按对齐规则排列所有成员大小之和含填充字节联合体union成员共用一块内存至少为最大成员大小需满足对齐示例对比结构体成员独立占用内存structS{charc;// 1字节inti;// 4字节因对齐c后填充3字节};// 大小1 3填充 4 8字节联合体成员共用内存unionUn{charc;// 1字节inti;// 4字节};// 大小4字节取最大成员大小1.4 联合体大小的计算规则基础规则联合体大小至少为最大成员的大小。对齐规则若最大成员大小不是“最大对齐数”的整数倍需向上对齐到整数倍。对齐数成员自身大小与默认对齐数的较小值默认对齐数通常为4或8示例计算案例1char[5]大小5与int大小4unionUn1{charc[5];// 对齐数1大小5inti;// 对齐数4大小4};// 最大成员大小5最大对齐数4。5不是4的倍数向上对齐到84×2。// sizeof(Un1) 8案例2short[7]大小14与int大小4unionUn2{shortc[7];// 对齐数2大小14inti;// 对齐数4大小4};// 最大成员大小14最大对齐数4。14不是4的倍数向上对齐到164×4。// sizeof(Un2) 161.5 联合体的典型应用应用1节省内存当数据包含“公共属性”和“互斥的特殊属性”时用联合体存储特殊属性可减少内存浪费。例如“礼品兑换单”设计优化前结构体包含所有属性浪费内存structgift_list{// 公共属性intstock_number;// 库存量doubleprice;// 价格intitem_type;// 商品类型1-图书2-杯子3-衬衫// 特殊属性互斥仅一种生效chartitle[20];// 书名仅图书charauthor[20];// 作者仅图书intnum_pages;// 页数仅图书chardesign[30];// 设计仅杯子/衬衫intcolors;// 颜色仅衬衫intsizes;// 尺寸仅衬衫};优化后用联合体存储特殊属性structgift_list{intstock_number;doubleprice;intitem_type;union{// 特殊属性共用内存struct{chartitle[20];charauthor[20];intnum_pages;}book;struct{chardesign[30];}mug;struct{chardesign[30];intcolors;intsizes;}shirt;}item;};优化后特殊属性仅占用最大成员的内存shirt结构体大小避免了无效属性的内存浪费。应用2判断机器字节序字节序是数据在内存中的存储顺序大端/小端联合体可简单判断// 返回1小端低地址存低位数据返回0大端低地址存高位数据intcheck_sys(){union{inti;// 4字节0x00000001charc;// 1字节取i的低地址位}un;un.i1;returnun.c;// 小端c1大端c0}二、枚举Enum2.1 什么是枚举枚举用于定义有限个可能取值的集合例如星期、性别、颜色等。它将离散值命名增强代码可读性。声明方式// 枚举类型声明默认值从0开始递增enumDay{Mon,// 0Tues,// 1Wed,// 2Thur,// 3Fri,// 4Sat,// 5Sun// 6};// 手动指定枚举值enumColor{RED2,// 2GREEN4,// 4BLUE8// 8};enum Day、enum Color为枚举类型Mon、RED等为枚举常量。2.2 枚举的优势对比#define优势说明增强可读性用RED代替1代码意图更清晰。类型检查更严格枚举变量只能接收枚举常量#define定义的常量无类型限制。便于调试预处理阶段会删除#define符号而枚举常量在调试时可见。批量定义常量一次声明多个相关常量无需重复写#define。遵循作用域规则枚举声明在函数内时仅在函数内有效避免全局命名污染。2.3 枚举的使用方法定义枚举变量enumColor{RED,GREEN,BLUE};enumColorclrGREEN;// 用枚举常量赋值赋值规则C语言允许直接赋值整数不推荐破坏类型检查enumColorclr2;// C中允许C中禁止建议始终使用枚举常量赋值保证代码规范性。