自定义类型②③——联合体和枚举

news2024/9/21 20:28:37

自定义类型②③——联合体和枚举

  • 1.联合体
    • 1.1 联合体类型的声明
    • 1.2 联合体的特点
    • 1.3 相同成员结构体和联合体的对比
    • 1.4 联合体大小的计算
    • 1.5 联合体的应用①
    • 1.5 联合体的应用②
  • 2. 枚举
    • 2.1 枚举类型的声明
    • 2.2 枚举类型的特点
    • 2.3 枚举的优点

在这里插入图片描述

1.联合体

1.1 联合体类型的声明

关键字:union
联合体的声明和结构体几乎一样。

union un
{
	char c;
	int i;
};

并且与结构体一样,也有 匿名声明 ,以及 typedef 重新命名这一语法

链接: 结构体

1.2 联合体的特点

联合体的特点
联合的成员是 共用同一块内存空间,所以 联合体又叫做共用体

看下面的代码

typedef union 
{
	char c;
	int i;
}un;

int main()
{
	un a = { 0 };
	printf("%p\n", &(a.c));
	printf("%p\n", &(a.i));
	printf("%p\n", &(a));

	return 0;
}

在这里插入图片描述


发现地址都是一样的,这也就反映了联合体只开辟一次空间,并且所有的变量都共用这一块空间,起始地址都是一样的。

联合体这样的特点导致联合体在使用的时候只能够一次性使用一个变量,不能同时使用多个变量,因为联合体共用了同一块内存空间,所以在修改其他成员变量的同时,就会改变之前变量的值


看下面的代码加深一下理解:

typedef union 
{
	char c;
	int i;
}un;

int main()
{
	un a = { 0 };
	a.i = 0x11223344;
	a.c = 0x55; //会改变a.i的值,由于VS是小端存储,所以“44”变为“55”
	printf("%x", a.i);

	return 0;
}

在这里插入图片描述
在这里插入图片描述


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

struct s
{
	char c;
	int i;
};

 union un
{
	char c;
	int i;
};

在这里插入图片描述


可见联合体相比于结构体或者位段,更加能够 节省空间

1.4 联合体大小的计算

由于联合体只需要开辟一次空间,所以都是从偏移量为0的地方开始开辟空间的。

联合体也满足以下的对齐规则:
  • 联合的大小至少是最大成员的大小
  • 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍

 union un
{
	char c[5];
	int i;
};

int main()
{
	union un a = { 0 };
	printf("%zd", sizeof(a));
	return 0;
}

在这里插入图片描述


这里最大的是字符数组为5,但是最大对齐数是4,因此最后的大小需要对齐到4的整数倍,也就是8

1.5 联合体的应用①

比如,我们要搞一个活动,要上线一个礼品兑换单,礼品兑换单中有三种商品:图书、杯子、衬衫。
每一种商品都有:库存量、价格、商品类型和商品类型相关的其他信息

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


如果我们使用结构体:

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; //尺寸
};

上述的结构虽然设计起来简单,用起来也方便,但是结构的设计中包含了所有礼品的各种属性就会使结构体的打下偏大,比较浪费内存。因为对于礼品兑换单中的商品来说,只有部分属性信息是常用的。比如: 商品是图书,就不需要design、colors、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;
};

1.5 联合体的应用②

在前面我们写了一个程序如何判断 大小端字节序

链接:大小端字节序的判断

现在我们在学习了联合体后利用其特点,可以写一个新的代码来判断大小端字节序:

union un
{
	int a;
	char i;
};
int main()
{
	union un a = { 0 };
	a.a = 1;
	printf("%d\n", a.i);
	if (a.i == 0) printf("大端");
	else printf("小端");
	return 0;
}

2. 枚举

2.1 枚举类型的声明

枚举顾名思义就是----列举.把可能得值一一列举.

比如我们的生活中:
  • 一周的星期一到星期日是有限的7天,可以一一列举
  • 性别有:男、女、保密,也可以是一一列举
  • 月份有12个月,也可以一一列举
  • 三原色(蓝绿红),也是可以一一列举

下面介绍枚举的结构,这个与结构体和联合体还是稍微有一点区别。

关键字: enum

enum day
{
	Mon,  // 之间是“,”,而不是“;”连接
	Tues,
	Wed,
	Thur,
	Fri,
	Sat,
	Sun // 最后一个什么也没有
};
int main()
{
	enum day birthday = Mon; //直接赋值就可以了
	return 0;
}

2.2 枚举类型的特点

枚举类型{ }里面的内容是枚举类型的可能取值,也叫 枚举常量 ,注意这些可能取值都是有值的,默认只从0开始,依次递增1。


enum day
{
	Mon,
	Tues,
	Wed,
	Thur,
	Fri,
	Sat,
	Sun
};
int main()
{
	enum day birthday = Mon;
	printf("%d\n", Mon);
	printf("%d\n", Tues);
	printf("%d\n", Wed);
	printf("%d\n", Thur);
	printf("%d\n", Fri);
	printf("%d\n", Sat);
	printf("%d\n", Sun);
	return 0;
}

在这里插入图片描述


当然在声明枚举类型的时候也可以赋初值

并且在创建了一个枚举变量后,应该用枚举常量进行赋值;


enum day
{
	Mon,
	Tues,
	Wed=5,
	Thur,
	Fri,
	Sat,
	Sun
};
int main()
{
	enum day birthday = Mon; //使用枚举常量进行赋值
	printf("%d\n", Mon);
	printf("%d\n", Tues);
	printf("%d\n", Wed);
	printf("%d\n", Thur);
	printf("%d\n", Fri);
	printf("%d\n", Sat);
	printf("%d\n", Sun);
	return 0;
}

在这里插入图片描述


发现从Wed开始的值就变了

2.3 枚举的优点

通过初步对枚举的学习我们不难发现,这个和与 #define 定义全局常量有点像,所以为什么要使用枚举呢?

主要有以下原因:
  1. 增加代码的可读性和可维护性;
  1. 和#define定义的标识符相比,枚举有类型检查,更加严谨(不过C语言没有,C++有,比如枚举类型就只能够用枚举常量进行赋值,哪怕Mon是0,但是只能用Mon进行赋值,而不能是0)
  1. 便于调试,因为在编译的时候会删除#define定义的标识符,会导致我们看到的代码与编译后的代码不一致的问题
  1. 使用方便,一次可以定义多个常量
  1. 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Whisper、Voice Engine推出后,训练语音大模型的高质量数据去哪里找?

近期,OpenAI 在语音领域又带给我们惊喜,通过文本输入以及一段 15 秒的音频示例,可以生成既自然又与原声极为接近的语音。值得注意的是,即使是小模型,只需一个 15 秒的样本,也能创造出富有情感且逼真的声音。…

【字符串】Leetcode 二进制求和

题目讲解 67. 二进制求和 算法讲解 为了方便计算,我们将两个字符串的长度弄成一样的,在短的字符串前面添加字符0;我们从后往前计算,当遇到当前计算出来的字符是> 2’的,那么就需要往前面进位和求余 注意&#xf…

腾讯崛起!2024年最赚钱的电商平台,竟然来自视频号

大家好,我是电商月月 说到卖货平台,这两年“抖音”绝对是所有人心里最赚钱的电商平台 抖音小店的商家利用抖店后台的“精选联盟”引流,不用自己直播,也能靠直播卖货赚的盆满钵满 于是好多平台都效仿抖店的直播卖货形式来获取更…

《自动机理论、语言和计算导论》阅读笔记:p428-p525

《自动机理论、语言和计算导论》学习第 14 天,p428-p525总结,总计 98 页。 一、技术总结 1.Kruskal’s algorithm(克鲁斯克尔算法) 2.NP-Complete Problems p434, We say L is NP-complete if the following statements are true about L: (1)L is …

电机控制器电路板布局布线参考指导(七)电流检测模块布局布线

电机控制器电路板布局布线参考指导(七)电流检测模块布局布线 1.高侧电流检测2.低侧电流监测3.两相和三相电流检测4.关键元器件选型要求5.布局6.布线7.工具设置8.输入和输出滤波9.注意事项 很多电机驱动器产品系列包括内置了电流感测功能的器件&#xff0…

ArthasGC日志GCeasy详解

Arthas详解 Arthas是阿里巴巴在2018年9月开源的Java诊断工具,支持JDK6,采用命令行交互模式,可以方便定位和诊断线上程序运行问题.Arthas官方文档十分详细.详见:官方文档 Arthas使用场景 Arthas使用 # github下载arthas wget https://alibaba.github.io/arthas/arthas-boot.j…

OpenHarmony实战开发-如何使用Web组件加载页面

页面加载是Web组件的基本功能。根据页面加载数据来源可以分为三种常用场景,包括加载网络页面、加载本地页面、加载HTML格式的富文本数据。 页面加载过程中,若涉及网络资源获取,需要配置ohos.permission.INTERNET网络访问权限。 加载网络页面…

计算机组成结构—高速缓冲存储器(Cache)

目录 一、Cache的基本工作原理 1.Cache工作原理 2.命中率 3.Cache的基本结构 4.Cache的改进 二、Cache和主存之间的映射方式 1.直接映射 2.全相联映射 3.组相联映射 三、Cache中主存块的替换算法 四、Cache的写策略 概为了解决 CPU 和主存之间速度不匹配的问题&#x…

(读书笔记-大模型) LLM Powered Autonomous Agents

目录 智能体系统的概念 规划组件 记忆组件 工具组件 案例研究 智能体系统的概念 在大语言模型(LLM)赋能的自主智能体系统中,LLM 充当了智能体的大脑,其三个关键组件分别如下: 首先是规划,它又分为以下…

成语:势如破竹、迎刃而解;明以前唯一同时入选文庙、武庙的牛人

千古流芳、身后能够进入文庙或武庙,是古人最高的荣誉,也是读书人和武将终极的追求,所谓的青史留名,享受万代祭祀、千秋敬仰,甚至都可以称之为圣人,但历史上,却有两人文武兼备、同时入选了文庙与…

RESTFul风格设计和实战

四、RESTFul风格设计和实战 4.1 RESTFul风格概述 4.1.1 RESTFul风格简介 RESTful(Representational State Transfer)是一种软件架构风格,用于设计网络应用程序和服务之间的通信。它是一种基于标准 HTTP 方法的简单和轻量级的通信协议&#x…

多目标转化依赖DBMTL与AIT区别

DBMTL:通过前序目标输出作为后序目标输入刻画概率转移关系,概率关系的刻画是通过MLP来刻画的;目标之间如果存在内在联系,稀疏目标能利用非稀疏目标中的信息,得到特殊收益; DBMTL与ESMM区别:直接…

Socket学习记录

本次学习Socket的编程开发,该技术在一些通讯软件,比如说微信,QQ等有广泛应用。 网络结构 这些都是计算机网络中的内容,我们在这里简单回顾一下: UDP(User Datagram Protocol):用户数据报协议;TCP(Transmission Contr…

04-18 周四 为LLM_inference项目配置GitHub CI过程记录

04-18 周四 为LLM_inference项目配置GitHub CI过程记录 时间版本修改人描述2024年4月18日10:30:13V0.1宋全恒新建文档 简介和相关文档 04-15 周一 GitHub仓库CI服务器配置过程文档actions-runner 是托管与GitHub上的仓库,下载最新的客户端程序即可。self hosted r…

spring高级篇(十)

1、内嵌tomcat boot框架是默认内嵌tomcat的,不需要手动安装和配置外部的 Servlet 容器。 简单的介绍一下tomcat服务器的构成: Catalina: Catalina 是 Tomcat 的核心组件,负责处理 HTTP 请求、响应以及管理 Servlet 生命周期。它包…

考研数学|基础跟张宇,强化直接1000题还是先做660?

跟宇哥用1000题的,我愿称之为卷王之王!660对基础阶段是绝佳的查漏补缺,必做! 自我介绍一下:我21年一战数学83,总分没过线,22年二战143,逆袭上岸211!660是我的心头好&…

Python测试框架Pytest的参数化详解

上篇博文介绍过,Pytest是目前比较成熟功能齐全的测试框架,使用率肯定也不断攀升。 在实际工作中,许多测试用例都是类似的重复,一个个写最后代码会显得很冗余。这里,我们来了解一下pytest.mark.parametrize装饰器&…

【intro】图卷积神经网络(GCN)-续

本文为【intro】图卷积神经网络(GCN)-CSDN博客后续(因为经验告诉我超过2w字编辑器就会卡……) 第一部分还是进一步再看看GCN 图卷积神经网络GCN_哔哩哔哩_bilibili 回顾 图神经网络的基本原理就是把图中的节点编码映射成一个低…

4.堆_树(汇总版)

目录 1.树概念及结构 1.1树的概念 1.2 树的相关定义 1.3 树的表示 2.二叉树概念及结构 2.1概念 2.2现实中的二叉树 2.3 特殊的二叉树 2.4 二叉树的性质 2.5 二叉树的存储结构 3.二叉树的顺序结构及实现 3.1 二叉树的顺序结构--堆 3.2 堆的实现 3.2.1打印 3.2.2 …

怎么通过Java语言实现远程控制无人售货柜

怎么通过Java语言实现远程控制无人售货柜呢? 本文描述了使用Java语言调用HTTP接口,实现控制无人售货柜,独立控制售货柜、格子柜的柜门。 可选用产品:可根据实际场景需求,选择对应的规格 序号设备名称厂商1智能WiFi控…