C语言自定义类型联合和枚举(25)

文章目录

  • 前言
  • 一、联合体
    • 联合体的声明
    • 联合体的特点
    • 联合体和结构体内存布局对比
    • 联合体的大小计算
    • 联合体的实际使用样例
      • 礼品兑换单
      • 判断当前机器是大端还是小端
  • 二、枚举
    • 枚举的定义
    • 枚举类型的声明
    • 枚举类型的优点
    • 枚举类型的使用
  • 总结


前言

  关于自定义类型除了我们常用的结构体,其实还有联合与枚举也是属于自定义类型
  我们也来学习一下吧!


一、联合体

联合体的声明

联合体是一个或多个成员组成,其中成员可以是不同类型,并且所有成员共用同一块内存空间,所以联合体也称为共用体。联合体声明的关键字是union

//联合体类型的声明
union Un
{// 1 + 4 == 5 吗?char c; // 1int i; // 4
};
int main()
{union Un un;// 联合体的定义sizeof("%zd\n,sizeof(un)"); // 4return 0;
}

联合体的特点

  1. 联合体所有成员共用同一块内存空间,一个联合体变量的大小,至少是最大成员的大小,编译器只为最大的成员分配足够大的空间
  2. 给联合体其中一个成员赋值,其他成员的值也会变化

我们不妨来两段代码来详细感受一下这个性质:

// 代码一
union Un
{char c;int i;
};int main()
{union Un un = {0};// 下⾯输出的结果是⼀样的吗?// 结果:001AF85C//      001AF85C//	    001AF85Cprintf("%p\n", &(un.i));printf("%p\n", &(un.c));printf("%p\n", &un);return 0;
}
// 代码二
union Un
{char c;int i;
};int main()
{union Un un = {0};un.i = 0x11223344;un.c = 0x55;// 结果:11223355printf("%x\n", un.i);return 0;
}

如果用一幅图来说明,那就是如下:
在这里插入图片描述
从代码一输出的结果是相同的,说明联合体中成员变量是一块空间存储
从代码二输出中,第四个字节的内容被修改位55,对联合体中成员赋值,会影响联合体的全部成员,char类型只占用一个字节

还记得前面的内容不,请在十秒内说出这是小端存储还是大端存储?
答案是小端!

联合体和结构体内存布局对比

我们再来比较一下同样成员变量情况下,两种结合方式的区别来加深印象:

struct Su
{char c;int i;
}S;Union Un
{char c;int i;
}un;

在这里插入图片描述

结构体是通过以为空间换取时间设计,而联合体是节省空间

联合体的大小计算

  1. 联合体的大小至少是最大成员的大小
  2. 当最大成员大小(联合体总大小)要对齐到最大对齐数的整数倍

请注意,很多学习资料都说联合体的大小就是最大成员的大小,其实这是不对的!
事实上,联合体也是有内存对齐的,下面我们就来举例说明

#include <stdio.h>union Un1
{char c[5]; int i; 
}; // 最大对齐数位4,最大成员大小为5,对齐到8是最大对齐数的整数倍union Un2
{short c[7];int i;
}; // 最大对齐数位4,最大成员大小为7,对齐到16是最大对齐数的整数倍int main()
{printf("%zd\n", sizeof(union Un1)); // 8printf("%zd\n", sizeof(union Un2)); // 16return 0;
}

联合体的实际使用样例

礼品兑换单

事实上你可以观察下这种做法,把公共属性单独写出来,剩余属于各种商品本身的属性使用联合体处理,其实是在一定程度上节省了内存

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;
};

判断当前机器是大端还是小端

这算是一个巧思,很妙,因为联合体公用一个空间,相当于我是把一个int变量的第一个字节的数据单独提取出来,如果最后返回的是1,那说明低字节位放数据低位,事实也确实是这样,也就说明小端是答案

union un
{char c;int i;
};bool check_sys()
{union un u;u.i = 0x00000001;return u.c;
}int main()
{if (check_sys()){printf("小端\n"); // YES}else printf("大端\n");return 0;
}

二、枚举

枚举的定义

枚举顾名思义就是一一列举,而列举可能的取值是用于定义一组具有离散值的常量,使数据更简洁、方便使用,关枚举的关键字enum

枚举类型的声明

enum Day
{Mon,Tues,Wed,Thur,Fri,Sat,Sun
};enum Sex
{Man,Woman;
}

以上定义的enum Day、enum Sex都是枚举类型,而{ }中枚举类型的可能取值称为枚举常量

枚举类型的优点

我么可以用宏来定义常量,那么这里为什么还要单独设立一种数据类型呢?

  1. 增加代码的可读性和可维护性
  2. 枚举类型有类型检查,更加严谨
  3. 便于调试,预处理阶段会删除#define定义的符号
  4. 一次可以定义多个枚举常量,使用方便
  5. 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用

枚举类型的使用

enum Color
{Red=2,Blue=1
}enum Color clr = Blue;

enum Color clr = 2;
这种写法可以么,毕竟2也是Red的值,应该支持隐式类型转换吧!
嗯…最好不要,C语言可以;Cpp不行,Cpp检查比较严格

那有没有具体一点的应用场景呢?
有,我们稍微回顾一下之前的扫雷
在这里插入图片描述
运用了枚举这个技巧后:

在这里插入图片描述

关于枚举其实我们后来还会有很多的应用场景,这就需要大家自己去慢慢发现了!


总结

  其实中途跳过去写Cpp了,现在再跳回来…
  反复横跳!

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

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

相关文章

Python机器视觉:01- 利用列表和切片操作 - 做一个弧线和图片相交的mask区域

前言&#xff1a; Python的列表处理&#xff0c;在机器视觉中经常被用到&#xff0c;这里结合基本的概念机器视觉实践案例&#xff0c;成文如下&#xff1a; 本身将实现一个&#xff0c;弧线的mask填充&#xff1a;这个mask是我的一个天文项目的应用&#xff0c;目的在于将月…

实现Xshell与虚拟机中Linux服务器的连接(附常见错误解决)

前言 Xshell是一个强大的安全终端模拟软件&#xff0c;它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议。Xshell 通过互联网到远程主机的安全连接以及它创新性的设计和特色帮助用户在复杂的网络环境中享受他们的工作。 本文将介绍Xshell与虚拟机中Linux服务器连接…

Web APIs——Dom获取属性操作

1.变量声明 1.1以后声明变量我们优先使用哪个&#xff1f; const 有了变量先给const&#xff0c;如果发现它后面是要被修改的&#xff0c;再改为let 1.2 为什么const声明的对象可以修改里面的属性&#xff1f; 因为对象是引用类型&#xff0c;里面存储的是地址&#x…

自动驾驶核心技术:感知融合、规划决策、控制执行

1、前言 简单来说&#xff0c;实现自动驾驶需要解决三个核心问题&#xff1a;“我在哪?我要去哪?我该如何去?”能完整解决这三个问题就是真正的自动驾驶。 目前&#xff0c;自动驾驶汽车关键技术主要包括环境感知、精准定位、决策与规划、控制与执行、高精地图与车联网V2X以…

大学生就业招聘:Spring Boot系统的设计与实践

5系统详细实现 5.1 用户模块的实现 5.1.1 求职信息管理 大学生就业招聘系统的用户可以管理自己的求职信息&#xff0c;可以对自己的求职信息添加修改删除操作。具体界面的展示如图5.1所示。 图5.1 求职信息管理界面 5.1.2 首页 用户登录可以在首页看到招聘信息展示也一些求职…

Flet介绍:平替PyQt的好用跨平台Python UI框架

随着Python在各个领域的广泛应用&#xff0c;特别是在数据科学和Web开发领域&#xff0c;对于一个简单易用且功能强大的用户界面&#xff08;UI&#xff09;开发工具的需求日益增长。传统的Python GUI库如Tkinter、PyQt虽然功能强大&#xff0c;但在易用性和现代感方面略显不足…

算法篇1:双指针思想的运用(1)--C++

一.算法解析 双指针&#xff0c;顾名思义就是两个指针&#xff0c;常见的算法中&#xff0c;我们可以看到两种&#xff1a; 1.对撞指针&#xff1a;一般用于顺序结构&#xff0c;也称为左右指针。 对撞指针从两端向中间移动。一个指针从最左端开始&#xff0c;另一个从最右端…

比较搜索难度曲线5s1-4和4s1

在行列可自由变换的条件下&#xff0c;平面上的5点结构只有34个,4点结构有16个 (A,B)---6*n*2---(0,1)(1,0) 让B全是0。当收敛误差为7e-4&#xff0c;收敛199次取迭代次数平均值。让隐藏层节点数n分别为10&#xff0c;15&#xff0c;20&#xff0c;25&#xff0c;30&#xff…

C(十四)while、for、do-while循环综合(一)

uu们&#xff0c;小弟我本科在读&#xff0c;文章我会一直坚持更新下去&#xff0c;包括但不限于C初阶、C进阶、数据结构、C、Linux、MySQL、项目、QT开发、各种算法&#xff08;之后会持续更新&#xff09;&#xff0c;并且站在小白的视角尽可能通俗易懂地把这些写出来&#x…

【Android】获取备案所需的公钥以及签名MD5值

目录 重要前提 获取签名MD5值 获取公钥 重要前提 生成jks文件以及gradle配置应用该文件。具体步骤请参考我这篇文章&#xff1a;【Android】配置Gradle打包apk的环境_generate signed bundle or apk-CSDN博客 你只需要从头看到该文章的配置build.gradle&#xff08;app&…

25重庆长安深蓝控制器开发面试经验 深蓝最常见面试问题总结

【面试经历】 秋招气氛组选手的第一场面试,9.17网申,9.24电话约面,9.26线上面试。问得很细,全长约1个小时 1. 自我介绍、项目介绍 2.项目细节,遇到了哪些困难;有没有PCB设计经验DC-DC芯片选型,电源噪声的原因、怎么消除、 3.画BUCK和BOOST拓扑图,讲原理 4.了解MCU的主…

西电25考研 VS 24考研专业课大纲变动汇总

01专业课变动 西安电子科技大学专业课学长看到953网络安全基础综合变为 893网络安全基础综合&#xff0c;这是因为工科要求都必须是8开头的专业课&#xff0c;里面参考课本还是没变的&#xff0c;无非就是变了一个名字 对于其他变动专业课也是同理的 02专业课考纲内容变化 对于…

uniapp中检测应用更新的两种方式-升级中心之uni-upgrade-center-app

uniapp一个很是用的功能&#xff0c;就是在我们发布新版本的app后&#xff0c;需要提示用户进行app更新&#xff0c;并告知用户我们新版的app更新信息&#xff0c;以使得用户能及时使用上我们新开发的功能&#xff0c;提升用户的实用度和粘性。注意:这个功能只能在app端使用 效…

创建django项目时,不同的编译类型有什么区别

这里主要提及的是 project venv 和 Custom environment 两种类型。 简单来说&#xff0c;project venv 是Python 3.3及以上版本中自带的虚拟环境管理工具&#xff0c;使用venv可以为每个项目创建一个独立的环境&#xff1a;python -m venv myprojectenv &#xff08;项目名后e…

【3D目标检测】激光雷达和相机联合标定(一)——ROS同步解包

ROS同步解包 引言1 鱼香ROS一键安装ros-docker脚本&#xff1a;2 指定目录映射3 数据解包3.1 解包脚本3.2 依赖安装3.3 运行脚本&#xff0c;解包 引言 总结步骤如下&#xff1a; 采集同步数据&#xff1a;ROS录制&#xff08;推荐&#xff09;&#xff0c;或者代码同步触发采…

如何使用工具删除 iPhone 上的图片背景

在 iPhone 上删除背景图像变得简单易行。感谢最近 iOS 更新中引入的新功能。如今&#xff0c;iOS 用户现在可以毫不费力地删除背景&#xff0c;而无需复杂的应用程序。在这篇文章中&#xff0c;您将学习如何使用各种方法去除 iPhone 上的背景。这可确保您可以选择最适合您偏好的…

通信工程学习:什么是IP网际协议

IP&#xff1a;网际协议 IP网际协议&#xff08;Internet Protocol&#xff0c;简称IP&#xff09;是整个TCP/IP协议栈中的核心协议之一&#xff0c;它负责在网络中传送数据包&#xff0c;并提供寻址和路由功能。以下是对IP网际协议的详细解释&#xff1a; 一、对IP网际协议的…

哈尔滨自闭症学校寄宿条件与优势解析

自闭症儿童的希望之光&#xff1a;广州星贝育园寄宿制学校深度解析 在当今社会&#xff0c;自闭症儿童作为一群需要特别关注和照顾的群体&#xff0c;其教育与康复问题日益受到社会各界的重视。自闭症儿童不仅需要专业的康复训练&#xff0c;还需要一个稳定、温馨且充满爱的环…

Java:插入排序

目录 排序的概念 插入排序 直接插入排序 哈希排序 排序的概念 排序&#xff1a;所谓的排序&#xff0c;就是使一串记录&#xff0c;按照某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个…

【设计模式-解释模式】

定义 解释器模式是一种行为设计模式&#xff0c;用于定义一种语言的文法&#xff0c;并提供一个解释器来处理该语言的句子。它通过为每个语法规则定义一个类&#xff0c;使得可以将复杂的表达式逐步解析和求值。这种模式适用于需要解析和执行语法规则的场景。 UML图 组成角色…