当前位置: 首页 > 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闭包与闭包陷阱
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • CAP 一致性协议及应用解析
  • Facebook AccountKit 接入的坑点
  • hadoop集群管理系统搭建规划说明
  • isset在php5.6-和php7.0+的一些差异
  • js操作时间(持续更新)
  • laravel with 查询列表限制条数
  • node.js
  • python3 使用 asyncio 代替线程
  • TypeScript实现数据结构(一)栈,队列,链表
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 关于Flux,Vuex,Redux的思考
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 如何实现 font-size 的响应式
  • 微信开源mars源码分析1—上层samples分析
  • 由插件封装引出的一丢丢思考
  • 原生js练习题---第五课
  • 容器镜像
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • (2)STL算法之元素计数
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (新)网络工程师考点串讲与真题详解
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .mysql secret在哪_MYSQL基本操作(上)
  • .net core使用RPC方式进行高效的HTTP服务访问
  • .net refrector
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .NET框架设计—常被忽视的C#设计技巧
  • /usr/bin/env: node: No such file or directory
  • @param注解什么意思_9000字,通俗易懂的讲解下Java注解
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
  • [AMQP Connection 127.0.0.1:5672] An unexpected connection driver error occured
  • [C puzzle book] types
  • [linux]linux命令学习-netstat
  • [Neural Network] {Université de Sherbrooke} L2.9 Param Initialization
  • [PHP]加密解密函数
  • [poj3686]The Windy's(费用流)
  • [Python]面向对象基础