【C语言】自定义类型之联合和枚举
目录
- 1. 前言
- 2. 联合体
- 2.1 联合体类型的声明
- 2.2 联合体的特点
- 2.3 相同成员的结构体和联合体对比
- 2.4 联合体大小的计算
- 2.4 判断当前机器的大小端
- 3. 枚举
- 3.1 枚举类型的声明
- 3.2 枚举类型的优点
- 3.3 枚举类型的使用
1. 前言
在之前的博客中介绍了自定义类型中的结构体,有想了解的可以点这个链接:link
今天来分享另外两种类型:联合和枚举。
2. 联合体
2.1 联合体类型的声明
像结构体一样,联合体也是由一个或者多个成员构成,这些成员可以不同的类型。但是编译器只为最大的成员分配足够的内存空间。
联合体的特点是所有成员共用同一块内存空间。所以联合体也叫:共用体。
-----------------------------------------------------------------------------------------
我们举个例子来看一下:
我们发现在联合体中的大小占4个字节,这是为什么呢?
我们来看看它每个成员的地址
我们发现那三个的地址都是一样的。
改到32位平台上发现内存地址还是一样的。
也就是说它们共用一块空间
-----------------------------------------------------------------------------------------
给联合体其中⼀个成员赋值,其他成员的值也跟着变化。
在同一个时间点只能使用一个联合体成员。
2.2 联合体的特点
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合⾄少得有能力保存最大的那个成员)。
来看个例子
#include <stdio.h>//联合类型的声明
union Un
{char c;int i;
};int main()
{//联合变量的定义union Un un = { 0 };un.i = 0x11223344;un.c = 0x55;printf("%x\n", un.i);return 0;
}
我们来看看在内存中的变换:
代码的输出,我们发现将i的第4个字节的内容修改为55了。
我们仔细分析就可以画出,un的内存布局图。
2.3 相同成员的结构体和联合体对比
我们再对比一下相同成员的结构体和联合体的内存布局情况
结构体的代码:
struct S
{char c;int i;
};
struct S s = {0};
联合体的代码:
union Un
{char c;int i;
};
union Un un = {0};
对于结构体来说就占了8个字节,浪费了3个字节,而联合体占了4个字节。
2.4 联合体大小的计算
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
举个例子:计算下面两个联合体的大小?
#include <stdio.h>union Un1
{char c[5];//5 1 8 1int i;//4 4 8 4
};union Un2
{short c[7];//14 2 8 2int i;//4 4 8 4
};int main()
{printf("%d\n", sizeof(union Un1));//8printf("%d\n", sizeof(union Un2));//16return 0;
}
对于Un1,char c[5],占五个字节,char类型占1个字节,对齐数默认是8,对比之后取对齐数取1。 int i,占4个字节,对齐数默认是8,对比之后取对齐数取4。所以等于5时,5不是4的倍数,就得浪费3个字节,取8。
对于Un2 ,short c[7]占14个字节,short占2个,对齐数默认是8,对比之后取对齐数取2; int i,占4个字节,对齐数默认是8,对比之后取对齐数取4。所以等于14时,14不是4的倍数,就得浪费2个字节,取16。
联合体的大小,并不是其中最大成员的大小
-----------------------------------------------------------------------------------------
使用联合体是可以节省空间的,
举例:
比如,我们要搞一个活动,要上线一个礼品兑换单,礼品兑换单中有三种商品:图书、杯子、衬衫。
每⼀种商品都有:库存量、价格、商品类型和商品类型相关的其他信息。
图书:书名、作者、页数
杯子:设计
衬衫:设计、可选颜⾊、可选尺寸
如果我们使用结构体来定义这个活动的礼物时,
代码如下:
struct gift_list
{//公共属性int stock_number;//库存量double price; //定价int item_type;//商品类型//特殊属性char title[20];//书名char author[20];//作者int num_pages;//⻚数char design[30];//设计int colors;//颜⾊int sizes;//尺⼨
};
上述的结构其实设计的很简单,用起来也方便,但是结构的设计中包含了所有礼品的各种属性,这样使得结构体的大小就会偏大,比较浪费内存。因为对于礼品兑换单中的商品来说,只有部分属性信息是常用的。
所以我们就可以把公共属性单独写出来,剩余属于各种商品本身的属性使用联合体起来,这样就可以介绍所需的内存空间,一定程度上节省了内存。
用联合体来实现,代码如下:
struct gift_list
{int stock_number;//库存量double price; //定价int item_type;//商品类型union {struct{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;
};
这里使用了匿名结构体,这里的书、杯子和衬衫是不能同时存在的。就按照最大的结构体内存也就是书所占的大小来开辟空间,这样其它的也能放下。
我们就可以选择礼物及它的成员。
2.4 判断当前机器的大小端
在之间博客中有说明,这里就不过多讲述,有需要的可以查看; link
之前所写的代码是利用指针来判断的:
int main()
{int a = 1;if (*(char*)&a == 1){printf("小端\n");}else{printf("大端\n");}return 0;
}
结果显示的是小端。
-----------------------------------------------------------------------------------------
这次我们使用联合体来判断
int check_sys()
{union{char c;int i;}u;u.i = 1;return u.c;
}int main()
{if (check_sys() == 1)printf("小端\n");elseprintf("大端\n");return 0;
}
也就是来判断一下u.c存的是0还是1?
结果和上面一样,是小端存储
3. 枚举
3.1 枚举类型的声明
枚举顾名思义就是一一列举。
把可能的取值一一列举。
比如我们现实生活中:
一周的星期一到星期日是有限的7天,可以一一列举
性别有:男、女、保密,也可以一一列举
月份有12个月,也可以一一列举
三原色,也是可以意义列举
这些数据的表示就可以使用枚举了。
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,当然在声明枚举类型的时候也可以赋初值。
来看看日期的取值:
也就是:默认从0开始,依次递增1,一直到6。
当然在声明枚举类型的时候也可以赋初值。
enum Color//颜⾊
{RED = 2,GREEN = 4,BLUE = 8
};int main()
{printf("%d %d %d\n", RED, GREEN, BLUE);return 0;
}
3.2 枚举类型的优点
我们可以使用 #define
定义常量,为什么非要使用枚举?
枚举的优点:
- 增加代码的可读性和可维护性
- 和
#define
定义的标识符比较枚举有类型检查,更加严谨。 - 便于调试,预处理阶段会删除
#define
定义的符号 - 使用方便,一次可以定义多个常量
- 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用
举个例子:实现一个简单计算器
我们就能将加减乘除设置成枚举类型,这样在主函数中进行对应的操作时就会知道就行的是哪中计算。
这里只是简单举个例子说明一下枚举的优点,具体的函数大家可以自行修改。
void menu()
{printf("*********************\n");printf("*** 1.add 2.sub ***\n");printf("*** 3.mul 4.div ***\n");printf("*** 0.exit ***\n");printf("*********************\n");
}enum Option
{EXIT,//0ADD,//1SUB,//2MUL,//3DIV//4
};
int Add(int a, int b)
{return a + b;
}int Sub(int a, int b)
{return a - b;
}int Mul(int a, int b)
{return a * b;
}int Div(int a, int b)
{return a / b;
}int main()
{int input = 0;int a = 0;int b = 0;do{menu();printf("请选择:");scanf("%d", &input);scanf("%d %d", &a,&b);switch (input){case ADD:Add(a, b);break;case SUB:Sub(a, b);break;case MUL:Mul(a, b);break;case DIV:Div(a, b);break;default:break;}} while (input);return 0;
}
3.3 枚举类型的使用
enum Color//颜色
{RED = 1,GREEN = 2,BLUE = 4
};int main()
{enum Color clr = GREEN;//使用枚举常量给枚举变量赋值enum Color clr2 = 2;printf("%d\n", sizeof(clr));//4return 0;
}
那是否可以拿整数给枚举变量赋值呢?在C语言中是可以的,但是C++是不行的,C++的类型检查比较严格。
有错误请指出,大家一起进步!
相关文章:
【C语言】自定义类型之联合和枚举
目录 1. 前言2. 联合体2.1 联合体类型的声明2.2 联合体的特点2.3 相同成员的结构体和联合体对比2.4 联合体大小的计算2.4 判断当前机器的大小端 3. 枚举3.1 枚举类型的声明3.2 枚举类型的优点3.3 枚举类型的使用 1. 前言 在之前的博客中介绍了自定义类型中的结构体,…...
使用Mosquitto/python3进行MQTT连接
一、简介 MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件。 …...
JavaWeb笔记之前端开发HTML
一、引言 1.1HTML概念 网页,是网站中的一个页面,通常是网页是构成网站的基本元素,是承载各种网站应用的平台。通俗的说,网站就是由网页组成的。通常我们看到的网页都是以htm或html后缀结尾的文件,俗称 HTML文件。 …...
通过IP地址定位解决被薅羊毛问题
随着互联网的普及,线上交易和优惠活动日益增多,这也为一些不法分子提供了可乘之机。他们利用技术手段,通过大量注册账号或使用虚假IP地址进行异常操作,以获取更多的优惠或利益,这种行为被称为“薅羊毛”。对于企业和平…...
Leetcode 122 买卖股票的最佳时机 II
题意理解: 已知:一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格 如何哪个时间点买入,哪个时间点卖出,多次交易,能够收益最大化 目的:收益最大化 解题思路: 使用贪心…...
音频文件合成
音频文件合成 音频文件合成 http://ffmpeg.org/download.html https://blog.csdn.net/u013314786/article/details/89682800 http://www.360doc.com/content/19/0317/01/10519289_822112563.shtml https://chaijunkun.blog.csdn.net/article/details/116491526?spm1001.210…...
20231220将NanoPC-T4(RK3399)开发板的Android10的SDK按照Rockchip官方挖掘机开发板编译打包刷机之后启动跑飞
20231220将NanoPC-T4(RK3399)开发板的Android10的SDK按照Rockchip官方挖掘机开发板编译打包刷机之后启动跑飞 2023/12/20 17:19 简略步骤:rootrootrootroot-X99-Turbo:~/3TB$ tar --use-compress-programpigz -xvpf rk3399-android-10.git-20210201.tgz rootrootro…...
vivo 容器平台资源运营实践
作者:vivo 互联网服务器团队 - Chen Han 容器平台针对业务资源申请值偏大的运营问题,通过静态超卖和动态超卖两种技术方案,使业务资源申请值趋于合理化,提高平台资源装箱率和资源利用率。 一、背景 在Kubernetes中,容…...
ASP.NET Core面试题之Redis高频问题
🎈🎈在.NET后端开发岗位中,如今也少不了、微服务、分布式、高并发高可用相关的面试题🎈🎈 👍👍本文分享一些整理的Redis高频面试题🎉 👍👍机会都是给有准备…...
【教程】Ubuntu基本软件安装
文章目录 一、搜狗输入法安装二、百度网盘安装三、划词翻译 一、搜狗输入法安装 全网最准确的Ubuntu 20.04 安装搜狗输入法的步骤 二、百度网盘安装 百度云盘for Linux安装教程和体验 三、划词翻译 ubuntu最好用的划词翻译词典:有道词典和GoldenDict...
Jenkins 构建环境指南
目录 Delete workspace before build starts(常用) Use secret text(s) or file(s) (常用) Add timestamps to the Console Output (常用) Inspect build log for published build scans Terminate a …...
基于Go语言的HTTP路由设计与实现
在Go语言的世界里,HTTP路由是一种将HTTP请求映射到相应处理函数的技术。通过路由,我们可以确定当用户发送一个HTTP请求时,应该调用哪个函数来处理该请求。在这个过程中,我们可以使用多种方法来实现路由设计,下面我将以…...
SpringMVC01
SpringMVC 1. 学习⽬标2. 什么叫MVC?3. SpringMVC 框架概念与特点4. SpringMVC 请求流程5. Spring MVC 环境搭建6. URL 地址映射配置7. 参数绑定8. JSON 数据开发JSON普通数组步骤1:pom.xml添加依赖步骤2: 修改配置⽂件步骤3. 注解使⽤ 1. 学习⽬标 2. 什…...
基于Redis限流(aop切面+redis实现“令牌桶算法”)
令牌桶算法属于流量控制算法,在一定时间内保证一个键(key)的访问量不超过某个阈值。这里的关键是设置一个令牌桶,在某个时间段内生成一定数量的令牌,然后每次访问时从桶中获取令牌,如果桶中没有令牌&#x…...
【小白专用】php pdo方式连接sqlserver 设置方法 更新23.12.21
windows系统的拓展相对来说比较好安装,直接下载对应的dll文件,修改php.ini配置文件即可。 添加PHP对SQL SERVER的支持 1.新建PHP 文件,输入内容: <?php echo phpinfo(); ?> 2.运行后,可以查看到如下数据&…...
打开C#项目时出现“error : 找不到指定的 SDK”的错误解决方法汇总
从github上克隆项目回来,发现编译通过,我是通过一下步骤解决的: 1.到适用于 Visual Studio 的 .NET SDK 下载网址下载对应版本的.NET SDK,关闭当前VS后安装; 2.参考VS2022报错:error : 找不到指定的 SDK“…...
MIT 6.824 练习1
Hi, there! 这是一份根据 MIT 6.824(2021) 课程的第 2 课的课堂示例代码改编的 2 个 go 语言编程练习。像其他的编程作业一样,我去除了核心部分,保留了代码框架,并编写了每一步的提示 练习代码在本文的最后面 爬虫 在第一部分,…...
Git报错x509: certificate signed by unknown authority
下载报错: Error downloading object: model-00001-of-00008.safetensors (ed3ac49): Smudge error: Error downloading model-00001-of-00008.safetensors (ed3ac4983f682a999b0e4b6f072aad294c4fd9a7e968e90835ba5c4b466d3c7c): LFS: Get https://cdn-lfs.huggin…...
OpenCV技术应用(8)— 如何将视频分解
前言:Hello大家好,我是小哥谈。本节课就手把手教大家如何将一幅图像转化成热力图,希望大家学习之后能够有所收获~!🌈 目录 🚀1.技术介绍 🚀2.实现代码 🚀1.技术介绍 视频是…...
Swagger2接口测试文档
目录 一、Swagger简介 1.1 Swagger是什么? 1.2 为什么要用Swagger 1.3 Swagger注解 二、Spring集成Swagger 三、测试环境配置 一、Swagger简介 1.1 Swagger是什么? Swagger 是一个开源的 API 设计和文档工具,它可以帮助开发人员更快、…...
【Java】BigDecimal 比较自动化页面获取数据的大小
jwensh2023.12.20 使用背景 对 web3 相关的数据进行计算的时候,需要进行大小加减计算,UI 自动化过程需要将数据转为自然数;页面获取的数据会有千分位 、高精度(18位) /*** Compares this {code BigDecimal} with the specified* {code BigDe…...
开源键盘工程QMK
一、Qmk简介 目录 一、Qmk简介 二、Qmk入门指导文档 三、QMK配置器 四、QMK层的概念 TMK原先是由Jun Wako设计实现...
Elasticsearch的批量bulk 提交 写入的方式会有顺序问题吗?
Elasticsearch的分布式特性可能会导致写入操作的执行顺序与提交顺序稍有不同。在分布式环境中,Elasticsearch将数据分散到不同的节点上进行存储和处理,因此写入操作的执行顺序可能会受到网络延迟、负载均衡等因素的影响。 根源在于ES的分布式架构。如上图所示,客户端的命令首…...
云原生之深入解析如何使用Vcluster Kubernetes加速开发效率
一、背景 为什么一个已经在使用 Kubernetes 本身方面已经很挣扎的开发人员还要处理虚拟集群呢?答案可能会让您感到惊讶,但虚拟集群实际上比单独的物理集群更容易处理,并且与本地 k3d、KinD 或 minikube 部署的集群相比具有相当多的优势。如果…...
PCL 已知同名点对计算旋转矩阵并对点云进行旋转
目录 一、 算法概述二、代码实现三、测试示例一、 算法概述 适用:已知三组及三组以上的同名点对,计算旋转矩阵;然后根据旋转矩阵对点云进行旋转,最后保存旋转后的点云文件。 二、代码实现 #include <Eigen/Core> #include <Eigen/Dense>...
MyBatis ORM映射
MyBatis只能自动维护库表”列名“与”属性名“相同时的对应关系,二者不同时无法自动ORM 因此需要使用到ORM映射。 共有两种解决办法:1.列的别名 2.结果映射 1.列的别名 在SQL中使用 as 为查询字段添加列别名,以匹配属性名 public List<…...
在线客服系统推荐:为何选择Zoho Desk?
客户和企业的关系并不止于一次买卖关系,企业后续持续的服务不仅是对客户的保障,更能收获良好的品牌口碑和持续的良性收益。所以,企业需要在客户旅程的每一个阶段为客户提供优质服务。而在这段服务旅程中,在线客服系统承担了重要的…...
手绘心情树叶,探索情绪世界
人生如同滚雪球,关键在于找到湿润的雪和陡峭的坡。正如巴菲特所言。昨天参与JSTO的经历,让我深有同感。徐老师分享的主题是《手绘心情树叶,探索情绪世界》,发现在JSTO这个平台上,伙伴们的成长速度惊人。从系统的角度看…...
智能优化算法应用:基于水基湍流算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于水基湍流算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于水基湍流算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.水基湍流算法4.实验参数设定5.算法结果6.…...
打开和关闭GBASE南大通用数据库连接
下面的样例代码使用连接字符串通过GBASE南大通用Connection 类创建连接对象、 打开连接、关闭连接GBASE南大通用。 C# 示例: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using Sys…...
专门做校招的网站/seo包年优化平台
2019独角兽企业重金招聘Python工程师标准>>> 在浏览网页的时候我们有时可以看到有的网页滚动条颜色不是系统默认的,而是漂亮的红色或其它颜色,其实这就是在网页代码之间加入代码来实现的,具体是哪些代码呢? 网页滚动…...
廊坊做网站电话/seo关键词优化外包
问题描述:父组件传如lesser和larger两个参数,并且是ajax从服务器获取的。子组件定义created阶段输出lesser和larger。但larger为空。改成延迟输出则正确。问题来源:https://segmentfault.com/q/1010000008912491提问者的主要问题是没有搞清楚…...
怎么把网站放到空间/成都最新热门事件
2019.08.29学习整理 绑定方法与非绑定方法 绑定方法 对象绑定方法 类的绑定方法 绑定方法:特殊之处,绑定给谁就是谁来调,并且会把自身调过来 类的绑定方法 绑定给类,类来调用,会把类自身传过来 类的绑定方法用在什么地…...
简网 互联 专业wordpress主机/媒体公关
C语言 _ 编辑、调试工具一、GCC编译器1、GNU工具2、GCC简介3、GCC编译器的版本4、gcc所支持后缀名解释5、编译器的主要组件6、GCC的基本用法和选项7、GCC的错误类型及对策8、**GCC编译过程**条件编译二、GDB调试工具1、Gdb调试流程:2、进入代码调试模式后一、GCC编译…...
苏州北京网站建设/页面关键词优化
安装Linux(如果之前已经有Linux,不用安装,直接安装Hadoop) 参考链接:厦门大学Hadoop安装教程_单机/伪分布式配置 1尝试新建一个名为hadoop的用户并且设置密码(同时添加管理员权限):…...
新网 主办网站已备案/鄞州seo整站优化服务
【51CTO.com快译】GitHub汇集了世界上一些***秀的项目,离不开全球各地开发人员的贡献。这个简单又极其强大的平台帮助每一个有兴趣构建或开发重要产品的人贡献代码,并在开源界得到尊重。本教程是安装和使用GitHub的快速安装指南,介绍了如何使…...