目录

  • 一、联合体
    • 1.1 联合体类型的声明
    • 1.2 联合体的特点
    • 1.3 相同成员的结构体和联合体对比
    • 1.4 联合体大小的计算
    • 1.5 联合练习
  • 二、枚举类型
    • 2.1 枚举类型的声明
    • 2.2 枚举类型的优点
  • 总结


一、联合体

1.1 联合体类型的声明

像结构体一样,联合体也是由一个或者多个成员构成,这些成员可以是不同的类型。

在联合体里编译器只为最大的成员分配足够的内存空间,所以联合体的特点是所有成员共用同一块内存空间,所以联合体也叫:共用体

给联合体其中一个成员赋值,其他成员的值也跟着变化。
在这里插入图片描述
所以联合体一般所占用的空间也更小

1.2 联合体的特点

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合体至少得有能力保存最大的那个成员)。

这里具体再看一下联合体及成员的内存是怎么分配的
在这里插入图片描述
这里输出的三个地址一模一样,其un的内存布局如下图:
在这里插入图片描述

还可用下面的例子验证其存储原理
在这里插入图片描述
这里确实开辟了四个字节的空间
在这里插入图片描述
在这里插入图片描述
这里改了c的值,连同i一起改了,验证了联合的成员是共用同一块内存空间的,这就是联合体与结构体的本质区别,结构体是给每个成员分配一块空间的。

1.3 相同成员的结构体和联合体对比

struct S
{char c;int i;
};
struct S s = { 0 };
union Un
{char c;int i;
};
union Un un = { 0 };

联合体和结构体内存布局情况:
在这里插入图片描述
所以联合体和结构体的使用情景是不同的

1.4 联合体大小的计算

  • 联合的大小至少是最大成员的大小
  • 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

在这里插入图片描述
按照第一点,Un1的大小应该是5个字节,Un2的大小应该是14个字节,出现这样的结果就涉及到第二点了

首先,数组在计算对齐数时,是按照元素来算的,数据类型为char,自身的大小为1,vs上默认对齐数为8,最终对齐数取较小值为1,这又涉及我上一篇关于对齐数的解析了深入解析自定义类型:结构体与位段
所以Un1的最大成员大小为5,不是最大对齐数4的整数倍,所以要对齐最大对齐数的整数倍,所以联合体大小为4的倍数,8,相当于浪费了3个空间用于对齐。

对于Un2也一样分析,数组的数据类型为short,自身大小为2,vs默认对齐数为8,最终对齐数取较小值2,i的数据类型为int,自身大小为4,小于vs默认对齐数8,所以i的最终对齐数为4
Un2的最大成员大小为14不是最大对齐数4的对数,所以联合体大小为16,浪费2个空间用于对齐。

使用联合体是可以节省空间的,如下例:
现在商场要搞一个活动,要上线一个礼品兑换单,礼品兑换单中有三种商品:图书、杯子、衬衫。
每一种商品都有:库存量、价格、商品类型和商品类型相关的其他信息

  • 图书:书名、作者、页数
  • 杯子:设计
  • 衬衫:设计、可选颜色、可选尺寸

总结下来就是下图:
在这里插入图片描述
单用结构体的话,写出来的程序就如下图
在这里插入图片描述
上述结构体构想的时候很简单,用起来也很方便,但是结构的设计包含了所有礼品的各种属性,图中红框成员在对应商品上就没有用上,这样就使得结构体的大小就会偏大,比较浪费内存。因为对于礼品兑换单中的商品来说,只有部分属性信息是常用的。
比如:
商品是图书,就不需要设计,可选颜色,可选尺寸了。

所以可以把公共属性单独写出来,剩余属于各种商品本身的属性使用联合起来。这样就可以介绍所需的内存空间,一定程度上节省了内存。

struct gift_list
{int stock_number;//库存量double price;//定价int item_type;//商品类型union {//结构体可以匿名,联合体也可以struct//这里3个匿名结构体创建的成员不一样,所以是三个单独的匿名结构体类型//所以符合匿名结构体只能使用一次的规则//这三个结构体变量不会同时存在,礼品之中三选一//所以这三者可以共用一片空间了{char title[20];//书名char author[20];//作者int num_pages;//页数}book;struct{char design[30];//设计}mug;//杯子struct{char design[30];//设计int colors;//颜色int sizes;//尺寸}shirt;}item;
};

union item:根据item_type的值,存储对应类型的礼品详细信息
共用体的特点是所有成员共享同一块内存空间,因此item的大小取决于其最大成员。这里最大的成员是shirt结构体(30+4+4=38 字节),所以item占用 38 字节。
item(38 字节,但需对齐到 4 的倍数,故为 40 字节)

1.5 联合练习

深入解析数据在内存中的存储 - 大小端字节序和字节序判断(百度笔试题)
在上面这篇文章是这样写的
在这里插入图片描述
这里使用联合体的知识进行改进
在这里插入图片描述


二、枚举类型

2.1 枚举类型的声明

顾名思义枚举的意思就是一一列举,把可能的取值一一列举出来,例如:

  1. 一周的星期一到星期日
  2. 性别:男,女,保密
  3. 12个月
  4. 三原色

用代码表示如下:

enum Day//星期
{Mon,Tues,Wed,Thur,Fri,Sat,Sun
};enum Sex//性别
{MALE,FEMALE,SECRET
};enum Color//颜色
{RED,GREEN,BLUE
};
  • 代码中定义的enum Day,enum Sex,enum Color都是枚举类型
  • {}中内容是枚举类型的可能取值,也叫枚举常量(即不能更改的)
  • 这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初始值。
    在这里插入图片描述
    在这里插入图片描述

2.2 枚举类型的优点

之前已经知道了#define定义常量,这里为什么还要会枚举呢?
枚举的优点:

  1. 增加代码的可读性和可维护性
    不使用枚举是这样写计算器的
//模拟实现简单计算器
#include<stdio.h>
void menu()
{printf("*************************\n");printf("***** 1.add  2. sub *****\n");printf("***** 3.mul  4. div *****\n");printf("***** 0.exit        *****\n");printf("*************************\n");
}int main()
{int input = 0;do{menu();printf("请选择:");scanf("%d", &input);switch (input){case 1:break;case 2:break;case 3:break;case 4:break;case 0:break;default:break;}} while (input);return 0;
}

这个不是很直观,但可以看出还是有一些可读性改进的。

#include<stdio.h>
enum Option
{EXIT,ADD,SUB,MUL,DIV
};//模拟实现简单计算器
void menu()
{printf("*************************\n");printf("***** 1.add  2. sub *****\n");printf("***** 3.mul  4. div *****\n");printf("***** 0.exit        *****\n");printf("*************************\n");
}int main()
{int input = 0;do{menu();printf("请选择:");scanf("%d", &input);switch (input){case ADD:break;case SUB:break;case MUL:break;case DIV:break;case EXIT:break;default:break;}} while (input);return 0;
}
  1. 和#define定义的标识符比较枚举有类型检查,更加严谨
    define定义的标识符是没有类型的
    在这里插入图片描述
    这里8是int类型,s是Sex类型,把s = FEMALE改为s = 8。在C语言下可以运行,在C++下就不能运行了
    在这里插入图片描述
    所以不同语言对语法检测的严格程度是不同的,C++对语法的检测非常严格。

  2. 便于调试,预处理阶段会删除#define定义的符号
    在这里插入图片描述
    #define定义的MALE在编译时就将MALE全部替换为5,调试时的代码MALE与看到的代码5不是一回事。

  3. 使用方便,一次可以定义多个常量

  4. 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用。


总结

以上就是联合体与枚举部分的全部内容了,说实话我感觉枚举的用处不大,但老师说以后工作会感受到它的具体用处,还有明天考科三,希望过。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/88970.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/88970.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/88970.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FS820R08A6P2LB——英飞凌高性能IGBT模块,驱动高效能源未来!

产品概述FS820R08A6P2LB 是英飞凌&#xff08;Infineon&#xff09;推出的一款高性能、高可靠性IGBT功率模块&#xff0c;采用先进的EconoDUAL™ 3封装&#xff0c;专为大功率工业应用设计。该模块集成了IGBT&#xff08;绝缘栅双极型晶体管&#xff09;和二极管&#xff0c;适…

python学智能算法(十八)|SVM基础概念-向量点积

引言 前序学习进程中&#xff0c;已经对向量的基础定义有所了解&#xff0c;已经知晓了向量的值和方向向量的定义&#xff0c;学习链接如下&#xff1a; 向量的值和方向 在此基础上&#xff0c;本文进一步学习向量点积。 向量点积 向量点积运算规则&#xff0c;我们在中学阶…

【windows办公小助手】比文档编辑器更好用的Notepad++轻量编辑器

Notepad 中文版软件下载&#xff1a;这个路径总是显示有百度无法下载&#xff0c;不推荐 更新&#xff1a;推荐下载路径 https://github.com/notepad-plus-plus/notepad-plus-plus/releases 参考博主&#xff1a;Notepad的安装与使用

2025年7月12日全国青少年信息素养大赛图形化(Scratch)编程小学高年级组复赛真题+答案解析

2025年7月12日全国青少年信息素养大赛图形化(Scratch)编程小学高年级组复赛真题+答案解析 选择题 题目一 运行如图所示的程序,舞台上一共会出现多少只小猫呢?( ) A. 5 B. 6 C. 7 D. 8 正确答案: B 答案解析: 程序中“当绿旗被点击”后,角色先移到指定位置,然后“重…

对于独热编码余弦相似度结果为0和词向量解决了词之间相似性问题的理解

文章目录深入理解简单案例结论词向量&#xff08;Word Embedding&#xff09;简介词向量如何解决相似性问题&#xff1f;简单案例&#xff1a;基于上下文的词向量训练总结对于独热表示的向量&#xff0c;如果采用余弦相似度计算向量间的相似度&#xff0c;可以明显的发现任意两…

数据结构·数状数组(BIT)

树状数组(Binary Index Tree) 英文名&#xff1a;使用二进制下标的树结构 理解&#xff1a;这个树实际上用数组来存&#xff0c;二进制下标就是将正常的下标拆为二进制来看。 求x的最低位1的函数lowbit&#xff08;x&#xff09; 假设x的二进制表示为x ...10000&#xff0c;…

uniapp video视频全屏播放后退出,页面字体变大,样式混乱问题

uniapp官方的说法是因为页面使用rpx&#xff0c;但是全屏和退出全屏自动计算屏幕尺寸不支持rpx&#xff0c;建议使用px。但是因为uniapp端的开发都是使用rpx作为屏幕尺寸计算参数&#xff0c;不可能因为video全屏播放功能就整个全部修改&#xff0c;工作量大&#xff0c;耗时耗…

重复频率较高的广告为何一直在被使用?

在日常生活中&#xff0c;重复评率较高的洗脑广告我们时常能够碰到。广告的本质是信息传递&#xff0c;而重复频率较高的广告往往可以通过洗脑式的传播方式来提升传播效率。下面就让我们一同来了解下&#xff0c;为何这类广告一直受到企业的青睐。一、语义凝练高频率广告的内容…

内容管理系统指南:企业内容运营的核心引擎

内容管理看似简单&#xff0c;实际上随着内容量的激增&#xff0c;管理难度也逐步提升。尤其是在面对大量页面、图文、视频资料等数字内容时&#xff0c;没有专业工具的支持&#xff0c;效率与准确性都会受到挑战。此时&#xff0c;内容管理系统&#xff08;CMS&#xff09;应运…

文献查找任务及其方法

1. 必备网站&#xff1a; 谷歌学术 Web of Science Engineering Village CNKI翻译助手 科研通 2. 任务 学术上的一个调研&#xff0c;自动驾驶 3d 目标检测 方向的近7年的方法&#xff0c;模态&#xff08;相机/雷达/相机雷达 等&#xff09;&#xff0c;及其使用的数据集&a…

鸿蒙的NDK开发初级入门篇

初级必备的知识&#xff1a; NDK开发在什么时候用&#xff1f; 答&#xff1a;&#xff1a;NDK 开发在帮助应用提升性能的情况下使用&#xff0c;比如游戏开发&#xff0c;和硬件交互的场景中。 还有一个公司已经有标准的C或C库&#xff0c;不想在开发ArkTS的代码前提下。 开发…

Unity发布Windows平台后通过Advanced Installer制作安装包

Unity发布Windows平台后是一堆库资源&#xff0c;以及一个可执行的exe文件&#xff0c;并不是一个安装包&#xff0c;如果需要制作成安装包&#xff0c;需要再进一步打包&#xff0c;本篇文章介绍一个Advanced Installer的软件&#xff0c;专门用来制作Windows平台的安装包的。…

代数基本定理

代数基本定理 多项式 f(z)anznan−1zn−1⋯a1za0f(z) a_n z^n a_{n-1} z^{n-1} \cdots a_1 z a_0f(z)an​znan−1​zn−1⋯a1​za0​&#xff08;其中 n>1n > 1n>1 且 an,a0≠0a_n,a_0 \neq 0an​,a0​0&#xff09;在复数域内有根。 约定 以 ttt 为参数的闭曲…

springboot快速集成对接本地Ollama里的Deepseek-R1

书接上回&#xff0c;我们在本地安装了一个Ollama&#xff0c;然后下载了一个deepseek-r1:7b&#xff0c;传送门 本次目标&#xff1a;使用springboot对接ollama&#xff0c;完成简单api对接 1.创建一个项目&#xff0c;选择JDK17&#xff0c;Spring Boot版本3.5.3&#xff0c…

Docker部署私有仓库

环境信息 centos7&#xff1a;docker26.1.4 IP&#xff1a;192.168.12.134 部署harbor wget https://github.com/goharbor/harbor/releases/download/v2.13.1/harbor-offline-installer-v2.13.1.tgz curl -L "https://github.com/docker/compose/releases/download/1.29.2…

张艺兴探班RED女团一周年舞台,见证21岁的梦想落地生根

从青涩的男团偶像&#xff0c;到如今独当一面的音乐制作人、公司老板&#xff0c;张艺兴的每一步都踏得坚定有力&#xff0c;他的故事充满了热血与梦想的色彩。而最近&#xff0c;他探班RED女团一周年舞台现场的举动&#xff0c;又一次成为粉丝和大众热议的焦点&#xff0c;也让…

网络编程 JAVA

一.网络编程1. 什么是网络编程&#xff1f;网络编程是指利用计算机网络实现程序之间通信的一种编程方式。在网络编程中&#xff0c;程序需要通过网络协议&#xff08;如 TCP/IP&#xff09;来进行通信&#xff0c;以实现不同计算机之间的数据传输和共享。2. 三个基本要素①IP …

UE5中的cesium

官方Fab地址&#xff08;https://www.fab.com/zh-cn/&#xff09;&#xff0c;每月可下载免费素材 在UE5中添加插件cesium for unreal&#xff0c; 知识点一&#xff1a;服务器部署.b3dm地形数据 通过在线链接访问数据目录tileset.json&#xff0c;在cesium for unreal添加空白…

持续优化小程序排名,稳定获取搜索流量

一、建立动态关键词管理机制周期性关键词迭代每月通过平台搜索分析工具&#xff08;如微信小程序后台&#xff09;抓取用户搜索词趋势&#xff0c;淘汰搜索量下降的关键词&#xff0c;补充行业热点词与长尾需求词。按 “核心词 季节 / 场景词” 动态调整名称与简介&#xff08…

MyBatis 进阶:连接池、动态 SQL 与多表关联查询

MyBatis 作为一款灵活的持久层框架&#xff0c;除了基础的 CRUD 操作&#xff0c;还提供了连接池管理、动态 SQL 以及多表关联查询等高级特性。本文将从连接池原理出发&#xff0c;深入讲解动态 SQL 的常用标签&#xff0c;并通过实例演示一对多、多对多等复杂关联查询的实现&a…