新手入门C语言之联合体和枚举

news/2024/4/27 14:58:20/文章来源:https://blog.csdn.net/qq_73509351/article/details/137079888

        在上一篇文章中,我们了解到在C语言中,自定义类型有三种,这里我们介绍后两种,联合体和枚举。

一.联合体

1.联合体的声明

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

        联合体的关键字是union,我们可以举例写出一个联合体的定义与初始化

union Un
{char c;//1int i;//4
};int main()
{union Un u = {0};return 0;
}

2.联合体的特点

        联合的成员是共用同一块内存空间的,他们的首地址是相同的,联合变量的带线啊哦,至少是最大的成员的大小。

        现在,我们来看一下联合体的大小和地址

union Un
{char c;//1int i;//4
};int main()
{union Un u = {0};printf("%zd\n", sizeof(u));//大小为4printf("%p\n%p\n%p\n", &u,&u.i,&u.c);return 0;
}

        我们会发现,大小为4,而输出地址时三者是相同的。

        既然是这样的,那我们是否可以通过更改c的值,来改变i的值呢?

int main()
{union Un u = { 0 };u.i = 0x11223344;u.c = 0x55;return 0;
}

        我们会发现,i的结果发生了变化,变成了0x11223355

       下面,我们来对比结构体和联合体内存布局的情况。

        我们发现,联合体节省了很多的空间。         

        因此,我们清楚了,一般来说,我们在使用某一个联合体的时候,都会使用联合体的一个变量。

3.联合体大小的计算

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

        我们写出如下的代码,进行分析

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

        在这个代码中,最大成员的大小是5,但是联合体的大小并不是5,char类型的对齐数是1,int类型的对齐数是4,因此最大对齐数是4,所以,我们在设计联合体的时候,设计的大小应该是8

        现在,我们再看一个代码来举例一下

        

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

        在这个联合体中,大小是16,一定要注意联合体的大小啊哦是最大对齐数的整数倍

4.联合体的实例

        那么,我们在什么时候会应用到联合体呢?下面给大家举一个实例。

我们要搞⼀个活动,要上线⼀个礼品兑换单,礼品兑换单中有三种商品:图书、杯⼦、衬衫。 每⼀种商品都有:库存量、价格、商品类型和商品类型相关的其他信息。 图书:书名、作者、⻚数 杯⼦:设计 衬衫:设计、可选颜⾊、可选尺⼨

在这里,三种礼品有公共的属性,也有特殊的属性,我们当然可以直接写一个结构体,来进行实践

struct gift_list
{//公共属性 int stock_number;//库存量 double price; //定价 int item_type;//商品类型 //特殊属性 char title[20];//书名 char author[20];//作者 int num_pages;//⻚数 char design[30];//设计 int colors;//颜⾊ int sizes;//尺⼨ 
};

但是,这样书写的结构体占据了很大的空间,且有的内容在定义时是用不到的,因此,我们就可以考虑使用联合体的方法来实现。

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;
};

5.联合体判断大小端

在之前,我们已经可以写出一个函数来判断大小端了,那么我们是否可以利用联合体的性质,来写出一个程序呢?

int check_sys()
{union{int i;char c;}un;un.i = 1;return un.c;//返回1是⼩端,返回0是⼤端 
}

这样,就可以实现啦。

二.枚举

1.枚举的声明

        枚举实际就是一一列举,比如,我们可以列举一周有七天,性别有男女,月份有十二个月等等。

        现在,我们开始写出枚举的式子吧。

enum Sex//性别
{MALE,FEMALE,SECRET
};enum Color//颜⾊
{RED,GREEN,BLUE
};

        这些都可以表示枚举。

        当然,我们也可以进行创建和初始化。

int main()
{enum Color color = RED;//RED = 5;//errprintf("%d\n", RED);printf("%d\n", GREEN);printf("%d\n", BLUE);return 0;
}

        在输出枚举的结果的时候,我们可以发现,如果我们不更改数据,RED代表的就是0,GREEN代表1,依次类推,我们是不能在主函数内进行更改的,这是因为,当枚举创建的时候,就是一个枚举常量,如果我们想更改数据,就必须要在枚举创建的时候赋初始值。

enum Color
{//三原色的可能取值,枚举常量RED=5,//5GREEN,//6BLUE//7
};

        当然,也可以这样更改

enum Color
{//三原色的可能取值,枚举常量RED,//0GREEN=5,//5BLUE//6
};

 2.枚举的优点

        我们会发现,枚举的内容在#define也可以做到,那么,为什么非要使用枚举呢?

1. 增加代码的可读性和可维护性

        便于书写和维护

2. 和#define定义的标识符⽐较枚举有类型检查,更加严谨。

        在C++中,把枚举单独认为是一种特定的类型,因此,不规范时会报错,使得程序更加严谨。

 3. 便于调试,预处理阶段会删除 #define 定义的符号

        在调试中,不会删除枚举中的内容

4. 使⽤⽅便,⼀次可以定义多个常量

5. 枚举常量是遵循作⽤域规则的,枚举声明在函数内,只能在函数内使⽤

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go——结构体

Go语言中没有类的概念,也不支持类的继承等面向对象的概念。Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性。 一. 类型别名和自定义类型 1.1 自定义类型 在Go语言中有一些基本的数据类型,如string,整型,…

手机网页关键词视频爬虫采集软件可导出视频分享链接|视频无水印批量下载工具

全新音视频批量下载工具,为您解放视频管理烦恼! 现如今,音上涌现出大量精彩的视频内容,但是要想高效地获取、管理和分享这些视频却是一件颇具挑战的事情。针对这一难题,我们自主研发了全新的音视频批量下载工具&#x…

数学建模体育建模和经济建模国防科大版

目录 6.体育中的数学建模 7.经济学问题中的数学建模 7.1.实物交换模型 7.2.边际效应 7.3.最佳消费选择模型 6.体育中的数学建模 体育科学的研究中,也有大量的数学建模问题,例如:棒球的最佳击球点问题、滑板滑雪赛道的设计、越野自行车比…

各种需要使用的方法-->vue/微信小程序/layui

各种需要使用的方法-->vue/微信小程序/layui 1、vue里样式不起作用的方法,可以通过deep穿透的方式2、 js获取本周、上周、本月、上月日期3、ArrayBuffer Blob 格式转换ArrayBuffer与Blob的区别ArrayBuffer转BlobBlob转ArrayBuffer需要借助fileReader对象 4、使用…

STM32使用滴答定时器实现delayms

在STM32上使用SysTick实现jiffies(时间戳)并且实现delay_ms 代码实现: volatile uint32_t jiffies 0; // 用于记录系统运行的jiffies数 void SysTick_Handler(void) {/* 每次SysTick中断,jiffies增加 */jiffies; }uint32_t tick…

如何利用生成式人工智能挑选合适的候选人?

在当今激烈的商业竞争中,招聘合适的人才是构建企业成功的基石。筛选和面试候选人是一个复杂且精细的过程,它不仅关系到职位的有效填补,更影响到企业的长期发展和团队建设。 选择合适候选人的重要性 选择合适的候选人就像寻找一片沙滩上的珍…

曲线生成 | 图解Reeds-Shepp曲线生成原理(附ROS C++/Python/Matlab仿真)

目录 0 专栏介绍1 什么是Reeds-Shepp曲线?2 Reeds-Shepp曲线的运动模式3 Reeds-Shepp曲线算法原理3.1 坐标变换3.2 时间翻转(time-flip)3.3 反射变换(reflect)3.4 后向变换(backwards) 4 仿真实现4.1 ROS C实现4.2 Python实现4.3 Matlab实现 0 专栏介绍 &#x1f5…

MP4如何把视频转MOV格式? MP4视频转MOV格式的技巧

在现代的数字媒体时代,视频格式转换成为了许多用户必须掌握的技能。特别是将MP4视频转换为MOV格式,这对于需要在Apple设备上播放或编辑视频的用户来说尤为重要。本文将详细介绍如何将MP4视频转换为MOV格式,帮助读者轻松应对不同设备和平台的需…

编程语言|C语言——C语言基本数据类型

前言 针对不同的数据,采取不同的存储方式和进行不同的处理。随着处理对象的复杂化,数据类型也要变得更丰富。数据类型的丰富程度直接反映了程序设计语言处理数据的能力。 C语言很重要的一个特点是它的数据类型十分丰富。因此,C语言程序数据处…

【Nuxt3】modules目录和nuxt3模块的简单介绍

简言 记录下nuxt3项目中module的用法 modules目录 使用 modules/ 目录在应用程序中自动注册本地模块。 这是一个很好的地方,可以放置您在构建应用程序时开发的任何本地nuxt模块。 nuxt模块相当于npm包,可以发布到npm社区中 在modules/ 目录下的本地模…

二叉树|654.最大二叉树

力扣题目地址 class Solution { public:TreeNode* constructMaximumBinaryTree(vector<int>& nums) {TreeNode* node new TreeNode(0);if (nums.size() 1) {node->val nums[0];return node;}// 找到数组中最大的值和对应的下标int maxValue 0;int maxValueIn…

Kubernetes生产集群部署指南

部署生产就绪的Kubernetes集群需要考虑到管理、负载均衡、安全、存储等很多细节&#xff0c;本文给出了一个生产就绪Kubernetes集群的完整部署流程&#xff0c;可以作为生产部署的有效参考。原文: Deploying a Production Kubernetes Cluster in 2023 — A Complete Guide Grow…

万兆车载以太网转换器 10G/2.5G多速车载以太网转换器-MC10GM

MC10GM转换器 一、产品简要分析 2.5G,5G,10G可切换万兆/多速车载以太网转换器。采用罗森博格H-MTD标准接口类型。实现将车载以太网标准2.5/5/10G BASE-T1转换为工业级2.5/5/10G 标准以太网&#xff0c;进而接入电脑或工控机. 产品实现2.5/5/10G Base-T1 和2.5/5/10G Base-R之间…

android Fragment 生命周期 方法调用顺序

文章目录 Introlog 及结论代码 Intro 界面设计&#xff1a;点击左侧按钮&#xff0c;会将右侧 青色的RightFragment 替换成 黄色的AnotherRightFragment&#xff0c;而这两个 Fragment 的生命周期方法都会打印日志。 所以只要看执行结果中的日志&#xff0c;就可以知道 Fragme…

CSS时钟案例

文章目录 1. 演示效果2. 分析思路3. 代码实现 1. 演示效果 2. 分析思路 背景是表盘&#xff0c;不用自己制作然后用CSS的定位做时针&#xff0c;分针和秒针黑点用伪元素::after生成转动用animation实现 3. 代码实现 <!DOCTYPE html> <html lang"en">&…

【详细讲解React 快速入门教程】

&#x1f525;博主&#xff1a;程序员不想YY啊&#x1f525; &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家&#x1f4ab; &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 &#x1f308;希望本文对您有所裨益&#xff0c;如有…

Python中的变量与常量

变量&#xff1a;在程序运行过程中&#xff0c;值会发生变化的量&#xff0c; 常量&#xff1a;在程序运行过程中&#xff0c;值不会发生变化的量。 无论是变量还是常量&#xff0c;在创建时都会在内存中开辟一块空间&#xff0c;用于保存它的值。 Python 中的变量不需要声明…

数据链路层协议之以太网协议

以太网协议是通过网线/光纤进行通信。这和通过wifi&#xff08;无线&#xff09;&#xff0c;通过移动流量&#xff08;4G/5G&#xff09;通信不一样。以太网&#xff0c;横跨数据链路层和物理层 一.以太网数据帧格式 包括了帧头载荷(IP数据报)帧尾。 1.目的地址 源地址 分别…

初探Flink集群【持续更新】

周末下雨&#xff0c;倒杯茶&#xff0c;在家练习Flink相关。 开发工具&#xff1a;IntelliJ Idea 第一步、创建项目 打开Idea&#xff0c;新建Maven项目&#xff0c;包和项目命名 在pom.xml 文件中添加依赖 <properties><flink.version>1.13.0</flink.vers…

【Redis主从架构。主从工作原理psync、bgsave、部分数据复制、主从复制风暴解决方案】【Redis哨兵高可用架构。sentinel】

Redis主从架构 Redis主从工作原理数据部分复制 Redis哨兵高可用架构client连接哨兵规则主节点挂了&#xff0c;集群从新选择主节点&#xff0c;并且同步给sentinel 转自图灵课堂 redis主从架构搭建&#xff0c;配置从节点步骤&#xff1a; 1、复制一份redis.conf文件2、将相关…