当前位置: 首页 > news >正文

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了,现在再跳回来…
  反复横跳!

相关文章:

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

文章目录 前言一、联合体联合体的声明联合体的特点联合体和结构体内存布局对比联合体的大小计算联合体的实际使用样例礼品兑换单判断当前机器是大端还是小端 二、枚举枚举的定义枚举类型的声明枚举类型的优点枚举类型的使用 总结 前言 关于自定义类型除了我们常用的结构体&…...

Kafka 的重平衡问题详解及解决方案

引言 Kafka 是目前非常流行的分布式消息队列系统&#xff0c;被广泛应用于流数据处理、日志分析、事件驱动架构等场景中。Kafka 的高吞吐量和分布式架构在应对海量数据传输方面具有显著优势。然而&#xff0c;Kafka 在处理消费者组时&#xff0c;会面临一个核心问题——重平衡…...

比较GPT4比较正确的回复的提问方式和比较失败的提问方式之间的区别?

比较GPT4比较正确的回复的提问方式和比较失败的提问方式之间的区别&#xff1f; 正确提问失败提问异同 正确提问 ####一堆python源码############# 这里如何根据数据是新建还是更新来调用不同的save方法&#xff1f; 失败提问 ####一堆python源码############# 为什么在修改…...

jmeter学习(1)线程组与发送请求

1、线程组 执行顺序 &#xff1a;setUp线程组 > 线程组 > tearDown线程组 2、 发送请求 可以发送http、java、dubbo 请求等 下面讲解发送http 1&#xff09;Http请求默认值 作用范围是该线程组下的所有HTTP请求&#xff0c;如果http请求设置的与默认值冲突&#xff0…...

【小技巧】mysql 判断表字段是否存在 删除字段 sql脚本

MySQL 判断表字段是否存在 删除字段 sql脚本 下面是一个包含插入和更新操作的流程&#xff1a; -- 先尝试插入数据 INSERT IGNORE INTO user_info (last_name, first_name) VALUES (x, y);-- 如果插入成功&#xff0c;ROW_COUNT() 返回 1&#xff0c;否则返回 0 IF ROW_COUNT…...

低代码革命:重塑工业互联网的未来版图

在数字化转型的浪潮中&#xff0c;低代码应用正以前所未有的速度席卷各行各业&#xff0c;尤其是在工业互联网领域&#xff0c;它正悄然改变着企业的技术架构和业务模式。本文将深入探讨低代码应用如何成为工业互联网的技术趋势&#xff0c;并展望其未来的辉煌前景&#xff0c;…...

KNN算法

KNN算法 一 KNN算法介绍二 KNN算法API2.1 KNeighborsClassifier 分类算法2.2 KNeighborsRegressor 回归算法 三 两个经典案例3.1 鸢尾花案例3.2 手写数字识别案例 一 KNN算法介绍 K-近邻算法&#xff08;K Nearest Neighbor&#xff0c;简称KNN&#xff09;.比如根据你的“邻居…...

TS 中类型的继承

在 TypeScript&#xff08;TS&#xff09;中&#xff0c;类型的继承通常通过接口&#xff08;Interfaces&#xff09;和类&#xff08;Classes&#xff09;来实现。接口提供了一种定义对象形状的方式&#xff0c;而类则提供了一种创建对象实例的方式。以下是如何在 TypeScript …...

在VS code 中部署C#和avalonia开发环境

要在 Mac 的 VS Code 中配置 C# 和 Avalonia 的开发环境&#xff0c;您可以按照以下步骤进行&#xff1a; 1. 安装 .NET SDK 下载 .NET SDK&#xff1a; 访问 .NET 下载页面。选择适用于 macOS 的最新稳定版本的 .NET SDK&#xff0c;并下载安装程序。安装 .NET SDK&#xff1…...

Windows删除service服务

Windows删除service服务 找到命令提示符&#xff1a; 右键&#xff0c;以管理员身份运行 输入&#xff1a; sc delete 服务名 Windows根据TCP端口号查找进程PID再kill进程_windows tcpkill-CSDN博客文章浏览阅读5.3k次&#xff0c;点赞42次&#xff0c;收藏104次。Windows根据…...

【数据结构】---图

图 前言 本篇作为图的基础概念篇&#xff0c; 了解图的离散数学定义&#xff0c; 图的分类&#xff0c; 图模型解决的问题&#xff08;图的应用&#xff09;&#xff0c; 图的相关算法&#xff08;仅仅介绍&#xff0c;具体不在此篇展开&#xff09;。 学习基本路线&#xff…...

《 C++ 修炼全景指南:十四 》大数据杀手锏:揭秘 C++ 中 BitSet 与 BloomFilter 的神奇性能!

本篇博客深入探讨了 C 中的两种重要数据结构——BitSet 和 BloomFilter。我们首先介绍了它们的基本概念和使用场景&#xff0c;然后详细分析了它们的实现方法&#xff0c;包括高效接口设计和性能优化策略。接着&#xff0c;我们通过对比这两种数据结构的性能&#xff0c;探讨了…...

相机基础概念

景深&#xff1a; 景深的定义 DOF:depth of filed 是指在摄影机镜头或其他成像器前沿能够取得清晰图像的成像所测定的被摄物体前后距离范围。光圈、镜头、及焦平面到拍摄物的距离是影响景深的重要因素。定义3&#xff1a;在镜头前方&#xff08;焦点的前、后&#xff09;有一…...

【python】追加写入excel

输出文件运行前&#xff08;有两张表&#xff0c;“表1”和“Sheet1”&#xff09;&#xff1a; 目录 一&#xff1a;写入单表&#xff08;删除所有旧工作表&#xff0c;写入新表&#xff09;二&#xff1a;写入多表&#xff08;删除所有旧工作表&#xff0c;写入新表&#x…...

继承实现单例模式的探索(二)

前言 本篇文章继续探索通过继承实现单例模式的可行方案&#xff0c;这次的方案将采用反射机制隐式创建派生类实例&#xff0c;示例代码为C#。 代码 v1.0 using System.Reflection;/// <summary> /// 单例模式基类 /// </summary> /// <typeparam name"T&…...

设计模式-访问者模式

访问者模式&#xff08;Visitor&#xff09;:表示一个作用于某对象结构中的各元素的操作&#xff0c;使得在不改变个元素的类的前提下定义作用于这些元素的新操作。...

国创——基于Unity3D和MediaPipe构建虚拟人物驱动系统

以下是一个基于Unity3D和MediaPipe构建虚拟人物驱动系统的基本概念和简化的Python示例代码框架。请注意&#xff0c;这只是一个基础示例&#xff0c;实际应用中可能需要更多的完善和调整。 一、整体概念 1. MediaPipe - MediaPipe是一个用于构建多模态&#xff08;例如视频、…...

环境可靠性

一、基础知识 1.1 可靠性定义 可靠性是指产品在规定的条件下、在规定的时间内完成规定的功能的能力。 可靠性的三大要素&#xff1a;耐久性、可维修性、设计可靠性 耐久性&#xff1a;指的是产品能够持续使用而不会故障的特性&#xff0c;或者说是产品的使用寿命。 可维修性&a…...

Chromium 设置页面打开系统代理源码分析c++

1、前端页面调用showProxySettings() {chrome.send("showProxySettings")} 2、c 响应代码如下 chrome\browser\ui\webui\settings\system_handler.ccvoid SystemHandler::RegisterMessages() {web_ui()->RegisterMessageCallback("showProxySettings",b…...

信号检测理论(Signal Detection Theory, SDT)

信号检测理论&#xff08;Signal Detection Theory, SDT&#xff09;模拟是一种实验设计&#xff0c;用于研究和理解在存在噪声或不确定性的情况下如何做出决策。在心理学、认知科学、工程学和许多其他领域&#xff0c;信号检测理论都非常重要。 一、基础概念&#xff1a; 在信…...

Flink源码剖析

写在前面 最近一段时间都没有更新博客了&#xff0c;原因有点离谱&#xff0c;在实现flink的两阶段提交的时候&#xff0c;每次执行自定义的notifyCheckpointComplete时候&#xff0c;好像就会停止消费数据&#xff0c;完成notifyComplete后再消费数据&#xff1b;基于上述原因…...

[Python学习日记-39] 闭包是个什么东西?

[Python学习日记-39] 闭包是个什么东西&#xff1f; 简介 闭包现象 闭包意义与作用 简介 在前面讲函数和作用域的时候应该提到过&#xff0c;当函数运行结束后会由 Python 解释器自带的垃圾回收机制回收函数内作用域已经废弃掉的变量&#xff0c;但是在 Python 当中还有一种…...

XSLT 实例:掌握 XML 转换的艺术

XSLT 实例&#xff1a;掌握 XML 转换的艺术 引言 XSLT&#xff08;可扩展样式表语言转换&#xff09;是一种强大的工具&#xff0c;用于将 XML&#xff08;可扩展标记语言&#xff09;文档转换为其他格式&#xff0c;如 HTML、PDF 或纯文本。在本文中&#xff0c;我们将通过一…...

【C++】第一节:C++入门

1、C关键字 2、命名空间 在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称将都存在于全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化&#xff0c;以避免命名冲突或名字污染&am…...

CSP-S 2021 T1廊桥分配

CSP-S 2021 T1廊桥分配 枚举分配给国内航班和国外航班的廊桥数量&#xff0c;若分配给国内机场 i i i个廊桥&#xff0c;则国外机场就有 n − i n-i n−i个廊桥&#xff0c;在此基础上分别判断两边各能通过多少飞机。用一个小根堆存储飞机离开的时间&#xff0c;枚举到一个飞机…...

项目配置说明

文章目录 一、下载 vscode 并安装相应扩展1.1 下载 vscode1.2 安装扩展 二、git 项目三、git 提交流程3.1 确定要提交的代码 四、git 拉新流程 一、下载 vscode 并安装相应扩展 1.1 下载 vscode vscode 我已经发群里了&#xff0c;或者自己去官网下载也行 1.2 安装扩展 打开…...

linux网络编程实战

前言 之前找工作的之后写了一些网络编程的笔记和代码&#xff0c;然后现在放到csdn上保存一下。有几个版本的&#xff0c;看看就好。就是简单的实现一下服务端和客户端之间的交互的&#xff0c;还没有我之前上linux编程课写的代码复杂。 哦对了&#xff0c;这个网络编程的代码对…...

网络基础 【HTTP】

&#x1f493;博主CSDN主页:麻辣韭菜&#x1f493;   ⏩专栏分类&#xff1a;Linux初窥门径⏪   &#x1f69a;代码仓库:Linux代码练习&#x1f69a; &#x1f4bb;操作环境&#xff1a; CentOS 7.6 华为云远程服务器 &#x1f339;关注我&#x1faf5;带你学习更多Linux知识…...

[Linux#61][UDP] port | netstat | udp缓冲区 | stm32

目录 0. 预备知识 1. 端口号的划分范围 2. 认识知名端口号 3. netstat 命令 4. pidof 命令 二.UDP 0.协议的学习思路 1. UDP 协议报文格式 报头与端口映射&#xff1a; 2. UDP 的特点 面向数据报&#xff1a; 3. UDP 的缓冲区 4. UDP 使用注意事项 5. 基于 UDP 的…...

定义类方法的错误总结

struct Renderer {vector<function<void(vector<string>)>> fileDropListeners;// 定义一个方法&#xff0c;它是将一个函数作为输入&#xff0c;callback是形参void print(function<void(float)> callback_func);void onFileDrop(function<void(ve…...