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

【c语言进阶】枚举与联合体的基本知识大全

在这里插入图片描述

🚀write in front🚀
📜所属专栏:c语言学习
🛰️博客主页:睿睿的博客主页
🛰️代码仓库:🎉VS2022_C语言仓库
🎡您的点赞、关注、收藏、评论,是对我最大的激励和支持!!!
关注我,关注我,关注我你们将会看到更多的优质内容!!

在这里插入图片描述

文章目录

  • 🫠前言🫠
  • 😃一:枚举😃
    • 1.1:枚举类型的定义:
    • 1.2:枚举的取值:
    • 1.3:枚举的优点:
    • 1.4:枚举的大小:
    • 1.5枚举的使用:
  • 😊二:联合(共用体)😊
    • 2.1:联合类型的定义:
    • 2.2:联合类型的特点:
    • 2.3:联合大小的计算:
    • 2.4:判断当前机器的大小端:
  • 😐总结:😐

🫠前言🫠

  前面我们完整的学完了结构体的相关知识点,而在我们的自定义类型中还有另外两个有趣又实用的成员—— 枚举联合 。通过灵活合理的使用它们就能使它们变成我们学习与工作中的好帮手,而本文就将带领大家在最短的时间内学会这两个好帮手的相关知识。

😃一:枚举😃

   枚举 是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。是一个被命名的整型常数的集合。简单来说就将某种特定类型的对象一一进行列举,一一列举特定类型可能的取值
  说白了,枚举常量属于枚举类型值是整形

1.1:枚举类型的定义:

   枚举类型的定义形式如下:

#include<stdio.h>
 
//枚举类型1:
enum Sex
{
	MALE,
	FEMALE,
	SECRET
}s1 = MALE;
//声明时进行定义与初始化(全局)
 
enum Sex s2 = FEMALE;
//声明时进行定义与初始化(全局)
 
//枚举类型2:
enum Day
{
	Mon,
	Tues,
	Wed,
	Thur,
	Fri,
	Sat,
	Sun
};
 
int main()
{
	enum Day s3 = Mon;
	//定义与初始化(局部)
 
	return 0;
}

  上面代码中的 enum Sex 就是我们定义出来的一个枚举类型。我们发现它和结构体的声明十分相似,但也有不同的地方

  • 结构体中的关键字是 struct 而枚举的关键字是 enum ;
  • 结构体的 { } 里面是结构体的成员列表,而枚举的 { } 里是枚举未来的可能取值,这些值是不能被修改的,因此我们也把这些值叫做枚举常量;
  • 最后一点不同在于,结构体的每一个成员后边都要加 : 隔开,而枚举常量之间是用 , 加以区分。

1.2:枚举的取值:

在这里插入图片描述
  通过打印我们发现,枚举常量的默认取值是从 0 00 开始的,每次递增 1 11 。当然我们在定义枚举类型的时候,也可以给他们赋初值:
在这里插入图片描述
  此时这三个枚举常量的值就不再是 0 ,1,2了,而是我们初始化赋值的 1 、2、4。如果只初始化枚举常量其中的某一个,后面的枚举常量会在当前初始化值的基础上,每次自增 1.
在这里插入图片描述
  如上,我们只初始化了枚举常量中的 FEMALE 给它赋值成 2,MALE 还是默认的从 0 开始,SECRET 则是在它前一个枚举常量 FEMALI 2 的基础上自增了 1 。

1.3:枚举的优点:

  于是这里就产生了一个问题,枚举类型的成员均为常量,不可在使用中被修改,那么我们同样可使用宏 #define 去定义常量,为什么非要使用枚举类型呢?

这是因为,相比于宏,枚举类型具有很多优点

  • 增加代码的可读性和可维护性
  • 和 #define 定义的标识符比较,枚举有类型检查,更加严谨
  • 防止了命名污染(封装)
  • 便于调试,#define在调试的时候会完成替换
  • 使用方便,一次可以定义多个变量

1.4:枚举的大小:

  已给枚举变量,只会用来存放一个枚举常量的值,所以一个枚举变量的大小应该就是一个 int 的大小,也就是4个字节。下面我们通过代码来测试一下。
在这里插入图片描述

1.5枚举的使用:

enum Color//颜色
{
 RED=1,
 GREEN=2,
 BLUE=4
};
enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
clr = 5;//避免这样写,c++会报错

😊二:联合(共用体)😊

2.1:联合类型的定义:

  联合也是一种特殊的自定义类型,这种类型定义的变量也包含有一系列的成员,但不同的是这些成员共用同一块空间遂也被称作共用体)

union UN
{
	char c;
	int i;
};
//定义了一个共用体类型

int main()
{
	union UN un;//定义了一个共用体变量
	return 0;
}

2.2:联合类型的特点:

  联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员),受限于联合体的特点,我们不会同时使用联合里面的成员,只会用一种的一个。

union UN
{
	char c;
	int i;
};
//定义了一个共用体类型

int main()
{
	union UN un;//定义了一个共用体变量
	printf("%d\n", sizeof(un));
	printf("%p\n", &un);
	printf("%p\n", &un.c);
	printf("%p\n", &un.i);
	return 0;
}
//结果:
4
00EFFA2C
00EFFA2C
00EFFA2C

可以看出, unun.cun.i 它们三个的起始地址都一样,这也说明,联合体的成员确实会共用同一块内存空间。

2.3:联合大小的计算:

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

我们来看看以下代码的结果:

#include<stdio.h>
 
//联合体1:
union TEST1
{
	char c[5];
	int i;
};
 
//联合体2:
union TEST2
{
	short c[7];
	int i;
};
 
int main()
{
	//检查联合体的大小:
	printf("The size of TEST1 is %d\n", sizeof(union TEST1));
	printf("The size of TEST2 is %d\n", sizeof(union TEST2));
 
	return 0;
}

在这里插入图片描述
  在联合体 TEST1 中,占用空间最大的成员是 char 类型数组 c ,且其中含有 5 个元素,则其所占空间大小为 5 个字节,而我们都知道 VS 的对齐数默认为 8 ,则将会对齐至默认对齐数 4 的整数倍,即 8 个字节;而联合体 TEST2 中,占用空间最大的成员是 short 类型数组 c ,且其中含有 7 个元素,则其所占空间的大小为 14 个字节,那么就将会对齐至对齐数 4 的整数倍,即 16 个字节;

2.4:判断当前机器的大小端:

  联合体最大的特点就是:联合体的成员是共用同一块内存空间的.

  于是,我们可以想一想,既然联合体的大小会随着内部成员大小的变化而变化,那么是不是联合体类型也可以通过判断内容大小,来帮助我们判断机器的大小端存储模式呢?

   我们直接开始实践:

union Un
{
	char c;
	int i;
};

int main()
{
	union Un un;
	un.i = 1;
	if (un.c == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

这里我们先把联合体里的 int 型变量赋值成 1,再用联合体里的 char 型变量取访问,因为联合体的成员共用一块空间,且 char 型变量,一次只能访问一个字节,我们就可以通过看 char 类型访问到的是不是 1 来判断大小端,就不用再像以前方法一那样,取 int 型的地址,然后再强制转换成 char* 的指针,再去解引用。

😐总结:😐

  枚举和联合体相关的知识现在使用的其实比较少,需要在以后的工作中才会慢慢体会到他的好处!自定义类型在我们未来的工作中将会频繁的使用到。所以各位小伙伴们对于自定义类型的使用一定要烂熟于心,下去以后一定要多加练习,牢固掌握
  更新不易,辛苦各位小伙伴们动动小手,👍三连走一走💕💕 ~ ~ ~ 你们真的对我很重要!最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!

专栏订阅:
每日一题
c语言学习
算法
智力题
更新不易,辛苦各位小伙伴们动动小手,👍三连走一走💕💕 ~ ~ ~ 你们真的对我很重要!最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!

在这里插入图片描述

相关文章:

  • Python与Matlab混合编程案例
  • 排列的时候如何避免重复?
  • 芒果改进YOLOv5系列:原创结合Conv2Formers改进结构,Transformer 风格的卷积网络视觉基线模型,超越ConvNeXt结构
  • 利用Windows系统服务进行权限提升
  • WebAssembly编译之(2)-Ubuntu搭建WASM编译环境
  • InstanceNorm LayerNorm
  • yolo结构介绍
  • 最详细、最仔细、最清晰的几道python习题及答案(建议收藏哦)
  • C语言:数组
  • Python装饰器使用方法详解
  • 「python|语言特性」为什么f-string是python中最舒适的字符串格式化方式
  • 8. 好客租房-WebSocket与即时通讯系统[项目必需]
  • 机器学习04 决策树
  • java基础学习 day37 (集合)
  • Python闭包与闭包陷阱
  • 《Java编程思想》读书笔记-对象导论
  • 07.Android之多媒体问题
  • Angular Elements 及其运作原理
  • ERLANG 网工修炼笔记 ---- UDP
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • Javascript基础之Array数组API
  • js继承的实现方法
  • Mac转Windows的拯救指南
  • ReactNative开发常用的三方模块
  • Webpack 4x 之路 ( 四 )
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 原生Ajax
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • #DBA杂记1
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (1)(1.9) MSP (version 4.2)
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (done) 两个矩阵 “相似” 是什么意思?
  • (pojstep1.1.2)2654(直叙式模拟)
  • (ros//EnvironmentVariables)ros环境变量
  • (笔试题)分解质因式
  • (七)Java对象在Hibernate持久化层的状态
  • (译)计算距离、方位和更多经纬度之间的点
  • (转)iOS字体
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .Net 知识杂记
  • .net2005怎么读string形的xml,不是xml文件。
  • .Net6使用WebSocket与前端进行通信
  • @ComponentScan比较
  • @TableLogic注解说明,以及对增删改查的影响
  • [ 云计算 | Azure 实践 ] 在 Azure 门户中创建 VM 虚拟机并进行验证
  • [1] 平面(Plane)图形的生成算法
  • [8-27]正则表达式、扩展表达式以及相关实战
  • [AIGC] 使用Curl进行网络请求的常见用法
  • [android] 练习PopupWindow实现对话框
  • [BZOJ1010] [HNOI2008] 玩具装箱toy (斜率优化)
  • [CareerCup][Google Interview] 实现一个具有get_min的Queue