C语言自定义类型(下)

news2024/11/27 7:36:55

大家好,我们今天来学习C语言自定义类型剩下的内容。
在这里插入图片描述

目录

1.枚举
2.联合

1.枚举类型

枚举顾名思义就是一一列举。
把可能的取值一一列举。

一周的星期一到星期日是有限的7天,可以一一列举。
性别有:男、女、保密,也可以一一列举。
月份有12个月,也可以一一列举

枚举类型的定义
直接看到代码:

enum Day//星期
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
enum Sex//性别
{
MALE,
FEMALE,
SECRET
}enum Color//颜色
{
RED,
GREEN,
BLUE
};

以上定义的 enum Day , enum Sex , enum Color 都是枚举类型。
{}中的内容是枚举类型的可能取值,也叫 枚举常量 。

那么我们的枚举常量的值又是多少呢?

enum Sex
{
	//枚举的可能取值
	MALE,//枚举常量
	FEMALE,
	SECRET
};
enum Color
{
	RED,
	GREEN,
	BLUE
};

int main()
{

	printf("%d\n", MALE);
	printf("%d\n", FEMALE);
	printf("%d\n", SECRET);
	enum Sex sex = SECRET;

	printf("%zd\n", sizeof(sex));

	return 0;
}

在这里插入图片描述

这是因为这些可能取值都是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值。

例如:

enum Sex
{
	//枚举的可能取值
	MALE=3,//枚举常量
	FEMALE,
	SECRET
};
int main()
{
	//MALE = 5;//ERR
	printf("%d\n", MALE);
	printf("%d\n", FEMALE);
	printf("%d\n", SECRET);
	enum Sex sex = SECRET;

	printf("%zd\n", sizeof(sex));

	return 0;
}

在这里插入图片描述

这里我们给它赋初值,我们给MALE赋值为3,后面的值就会默认加1,所以打印的结果就为3,4,5。

我们不仅可以这么定义,而且我们可以用宏来进行赋值定义:

#define MALE 3
#define FEMALE 4
#define SECRET 5

那么我们最好还是用枚举,那这是为什么呢,只就得提到我们枚举的优点了:

我们可以使用 #define 定义常量,为什么非要使用枚举?
枚举的优点:

  1. 增加代码的可读性和可维护性
  2. 和#define定义的标识符比较枚举有类型检查,更加严谨。
  3. 防止了命名污染(封装)
  4. 便于调试
  5. 使用方便,一次可以定义多个常量

当我们使用枚举时只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
例如下面的代码:

enum Color//颜色
{
RED=1,
GREEN=2,
BLUE=4
};
enum Color clr = GREEN;

相信大家应该都已经了解了枚举的应用,那么我们就进入下个内容的学习。

2.联合(共用体)

联合类型的定义:

联合也是一种特殊的自定义类型
这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。

//联合类型的声明
union Un
{
	char c;
	int i;
};
//联合变量的定义
int main()
{
	union Un un;
	//计算连个变量的大小
	printf("%d\n", sizeof(un));
	return 0;
}

在这里插入图片描述

union Un
{
	char c;//1
	int i;//4
};

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个字节,而我们定义的int型变量i就是4个字节,那么我们是不是就可以间接的认为联合体是公用一个空间一个内存的呢?我们再看到我们对整个联合体变量取地址和分别对联合体的成员变量取地址,打印出来发现它们的地址是一样的,这就可以说明联合体是公用一段内存的。

联合的特点

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。

还记得之前我们如何判断大端还是小端的题吗?这里我们就可以利用联合体来解决:

int check_sys()
{
	int a = 1;
	if (*(char*)&a == 1)//int*
		return 1;
	else
		return 0;
}

int main()
{
	int ret = check_sys();
	if (ret == 1)
		printf("小端\n");
	else
		printf("大端\n");

	return 0;
}

在这里插入图片描述

在这里插入图片描述

我们的小端是从低地址到高地址的,所以我们给a取出一个字节就是先给它强制转换为char型在解引用,如果等于1那么就是小端,如果不是1那就是大端。

联合大小的计算

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

union Un
{
	char c[5];//5
	int i;//4
};

int main() 
{
	printf("%zd\n", sizeof(union Un));

	return 0;
}

在这里插入图片描述

union Un
{
	short c[7];//14
	int i;//4
};

int main()
{
	printf("%zd\n", sizeof(union Un));

	return 0;
}

在这里插入图片描述

我们看到第一个代码因为char型的大小是一个字节,和vs默认的8个对齐数相比更小,所以它的对齐数是1,而int型的大小是4个字节,和vs默认的8个对齐数相比也小,所以它的对齐数就是4,而c是个字符类型的数组,占了5个字节,i只占了4个字节,因为联合的大小至少是最大成员的大小。当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。所以我们联合体的大小就是8个字节。而第二个代码也是这么计算,得出来的就是16个字节。

好了今天的学习就到这里了,感谢大家的支持,我们下次再见。

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

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

相关文章

2023年【电工(中级)】考试资料及电工(中级)找解析

题库来源:安全生产模拟考试一点通公众号小程序 电工(中级)考试资料是安全生产模拟考试一点通总题库中生成的一套电工(中级)找解析,安全生产模拟考试一点通上电工(中级)作业手机同步…

面试官问:大量的 TIME_WAIT 状态 TCP 连接,对业务有什么影响?怎么处理?

几个方面: 问题描述:什么现象?什么影响? 问题分析 解决方案 底层原理 1.问题描述 模拟高并发的场景,会出现批量的 TIME_WAIT 的 TCP 连接: 短时间后,所有的 TIME_WAIT 全都消失&#xff0…

[linux(静态文件服务)] 1.部署vue发布后的dist网页到nginx 2.偷懒的话可以用宝塔部署nginx

所以说: 1.windows下把开发好的vue工程打包为dist文件然后配置下nginx目录即可。 2.linux上不需要安装node.js环境。 3.这样子默认访问服务器ip地址,就可以打开,毕竟默认就是:80端口。 注意:如果windows下部署正常&…

C++,异常、转换函数、智能指针

目录 一、异常 1 C 异常机制: 2 使用try catch进行异常处理. 3、c 已经内置标准异常类,专业用于抛出的语法中 4 自定义异常: 5 函数只抛出,不处理。让上层函数处理,并且上层函数还可以不处理,让上上层…

机器学习笔记:Huber Loss smooth L1 loss

1 Huber loss 1.1 介绍 Huber Loss是回归问题中的一种损失函数,它结合了均方误差MSE和绝对误差MAE的特点。 Huber Loss在误差较小的时候是平方损失,而在误差较大的时候是线性损失。因此,它在处理有噪声的数据时,尤其是存在离群点…

【从入门到起飞】JavaAPI—BigInteger,BigDecimal的使用方法

🎊专栏【Java基础】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【The truth that you leave】 🥰欢迎并且感谢大家指出我的问题 文章目录 🎁BigInteger🍔获取BigInteger对象⭐获…

【数据结构-图】最小生成树

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

AWS SAA知识点整理(作成中)

共通 一些信息已经更新了,但参考题的答案还是旧的。 比如: S3的最大读写性能已经提高到 3,500 PUT/COPY/POST/DELETE or 5,500 GET/HEAD requests per second 并且不再要求使用random prefix Storage Amazon S3 为了提高读取的performance: For exam…

CTF 入门指南:从零开始学习网络安全竞赛

文章目录 写在前面CTF 简介和背景CTF 赛题类型介绍CTF 技能和工具准备好书推荐 写作末尾 写在前面 CTF比赛是快速提升网络安全实战技能的重要途径,已成为各个行业选拔网络安全人才的通用方法。但是,本书作者在从事CTF培训的过程中,发现存在几…

每月固定日期提醒app用哪个?手机上可固定日期提醒的工具选择哪一个

在这个繁忙的世界中,时间总是飞逝而过,我们常常需要一些方式来提醒自己按时完成一些重要的工作任务。每月固定日期提醒是其中之一,它可以涵盖很多方面的事情,从生日、账单支付到工作报告的提交。然而,如何有效地管理这…

7章:动态加载数据处理(selenium)

selenium模块和爬虫之间的关联 便捷的获取网站中动态加载的数据便捷实现模拟登录 什么是selenium模块 基于浏览器自动化的一个模块 selenium使用流程: - 环境安装:pip install selenium - 下载一个浏览器的驱动程序(谷歌浏览器&#xff…

Python爬虫之入门保姆级教程

目录 一、分析要爬取的网站 二、导入相关库 三、相关的参数 四、向网站发出请求(使用代理IP) 五、匹配 六、获取图片,保存到文件夹中(os库) 七、完整代码 总结 相信许多人都曾为如何入门Python爬虫而烦恼。今天…

MySQL 权限变更,何时生效?

本文讲述了对三种级别权限的变更后,使其生效的方法。 作者:欧阳涵,爱可生团队 DBA 成员,看到下雨知道要打伞的 2.5 次元爱好者~ 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源…

springCloud和springboot升级

一、引言 springCloud和springBoot较低版本有时候会有网络漏洞,所以随着springCloud和springBoot的升级会修复这些漏洞。那么有时候就遇到在升级过程中,遇到不兼容的问题。需要总结下来记录一下。 二、springBoot和springCloud的使用 1、springBoot的引…

【2023年11月第四版教材】第15章《风险管理》(第三部分)

第15章《风险管理》(第三部分) 5 过程1-规划风险管理6 过程2-识别风险6.1 识别风险★★★6.2 数据收集★★★6.3 数据分析★★★ 7 过程3-实施定性风险分析7.1 实施定性风险分析7.2 数据分析★★★7.3 数据表现★★★7.4 项目文件(更新&#…

Java诊断利器Arthas安装和使用

下载 curl -O https://alibaba.github.io/arthas/arthas-boot.jar先启动java项目,然后再启动 arthas-boot.jar 第一次使用arthas的时候,先按1(后面没有对应类的)安装上arthas 粘附一个进程 常用命令 dashboard 命令&#xff1a…

安防监控/视频汇聚平台EasyCVR云端录像不展示该是什么原因?该如何解决?

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、…

中国首个接入大模型的Linux操作系统;ChatGPT支持图片和语音输入;抖音上线方言自动翻译功能丨RTE开发者日报 Vol.57

开发者朋友们大家好: 这里是「RTE 开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE (Real Time Engagement) 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…

【强化学习】01—— 强化学习简介

文章目录 两种机器学习类型强化学习定义强化学习交互过程强化学习系统要素历史(History)状态(State)策略(Policy)奖励(Reward)价值函数(Value Function)模型(Model)迷宫例子 强化学习智能体分类参考 两种机器学习类型 监督学习/无监督学习/强化学习/机器学习之间的关系 预测 根…

React的高阶函数

1.认识高阶函数 高阶组件 本身不是一个组件,而是一个函数函数的参数是一个组件,返回值也是一个组件 高阶组件的定义 import ThemeContext from "../context/theme_context"function withTheme(OriginComponent) {return (props) > {retur…