联合(union)和枚举(enum)学习(c语言)

前言

Hello,亲爱的小伙伴们,好久不见,今天我们继续来学习新的内容-----联合和枚举

如果喜欢作者菌的文章的话,就不要吝啬手中的三连呀,万分感谢!!

联合(共用体)(union)


联合是一种数据类型,它能在同一个内存空间储存不同的数据类型(不是同时储存),一次只能存储一种数据类型。其典型用法是,设计一种表以储存既无规律、实现也不知道顺序的混合类型。其中联合的大小都相等,每个联合可以储存各种数据类型。共用体的长度为其最大的成员的长度。
用途:当数据项使用两种或多种格式(但不会同时使用)时,可以节省空间。节省内存。
比如用户ID,有时候需要把它当做字符串,有时需要当做数字。

#include<stdio.h>
union hold {int digit;double bigfl;char letter;
};
/*该联合只可储存一个int类型、一个double类型或一个char类型的值。只能储存一个*/
int main(void)
{union hold fit;//hold类型的联合变量union hold save[10]; //内含是个联合变量的数组union hold * pu;     //指向hold类型联合变量的指针printf("size of fit = %u,size of save = %u,size of pu = %u\n",sizeof fit, sizeof save, sizeof pu);/*结果: size of fit = 8,size of save = 80,size of pu = 8编译器会分配足够的空间以便它能储存联合声明中占用最大字节的类型。---double---8字节  */ //初始化,联合只能存储一个值, union hold valA;valA.letter = 'R';union hold valB = valA;union hold valC = {88}; union hold valD = {.bigfl = 118.2};//使用联合fit.digit = 23;//把23储存在fit,占两字节printf("size of fit = %u\n",sizeof fit);fit.bigfl = 2.9;//清除23,储存2.0,占8字节printf("size of fit = %u\n",sizeof fit);fit.letter = 'h'; //清除2.0,储存h,占1字节 printf("size of fit = %u\n",sizeof fit);//使用指针pu = &fit;x = pu->digit;//相当于x = fit.digitreturn 0;
/*结果:size of fit = 8,size of save = 80,size of pu = 8size of fit = 8size of fit = 8size of fit = 8*/
} 


枚举(enum)
可以使用枚举声明符号名称来表示整数常量。使用enum关键字,可以创建一个新“类型”并指定它可具有的值(实际上,enum常量是int类型,因此,只要能使用int类型的地方就可以使用枚举类型)
枚举量能提升为int类型。

#include<stdio.h>enum spectrum {red,orange,yellow,green,blue,violet
};
enum spectrum color;
//第一个声明创建了spectrum作为标记名,允许把enum spectrum作为一个类型名使用
//第二个声明使color作为该类型的变量,第一个花括号中的标识符枚举了spectrum变量可能的值。
//因此color可能的值为red、orange、yellow等等,这些符号称为 枚举符。 
int main(void)
{color = blue;/*C枚举的一些特性并不适用C++,例如C允许枚举变量使用++运算符,但是C++标准不允许 red、blue是int类型的常量。 */ printf("color = %d, red = %d, violet = %d\n",color, red, violet);/*结果: color = 4, red = 0, violet = 5通常情况下,枚举列表的常量都被赋予0,1,2,3...等 *///在枚举声明中,可以为枚举常量指定整数值,如果后面没有继续赋值,后面的常量会被赋予后续的值 enum levels {low = 100, medium = 500, high = 2000, super}; printf("low = %d, medium = %d, super = %d\n",low, medium, super);//low = 100, medium = 500, super = 2001return 0; 
}


步骤(一)——枚举量的声明和定义

(1)首先,请看下面的语句:

enum enumType {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};


这句话有两个作用:

第一:声明enumType为新的数据类型,称为枚举(enumeration);
第二:声明Monday、Tuesday等为符号常量,通常称之为枚举量,其值默认分别为0-6。(后面会介绍怎样显式的初始化枚举量的值)


(2)接着利用新的枚举类型enumType声明这种类型的变量:enumType Weekday 就像使用基本变量类型int声明变量一样,如 int a;也可以在定义枚举类型时定义枚举变量enum enumType {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}Weekday;

然而与基本变量类型不同的地方是,在不进行强制转换的前提下,只能将定义的枚举量赋值给该种枚举的变量,如:Weekday = Monday;或者Weekday = Sunday;不能将其他值赋给枚举变量,如:Weekday = 10;这是不允许的,因为10不是枚举量。也就是说Weekday只能是定义的Monday-Sunday这些定义过的枚举量。然而这不是绝对的,第六条会讲到利用强制类型转换将其他类型值赋给枚举变量。

(3)上面讲不能将非枚举量赋给枚举变量,那么能不能将枚举量赋给非枚举变量呢?

如:int a=Monday;这是允许的,因为枚举量是符号常量,这里的赋值编译器会自动把枚举量转换为int类型。
(4)前面讲可以对枚举进行赋值运算,那枚举变量能不能进行算术运算呢?
Weekday++;Weekday = Monday + Tuesday;这是非法的,因为这些操作可能导致违反类型限制,比如:Weekday = Sunday;
Weekday++;Weekday首先被赋予枚举量中的最后一个值Sunday(值为6),再进行递增的话,Weekday增加到7,而对于enumType类型来说,7是无效的。

总结:对于枚举,只定义了赋值运算符,没有为枚举定义算术运算。

(5)不能对枚举量进行算术运算,那么枚举量能不能参与其他类型变量的运算呢?int a;a = 1 + Monday;这是允许的,因为编译器会自动把枚举量转换为int类型。

(6)第二条讲:在不进行强制转换的前提下,只能将定义的枚举量赋值给该种枚举的变量,言下之意就是可以通过强制转换将其他类型值赋给枚举变量:

Weekday = enumType(2);等同于:Weekday = Wednesday;但是,如果试图将一个超出枚举取值范围的值通过强制转换赋给枚举变量,会出现什么结果?

Weekday = enumType(20);结果将是不确定的,这么做不会出错,但得不到想要的结果。

步骤(二)——自定义枚举量的值

(1)前面讲通过定义enum enumType {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

枚举量Monday、Tuesday等的值默认分别为0-6,我们可以显式的设置枚举量的值:

enum enumType {Monday=1, Tuesday=2, Wednesday=3, Thursday=4, Friday=5, Saturday=6, Sunday=7};

指定的值必须是整数!

(2)也可以只显式的定义一部分枚举量的值:

enum enumType {Monday=1, Tuesday, Wednesday=1, Thursday, Friday, Saturday, Sunday};这样Monday、Wednesday均被定义为1,则Tuesday=2,Thursday、Friday、Saturday、Sunday的值默认分别为2、3、4、5.总结:未被初始化的枚举值的值默认将比其前面的枚举值大1。

(3)第二条还说明另外一个现象,就是枚举量的值可以相同。

步骤(三)——枚举的取值范围


前面讲到可以通过强制转换将其他类型值赋给枚举变量:Weekday = enumType(2);这是合法的;但是Weekday = enumType(20);是非法的。这里涉及枚举取值范围的概念:枚举的上限是 大于最大枚举量的 最小的2的幂,减去1;

枚举的下限有两种情况:一、枚举量的最小值不小于0,则枚举下限取0;二、枚举量的最小值小于0,则枚举下限是 小于最小枚举量的 最大的2的幂,加上1。

举例来讲:

假如定义 enum enumType1 { First=-5,Second=14,Third=10 };则枚举的上限是16-1=15(16大于最大枚举量14,且为2的幂); 枚举的下限是-8+1=-7(-8小于最小枚举量-5,且为2的幂);
步骤(四)——枚举应用
个人觉得枚举和switch是最好的搭档:enum enumType{Step0, Step1, Step2}Step=Step0;//注意这里在声明枚举的时候直接定义了枚举变量Step,并初始化为Step0

switch (Step)
{case Step0:{...;break;}case Step1:{...;break;}case Step2:{...;break;}default:break;
}


另外枚举还有一种少见的用法是 enum { one ,two ,three}; 就是不指定一个名字,这样我们自然也没法去定义一些枚举类型了。此时就相当于static const int one = 0;这样定义三个常量一样。然后用的话就是int no = one。

一、简述
强类型枚举(Strongly-typed enums),号称枚举类型,是C++11中的新语法,用以解决传统C++枚举类型存在的缺陷。传统C++中枚举常量被暴漏在外层作用域中,这样若是同一作用域下有两个不同的枚举类型,但含有相同的枚举常量也是不可的,比如:

enum Side{Right,Left};
enum Thing{Wrong,Right};
这是不能一起用的。
另外一个缺陷是传统枚举值总是被隐式转换为整形,用户无法自定义类型。C++11中的强类型枚举解决了这些问题。

二、强类型枚举
强类型枚举使用enum class语法来声明,如下:

enum class Enumeration{
VAL1,
VAL2,
VAL3=100,
VAL4
};


这样,枚举类型时安全的,枚举值也不会被隐式转换为整数,无法和整数数值比较,比如(Enumeration::VAL4==10会触发编译错误)。
另外枚举类型所使用的类型默认为int类型,也可指定其他类型,比如:

enum calss Enum:unsigned int{VAL1,VAL2};


正如前面所说,强类型枚举能解决传统枚举不同枚举类下同枚举值名的问题,使用枚举类型的枚举名时,必须指明所属范围,比如:Enum::VAL1,而单独的VAL1则不再具有意义。

还有一点值得说明的是C++11中枚举类型的前置声明也是可行的,比如:

enum calss Enum;
enum class Enum1:unsigned int;


—————————————————————————

三、项目中的强类型枚举代码片段
1、图像处理
enum class Color{RED,BLUE,YELLOR,BLACK,WHITE};
2.交通灯
enum class TrafficLight{RED,YELLOR,GREEN};
强类型枚举值具有传统枚举的功能——命名枚举值,同时又具有类的特点——具有类域的成员和无法进行默认的类型转换。所以也称之为枚举类——enmu class

枚举类的底层数据必须是有符号或无符号整型,比如char unsigned int unsigned long,默认为int。

3.前置声明应用

enmu class Clolor:char;  //前置声明枚举类
void Foo(Color*p);        //前置声明的使用
//....................
enum class Color:char{RED,GREEN,BLACK,WHITE};                       //前置声明的定义


总结 :枚举类型是不能被直接用int变量赋值的,枚举类型只能用枚举常量赋值。而枚举类型可以同int类型进行计算,这时枚举类型就是按照int类型和其他数量进行计算了。

另外枚举类型可以看成是常量,直接在整个作用域里使用。

                         好,今天的学习就到这里,咱们下期再见,拜拜!!

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

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

相关文章

【计算机网络】计算机网络的组成与功能

计算机网络的组成与功能 导读一、计算机网络的组成1.1 从组成方式上1.1.1 硬件1.1.2 软件1.1.3 协议 1.2 从工作方式上1.3 从功能组成上 二、计算机网络的功能2.1 数据通信2.2 资源共享2.3 分布式处理2.4 提高可靠性2.5 负载均衡2.6 其它 结语 导读 大家好&#xff0c;很高兴又…

【python基础篇】 5. python 异常、文件与流

1 异常 错误&#xff1a;语法错误&#xff08;一般IDE能够发现&#xff09;&#xff0c;逻辑错误&#xff08;很难发现&#xff0c;提示起来比较麻烦&#xff09; 异常&#xff1a;当python检测到一个错误时&#xff0c;解释器无法继续执行下去&#xff0c;于是抛出相应的信息…

Web3开发框架分析

Web3开发框架旨在简化区块链和去中心化应用&#xff08;DApp&#xff09;的开发过程&#xff0c;为开发者提供必要的工具和库。以下是一些主要的Web3开发框架。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.Truffle Suite Truffl…

$MPC 登录MEXC,加速Partisia Blockchain 生态市场进程

Partisia Blockchain是一个以MPC技术方案为基础&#xff0c;具备可审计特性的隐私Layer1生态&#xff0c;与此同时&#xff0c;该链通过系列创新的系统架构&#xff0c;能够兼顾高迸发、安全、可拓展性以及可互操作特性。基于系列技术特性&#xff0c;Partisia Blockchain正在构…

OrangePi KunPengPro | linux系统下挂载U盘

OrangePi KunPengPro | linux系统下挂载U盘 时间&#xff1a;2024年6月6日21:32:53 文章目录 OrangePi KunPengPro | linux系统下挂载U盘1.参考2.操作fdisk -l 列出系统上所有磁盘的分区表信息将 /dev/sda1 分区挂载到 /mnt/udisk/ 目录显示文件系统的磁盘空间使用情况卸载文件…

RAG检索增强生成(1)-大语言模型的外挂数据库

Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks Lewis P, Perez E, Piktus A, et al. Retrieval-augmented generation for knowledge-intensive nlp tasks[J]. Advances in Neural Information Processing Systems, 2020, 33: 9459-9474. RAG结合了信息检…

python中B.py调用A.py中所有方法,该怎么导入呢

函数调用 python中B.py调用A.py中所有方法&#xff0c;该怎么导入呢1. 确保A.py和B.py在同一目录2. 在A.py中定义一些方法3. 在B.py中导入A.py并调用其方法4. 运行B.py详细解释额外提示 2 采用from A.py import *是否可行1. 确保A.py和B.py在同一目录2. 在A.py中定义一些方法3.…

Java数据结构与算法(最长回文子串动态规划)

前言 动态规划主要用于解决具有重叠子问题和最优子结构性质的问题。它通过将问题分解为子问题来解决复杂问题&#xff0c;每个子问题仅解决一次&#xff0c;并将其结果存储&#xff0c;以供后续使用&#xff0c;从而避免了重复计算。 动态规划的基本思想 分解问题&#xff1…

C++入门 ros服务通信

一、 开发环境 ubuntu20.04 ros版本noetic 参考视频 https://www.bilibili.com/video/BV1Ci4y1L7ZZ/?p52&spm_id_from333.1007.top_right_bar_window_history.content.click&vd_source4cd1b6f268e2a29a11bea5d2568836ee 二、 编写srv文件 在功能包下面创建srv文件夹…

【SpringBoot + Vue 尚庭公寓实战】项目初始化准备(二)

尚庭公寓SpringBoot Vue 项目实战】项目初始化准备&#xff08;二&#xff09; 文章目录 尚庭公寓SpringBoot Vue 项目实战】项目初始化准备&#xff08;二&#xff09;1、导入数据库2、创建工程3、项目初始配置3.1、SpringBoot依赖配置3.2、创建application.yml文件3.3、创建…

【Linux取经路】网络套接字编程——TCP篇

文章目录 前言十、Tcp Server 端代码10.1 socket、bind10.1 listen——监听一个套接字10.2 accept——获取一个新连接10.3 read——从套接字中读取数据10.4 write——向套接字中进行写入10.5 Tcp Service 端完整代码&#xff08;单进程版&#xff09;10.6 Tcp Server 端代码&am…

MySQL 8.0中查询缓存的废弃与原因分析

MySQL 8.0中查询缓存&#xff08;Query Cache&#xff09;的废弃与原因分析 引言 尽管MySQL的查询缓存&#xff08;Query Cache&#xff09;最初设计目的是为了提升性能&#xff0c;但因其存在严重的可扩展性问题和易成为系统瓶颈&#xff0c;MySQL在8.0版本中正式移除了这一…

这个世界,对于心态好的人,就是个大游乐场,越刺激越好玩。对于胆小鬼,那就是地狱,随时随地都会受伤

心态决定你的世界&#xff1a;游乐场还是地狱 在这个充满变数的世界里&#xff0c;我们的心态决定了我们看待世界的方式。对于心态积极的人来说&#xff0c;世界就像一个巨大的游乐场&#xff0c;每一个挑战都是一个新的游戏&#xff0c;每一个刺激都是乐趣的一部分。而对于那…

解决跨域的几种方法

解决跨域的方法主要有以下几种&#xff1a; 1.CORS&#xff08;跨域资源共享&#xff09; CORS是一种W3C规范&#xff0c;它定义了一种浏览器和服务器交互的方式来确定是否允许跨源请求。 服务器通过设置响应头Access-Control-Allow-Origin来允许或拒绝跨域请求。例如&#xf…

python-数据分析-缺失值-函数-数据类型

1 常用排序和统计函数 1 排序 sort_values() # by 指定排序的字段 可以传入列表&#xff0c;做多字段排序&#xff0c; 比如下面的例子&#xff0c; 当价格相同的时候&#xff0c; 价格相同的数据再按面积排序 # ascending 也可以传入列表&#xff0c;长度更by 的列表相同&…

[笔试训练](三十四)100:[NOIP2008]ISBN号码101:kotori和迷宫102:矩阵最长递增路径

目录 100:[NOIP2008]ISBN号码 101:kotori和迷宫 102:矩阵最长递增路径 100:[NOIP2008]ISBN号码 题目链接:[NOIP2008]ISBN号码_牛客题霸_牛客网 (nowcoder.com) 题目&#xff1a; 题解: 简单模拟 #include <iostream> #include<string> using namespace std; str…

大数据技术Hbase列数据库——topic2

目录 启动Hadoop启动HbaseHbase常用Shell命令基本命令关于表的操作增删改查询 启动Hadoop 1.到Hadoop安装目录下输入命令 sbin/start-all.sh[rootlocalhost hadoop-2.7.1]# sbin/start-all.sh This script is Deprecated. Instead use start-dfs.sh and start-yarn.sh Starti…

Maven导入jar包到本地仓库

导入本地jar包 <dependency><groupId>com.xxl</groupId>-----------------(参数二)<artifactId>xxl-sso-client</artifactId>-----------(参数三)<version>1.1.2</version>-----------------------(参数四) </dependency>用m…

5-Django项目--分页与搜索(资产页面)

目录 views/asset_data.py asset_data/asset_data.html 搜索与分页笔记: 搜索 整数搜索 字符串搜索 分页 views/asset_data.py # -*- coding:utf-8 -*- from django.shortcuts import render, redirect, HttpResponse from django.utils.safestring import mark_safe f…

MySQL查询数据库响应时长的方法

要查询MySQL数据库的响应时长&#xff0c;通常我们需要测量查询执行的时间。MySQL本身并不直接提供一个查询来显示每个查询的响应时长历史记录&#xff0c;但我们可以使用MySQL的内置函数和工具来测量和记录查询的执行时间。 以下是一些方法&#xff0c;我们可以用来测量MySQL…