巧用联合与枚举:解锁自定义类型的无限潜力

嘿嘿,家人们,今天咱们来详细剖析C语言中的联合与枚举,好啦,废话不多讲,开干!


目录

1.:联合体

1.1:联合体类型的声明

1.1.1:代码1

1.1.2:代码2(计算机联合体的大小)

1.1.3:代码3

1.2:联合体的特点

1.2.1:代码1 

1.2.2:代码2

1.3:相同成员的结构体与联合体进行对比

1.3.1:代码1(结构体)

1.3.2:代码2(联合体)

 ​编辑

1.4:联合体大小的计算

1.4.1:代码1

1.4.2:代码2

1.4.3:联合体的优点

1.4.3.1:结构体描述

1.4.3.2:使用联合体描述 

1.5:联合的一个练习

1.5.1:(通过拿数值1的最低位并且按位与1)

1.5.2:代码2(通过联合体)

2:枚举类型

2.1:枚举类型的声明

2.1.1:代码1 

2.1.2:代码2(给枚举类型赋初值)

2.2:枚举类型的优点

2.3:枚举类型的使用


1.:联合体

1.1:联合体类型的声明

联合体像结构体一样,联合体也是由一个或多个成员构成,这些成员可以是不同的类型.但是编译器只能为最大的成员分配足够的内存空间.联合体的特点是所有成员共用一块内存空间,所以联合体也叫:共同体.

1.1.1:代码1

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>union Un
{char _c;int _i;
};int main()
{//联合变量的定义union Un  u1 = {'c'};return 0;
}

1.1.2:代码2(计算机联合体的大小)

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>union Un
{char _c;int _i;
};int main()
{//联合变量的定义union Un  u1 = {'c'};printf("%d\n", sizeof(u1));return 0;
}

在结构体那一章节,博主讲到了,结构体的大小要遵循内存对齐的规则,那么联合体要不要遵从内存对齐的规则,如果遵从的话,上面的代码计算出来的结果是8(原因博主不过多解释哈,忘了滴uu可以去去博主那篇结构体的博客).

1.1.3:代码3

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>union Un
{char _c;double _i;
};int main()
{//联合变量的定义union Un  u1 = {'c'};printf("%d\n", sizeof(u1));return 0;
}

上面的两段代码输出结果是4与8,那么为什么是4与8呢?这里就要讲到联合体的特点了

1.2:联合体的特点

联合体的成员是共用一块内存空间的,这样一个联合体变量的大小,至少是最大成员的大(因为联合体至少得有能力保存最大的那个成员),而上面的代码中最大成员int类型,因此结果为4

1.2.1:代码1 

#include <stdio.h>
int main()union Un
{char _c;int _i;
};
{union Un u1 = {0};printf("&u1._c == %p\n",&u1._c);printf("&u1._i == %p\n",&u1._i);printf("&u1 == %p\n",&u1);return 0;    
}

上面的代码输出的三个均是一模一样,那么我们仔细便可以画图u1的内存分布图.

1.2.2:代码2

#include <stdio.h>
int main()union Un
{char _c;int _i;
};
{union Un u1 = { 0 };u1._i = 0x11223344;u1._c = 0x55;printf("%x\n", u1._i);return 0;
}

通过上面的代码我们可以分析出,将变量i的第4个字节改成了55,那么因此我们可以画出其对应的内存分布图.

1.3:相同成员的结构体与联合体进行对比

我们再来对比一下,相同成员的结构体与联合体的内存布局情况.

1.3.1:代码1(结构体)

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>struct S
{char _c;int _i;
};int main()
{struct S s1 ={'c'};return 0;
}

1.3.2:代码2(联合体)

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>union Un
{char _c;int _i;
};int main()
{union Un u = {0};return 0;
}

 

1.4:联合体大小的计算

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

1.4.1:代码1

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>union Un1
{char c[5];int _i;
};int main()
{printf("Un1的大小为:> %zd\n", sizeof(union Un1));return 0;
}

1.4.2:代码2


#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>union Un2
{short s[5];int _i;
};int main()
{printf("Un2的大小为:> %zd\n", sizeof(union Un2));return 0;
}

1.4.3:联合体的优点

使用联合体是可以节省空间的,例如:

我们要搞一个活动,要上线一个礼品兑换单,礼品兑换单中有三种商品 图书、杯子、衬衫 .
每一种商品都有: 库存量、价格、商品类型和商品类型相关的其他信息.
  • 图书:设计、书名、作者、页数.
  • 杯子:设计、品牌.
  • 衬衫:设计、颜色、尺寸、品牌

如果我们使用结构体来描述的话,将会是如下代码 

1.4.3.1:结构体描述
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
struct Gift_List
{//库存量int _Inventory;//价格double _Price;//商品类型int Type_Of_Merchandise;//书的特殊属性char _Name[20];//书的作者char _Author[20];//书的页数int _Pages;//衬衫的颜色char _Color[20];//衬衫的尺寸int _Sizes;//三者的设计char _Desigin[20];//三者的品牌char _Brand[20];
};int main()
{printf("%zd\n", sizeof(struct Gift_List));return 0;
}

  • 上面的结构其实设计的很简单,用起来也方便,但是结构的设计中包含了所有礼品的各种属性,这样使得结构体的大小就会偏大,比较浪费内存.因为对于礼品兑换单中的商品来说,只有部分属性信息是常用的.
  • 比如:商品是图书,就不需要_Design、_Color、_Sizes.
  • 所以可以把公共属性单独写出来,剩余属于各种商品本身的属性使用联合体保存起来,这样就可以节省所需的内存空间,一定程度上节省了内存。
1.4.3.2:使用联合体描述 
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
struct Gift_List
{//库存量int _Inventory;//价格double _Price;//商品类型int Type_Of_Merchandise;//三者的设计char _Desigin[20];//三者的品牌char _Brand[20];union{struct Book{//书的特殊属性char _Name[20];//书的作者char _Author[20];//书的页数int _Pages;};struct Shirt{//衬衫的颜色char _Color[20];//衬衫的尺寸int _Sizes;};};
};int main()
{printf("Gift_List(嵌套联合体):>%zd\n", sizeof(struct Gift_List));return 0;
}

通过对比二者,我们可以清晰地发现,使用联合体可以大大地减少内存空间的占用.

1.5:联合的一个练习

在数据类型在内存的存储方式那篇博客中,我们讲到了大小端的概念.

  • 大端:地址低位存放着数值高位,地址高位存放着数值低位.
  • 小端:地址低位存放着数值低位,地址高位存放着数值高位.

在那里我们通过拿到数值1的最低位并且按位与1来判断来判断程序的大小端

1.5.1:(通过拿数值1的最低位并且按位与1)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int check_sys()
{int value = 1;return (*(char*)&value & 1);
}
int main()
{int result = check_sys();if(result == 0){printf("大端存储\n");}else{printf("小端存储\n");}}

 

 

1.5.2:代码2(通过联合体)

除了上面的方式,我们也可以通过联合体的方式来进行求解,联合体的特点是

  • 联合体的成员是共用一块内存空间的,这样一个联合体变量的大小,至少是最大成员的大(因为联合体至少得有能力保存最大的那个成员).
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int Check_sys()
{union{int _i;char _c;}un;un._i = 1;return un._c;
}int main()
{int result = Check_sys();if (result == 0){printf("大端存储\n");}else{printf("小端存储\n");}}

2:枚举类型

2.1:枚举类型的声明

枚举顾名思义就是⼀⼀列举, 把可能的取值⼀⼀列举, 比如我们现实生活中:
  • ⼀周的星期一到星期日是有限的7天,可以⼀⼀列举.
  • 性别有:男、女、保密,也可以⼀⼀列举.
  • 月份有12个月,也可以一一列举.
  • 三原色,也是可以意义列举.

2.1.1:代码1 

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>//星期
enum Day
{Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
};//性别
enum Sex
{Boy,Girl,Other
};//颜色
enum Color
{Red,Green,Blue
};int main()
{printf("Day:Monday> %d\n", Monday);printf("Sex:Girl> %d\n", Girl);printf("Color:Blue> %d\n", Blue);return 0;
}
  •  以上定义的 enum Day,enum Sex,enum Color 都是枚举类型.
  • {}中的内容以,为分隔符,枚举类型的可以取值,也叫枚举常量.
  • 这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值.

2.1.2:代码2(给枚举类型赋初值)

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>//星期
enum Day
{Monday = 1,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
};//性别
enum Sex
{Boy = 5,Girl,Other
};//颜色
enum Color
{Red,Green,Blue = 2
};int main()
{printf("Day:Monday> %d\n", Monday);printf("Sex:Girl> %d\n", Girl);printf("Color:Blue> %d\n", Blue);return 0;
}

2.2:枚举类型的优点

 我们可以使用#define定义常量,但是为什么非要使用枚举呢

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

2.3:枚举类型的使用

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>//性别
enum Sex
{Boy = 5,Girl,Other
};int main()
{enum Sex Tom = Boy;printf("%d\n", Tom);return 0;
}

那是否可以拿整数给枚举变量赋值呢?在C语言中是可以的,但是在C++是不行的,C++的类型检查比较较严格。
好啦,uu们,C语言的联合与枚举这部分滴详细内容博主就讲到这里啦,如果uu们觉得博主讲的不错的话,请动动你们滴小手给博主点点赞,你们滴鼓励将成为博主源源不断滴动力,同时也欢迎大家来指正博主滴错误.

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

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

相关文章

【SA8155P】AIS Camera相关内容的简单介绍

高通车载相机模块(AIS,Automotive lmage System)是专门针对车载系统特性而设计的一套车载视觉架构,可用于AVM、RVC、DMS等常见车载视频应用开发。车载Camera系统的图像大部分是给自动驾驶等使用,更多考虑的是远距离传输、多摄像头图像处理等场景。 本文仅对AIS Camera相关…

国庆头像制作教程,这几种方法轻松制作国庆头像

随着国庆佳节的临近&#xff0c;朋友圈里是不是已经开始弥漫着浓浓的节日气氛&#xff1f;想要让你的头像也加入这场盛宴&#xff0c;成为最吸睛的存在吗&#xff1f;别急&#xff0c;今天就为你揭秘4款超实用的头像制作神器&#xff0c;能够让你的头像显现出浓郁的国庆节气氛&…

竹云董事长董宁主持2024深商千人中秋晚会

9月13日&#xff0c;由深商会主办“湾区升明月&#xff0c;深商共此时”2024深商中秋千人晚会在洲际酒店隆重举行&#xff0c;TCL 集团、农商银行、资本运营集团、泸州老窖、中集车辆、三诺集团、雷曼光电、置富控股、顺络电子、北科生物、霖峰投资、中国南玻集团、兆驰股份、山…

如何衡量品牌在社媒平台的投放效果?

企业去评估在社媒上的投放效果&#xff0c;不仅仅是看投放内容数据、最终销量如何&#xff0c;要从数据去分析更深纬度的效果。比如对于整体品牌声量的提升&#xff0c;品牌行业占有率的上涨&#xff0c;品牌口碑的优化等等。我们可以用声量通对企业多平台上整体的品牌声量情况…

【数据结构-差分】力扣1589. 所有排列中的最大和

有一个整数数组 nums &#xff0c;和一个查询数组 requests &#xff0c;其中 requests[i] [starti, endi] 。第 i 个查询求 nums[starti] nums[starti 1] … nums[endi - 1] nums[endi] 的结果 &#xff0c;starti 和 endi 数组索引都是 从 0 开始 的。 你可以任意排列…

迁移学习+多模态融合,小白轻松发一区!创新性拉满!

多模态研究如今愈发火热&#xff0c;已成为各大顶级会议的投稿热门。今天&#xff0c;我为大家提供一个多模态的创新思路&#xff1a;迁移学习与多模态融合。 迁移学习多模态融合方向的优势 1.提升模型性能&#xff1a;综合更多维度优势&#xff0c;跨模态互补 2.快速适应新…

【Verilog学习日常】—牛客网刷题—Verilog快速入门—VL17

用3-8译码器实现全减器 描述 请使用3-8译码器和必要的逻辑门实现全减器&#xff0c;全减器接口图如下&#xff0c;A是被减数&#xff0c;B是减数&#xff0c;Ci是来自低位的借位&#xff0c;D是差&#xff0c;Co是向高位的借位。 3-8译码器代码如下&#xff0c;可将参考代码添…

基于Java的房地产在线营销管理系统研究与实现

目录 前言 功能设计 系统实现 获取源码 博主主页&#xff1a;百成Java 往期系列&#xff1a;Spring Boot、SSM、JavaWeb、python、小程序 前言 随着信息技术的迅猛发展&#xff0c;互联网已经渗透到我们生活的方方面面&#xff0c;为各行各业带来了前所未有的变革。房地产…

Fiddler的下载(带安装包和安装配置教程)

1.安装包下载 1.1官网下载 https://www.telerik.com/download/fiddler 填上相应的信息即可 1.2安装包下载 安装包地址 提取码&#xff1a;uq2n 2.安装 选择路径 3.使用 3.1配置支持抓https的包 配置成功!!&#xff01;如果还是抓不到 重启一下&#xff01; 3.2抓包 双…

Flux【真人模型】:高p高糊反向真实质感!网图风格的Lora模型,超逼真的AI美女大模型!

大家好&#xff0c;我是画画的小强 今天和大家分享一款基于Flux训练的网图风格的lora模型&#xff1a;墨幽-F.1-Lora-网图&#xff0c;该Lora模型由墨幽团队出品&#xff0c;旨在生成高p高糊的反向真实质感图片&#xff0c;而非真实摄影图片。不过&#xff0c;在自己出图过程中…

车间生产电子看板系统在工厂中的高效运用

在当今竞争激烈的制造业领域&#xff0c;工厂不断寻求提高生产效率、优化管理流程的方法。车间生产电子看板系统的出现&#xff0c;为工厂带来了全新的管理模式和高效的生产方式。 车间生产电子看板系统通过数字化的显示方式&#xff0c;将生产进度、任务安排、质量状况、设备运…

已知曲线满足正余弦函数,根据其峰值,还原出整条曲线

&#x1f3c6;本文收录于《全栈Bug调优(实战版)》专栏&#xff0c;主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&am…

C++和OpenGL实现3D游戏编程【连载9】——纹理的镂空显示

1、本节实现的内容 前面的课程中,我们学会了加载纹理并显示纹理图案,但是纹理的图案都是长方形的图片,图片就会有白色或黑色背景,那么在游戏设计过程中,我们经常不需要显示图片的背景部分,那么这节课我们就来讨论一下如何实现剔除白色或黑色背景后的镂空图像,下图就是将…

百元头戴式耳机都有哪些?五大精品独家推荐!

在当今市场中&#xff0c;耳机已经成为我们生活中不可或缺的电子设备之一。而对于追求性价比的朋友来说&#xff0c;如何在百元价位内挑选到一款音质出色、舒适耐用的头戴式耳机&#xff0c;无疑是一大难题。百元头戴式耳机都有哪些&#xff1f;为了帮助大家在琳琅满目的产品中…

图结构的稀疏变换器:EXPHORMER框架

人工智能咨询培训老师叶梓 转载标明出处 尽管图变换器在理论上具有强大的表达能力&#xff0c;但是它们在扩展到大型图时面临着巨大的挑战。这一挑战主要源于其全局注意力机制的二次方时间复杂度&#xff0c;这不仅限制了其在大型图数据集上的应用&#xff0c;也使得其在内存和…

Docker 里面按照ifconfig

1. 进入Docker 容器内部 docker exec -it xxx bash2. 安装 net-tools iputils-ping apt-get update && apt-get install -y net-tools apt-get update && apt-get install -y iputils-ping 3. 执行ifconfig 执行ping

Nacos注册中心(Nacos安装,快速入门,多级存储,负载均衡,环境隔离,配置管理,热更新,集群搭建,nginx反向代理)

Nacos注册中心 1. Nacos安装 (windows) 1.1 官网下载 网址:https://github.com/alibaba/nacos/releases/tag/1.4.1 这里下载nacos1.4.1的Windows版本为例1.2 解压到本地 注: 解压到非中文目录 nacos默认端口号:8848,可在配置文件properties中修改1.3 启动nacos 在G:\Sp…

鸿蒙OpenHarmony【轻量系统内核通信机制(互斥锁)】子系统开发

互斥锁 基本概念 互斥锁又称互斥型信号量&#xff0c;是一种特殊的二值性信号量&#xff0c;用于实现对共享资源的独占式处理。 任意时刻互斥锁的状态只有两种&#xff0c;开锁或闭锁。当任务持有互斥锁时&#xff0c;该互斥锁处于闭锁状态&#xff0c;这个任务获得该互斥锁…

了解CRM销售自动化:类型、优势、策略和工具

对于疲于手动追踪潜在客户和管理客户关系的销售人员而言&#xff0c;销售自动化提供了一种有效的解决方案&#xff0c;它能够简化这些繁琐的任务&#xff0c;从而使销售团队能够专注于其核心优势——销售本身。 销售自动化是什么&#xff1f; 销售自动化是指运用软件工具自动…

高德地图JS API AMap.MouseTool绘制

fang &#x1f916; 作者简介&#xff1a;水煮白菜王 &#xff0c;一位资深前端劝退师 &#x1f47b; &#x1f440; 文章专栏&#xff1a; 高德AMap专栏 &#xff0c;记录一下平时在博客写作中&#xff0c;总结出的一些开发技巧✍。 感谢支持&#x1f495;&#x1f495;&#…