枚举类型enum详解——C语言
enum
enum是C语言中的一个关键字,enum叫枚举数据类型,枚举数据类型描述的是一组整型值的集合(这句话其实不太妥当),枚举型是预处理指令#define的替代,枚举和宏其实非常类似,宏在预处理阶段将名字替换成对应的值,枚举在编译阶段将名字替换成对应的值,
我们可以将枚举理解为编译阶段的宏,使用格式:
enum typeName{ valueName1, valueName2, valueName3, ...... };
typeName是枚举类型的名字,花括号里面的元素(枚举成员)是常量而不是变量,这个一定要搞清楚,因为枚举成员的是常量,所以不能对它们赋值,只能将它们的值赋给其他的变量
枚举类型(枚举标签)、枚举成员(枚举常量)、枚举变量之间的区别

当枚举类型和枚举变量放在一起定义时,枚举类型的名字(就是enum week中的week)可以省略不写,意思是上图的有两种写法
第一种:
enum week{Mon = , Tues, Wed, Thurs}num;
第二种:
enum {Mon = , Tues, Wed, Thurs}num;
这一点其实和结构体中的无名结构很相似,虽然定义枚举类型变量和定义结构类型变量看起来很相似,但是两者的区别还是蛮大的,一个结构体类型变量里面包含若干个成员,相当于一个打包好的快递盒子,
而枚举类型变量就不一样了,枚举类型变量不是一个包含若干个成员的集合,枚举类型变量和int、char类型的变量其实差不多,只不过枚举类型变量的赋值只能用自身的枚举成员来赋值,以上面的例子来说,
num的赋值就只能用枚举成员Mon、Tues、Wed、Thurs,而不能用其他枚举类型的枚举成员来赋值
定义枚举变量和定义结构体变量相同,有两种定义方法
第一种:(定义枚举类型的同时定义枚举变量)
enum week{Mon = , Tues, Wed, Thurs}num;
第二种:(先定义枚举类型,再定义枚举变量)
enum week{Mon = , Tues, Wed, Thurs};
enum week num;
枚举类型的特点
下面将用不同的示例来说明枚举类型的特点
示例一:(不显式说明枚举常量的值)
enum week{Mon, Tues, Wed, Thurs, Fri, Sat, Sun};
在没有显示说明的情况下,枚举常量(也就是花括号中的常量名)默认第一个枚举常量的值为0,往后每个枚举常量依次递增1,所以Mon=0,Tues=1,····Sun=6,下面来验证一下
enum week{Mon, Tues, Wed, Thurs, Fri, Sat, Sun};
printf("Mon=%d\nTues=%d\nWed=%d\nThurs=%d\nFri=%d\nSat=%d\nSun=%d\n", Mon, Tues, Wed, Thurs, Fri, Sat, Sun);
运行结果:

示例二:(显示说明部分枚举常量的值)
enum week{Mon = , Tues, Wed, Thurs, Fri, Sat, Sun};
上面的代码中,只显式说明了枚举常量Mon的值为1,未指定的枚举名的值将依着最后一个指定值向后依次递增(注意是最后一个指定值)
enum week{Mon = , Tues, Wed, Thurs, Fri, Sat, Sun};
printf("Mon=%d\nTues=%d\nWed=%d\nThurs=%d\nFri=%d\nSat=%d\nSun=%d\n", Mon, Tues, Wed, Thurs, Fri, Sat, Sun);
运行结果:

对上面的代码稍加修改
enum week{Mon = , Tues, Wed, Thurs, Fri = , Sat, Sun};
printf("Mon=%d\nTues=%d\nWed=%d\nThurs=%d\nFri=%d\nSat=%d\nSun=%d\n", Mon, Tues, Wed, Thurs, Fri, Sat, Sun);
运行结果:

示例三:(对枚举变量进行赋值)
enum week{Mon = , Tues, Wed, Thurs}num;
num = (enum week);
printf("%d", num);
一个整数不能直接赋值给一个枚举变量,必须用该枚举变量所属的枚举类型进行类型强制转换后才能赋值,上面的代码中,在对枚举变量赋值10的时候进行的强制类型转换,将整型常量10转换成了enum week类型再赋值给num变量,
运行结果:

总结:
1、在没有显示说明的情况下,枚举常量(也就是花括号中的常量名)默认第一个枚举常量的值为0,往后每个枚举常量依次递增1
2、在部分显示说明的情况下,未指定的枚举名的值将依着之前最有一个指定值向后依次递增
3、一个整数不能直接赋值给一个枚举变量,必须用该枚举变量所属的枚举类型进行类型强制转换后才能赋值
4、同一枚举类型中不同的枚举成员可以具有相同的值
5、同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的枚举成员(枚举常量)
enum与typedef配合使用
typedef enum week my;
或者
typedef enum week{Mon = , Tues, Wed, Thurs}my;
上面typedef也可以省略week
typedef enum{Mon = , Tues, Wed, Thurs}my;
上面两种形式中,my都是enum week的别名(意思是my和enum week等价),需要注意的是如果将第二句的typedef去掉那么my就变成了enum week类型的变量,如果加上typedef那么my就是enum的别名,这点要注意区分
在定义了enum week的别名my后,后面就可以使用my来定义枚举类型变量
my num; num = (enum week);
printf("%d", num);
上述语句中的(enum week),可以改为(my),两者效果是一样的
补充:对上面总结的第五点:同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的枚举成员(枚举常量),进行验证
enum m1{m1, m2};
enum m2{m3, m4};
enum m1{m5, m6};
上述代码定义的枚举类型enum m1多次定义,是不允许的,编译器会报错
还有一种特殊情况,即使定义了同名的枚举类型,编译器也不会报错
enum m1{m1, m2};
enum m2{m3, m4};
enum m1;
上面的代码中,第二个enum m1没有定义枚举成员,在编译阶段是不会报错的(估计是编译器并不认为定义了枚举成员的enum m1 和 没有定义枚举成员的enum m1是同名的枚举类型)

enum的赋值范围
这个也是无意间注意到的,文章在开头提到枚举类型描述的是一组整型值的集合,枚举类型的占的字节数是4个字节,所以我们可以用INT_MAX和INT_MIN来测试枚举类型的赋值范围,赋值的最大值应该是INT_MAX(也就是2147483647),下面用代码来测试一下
enum test{m1=INT_MAX};
printf("%d\n%d\n", m1, INT_MAX);
运行结果:

上面的代码没有问题,下面来测试一下越界的赋值
enum test{m1=INT_MAX+};
printf("%d\n%d\n", m1, INT_MAX);
编译器在编译阶段会有警告
,测试了枚举类型的最大值,下面来测试下枚举类型的最小值
enum test{m1=INT_MIN};
printf("%d\n%d\n", m1, INT_MIN);
运行结果:

上面的代码没有问题,下面来测试一下越界的赋值
enum test{m1=INT_MIN-};
printf("%d\n%d\n", m1, INT_MIN);
和上面相同,编译器也会有警告
为什么“枚举类型描述的是一组整型值的集合”其实不太妥当?
上面这句话很容易让读者以为enum类型和int类型是等价的,好像可以把int型的数据直接赋值给enum变量,实际上是不行的,需要进行强制类型转换,C语言提供了一种称为“枚举”的类型,其中一个枚举常量的占的字节数为4个字节,恰好和int类型的变量占的字节数相同,假设把这些枚举常量说明为整型,字符型或其他类型显然是不妥当的,因为枚举类型是一种基本数据类型,而不是一种构造类型,它不能再分解为什么基本类型
枚举类型enum详解——C语言的更多相关文章
- Java 枚举(enum) 详解7种常见的用法
Java 枚举(enum) 详解7种常见的用法 来源 https://blog.csdn.net/qq_27093465/article/details/52180865 JDK1.5引入了新的类型— ...
- 详解 Go 语言中的 time.Duration 类型
swardsman详解 Go 语言中的 time.Duration 类型swardsman · 2018-03-17 23:10:54 · 5448 次点击 · 预计阅读时间 5 分钟 · 31分钟之 ...
- Scala 深入浅出实战经典 第53讲:Scala中结构类型实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- 详解go语言的array和slice 【二】
上一篇已经讲解过,array和slice的一些基本用法,使用array和slice时需要注意的地方,特别是slice需要注意的地方比较多.上一篇的最后讲解到创建新的slice时使用第三个索引来限制sl ...
- JS类型转换规则详解
JS类型转换规则详解 一.总结 一句话总结:JS强制类型转换中的类型名强制类型转换和其它语言不同,是类型类的构造方法,Number(mix) 一句话总结(JS类型本质):因为js是弱类型语言,所以它相 ...
- 详解Go语言调度循环源码实现
转载请声明出处哦~,本篇文章发布于luozhiyun的博客: https://www.luozhiyun.com/archives/448 本文使用的go的源码15.7 概述 提到"调度&q ...
- Scala 深入浅出实战经典 第54讲:Scala中复合类型实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- 【转】java枚举类型enum的使用
原文网址:http://blog.csdn.net/wgw335363240/article/details/6359614 java 枚举类型enum 的使用 最近跟同事讨论问题的时候,突然同事提到 ...
- C# 中的枚举类型 enum (属于值类型)
原文 C# 中的枚举类型 enum (属于值类型) C# 支持两种特殊的值类型:枚举和结构. 声明枚举:声明时要声明所有可能的值. using System; using System.Collect ...
随机推荐
- json&pickle&shelve模块
之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了 ...
- Nmap扫描命令使用详解
Nmap扫描基础扫描 当用户对Nmap工具了解后,即可使用该工具实施扫描.通过上一章的介绍,用户可知Nmap工具可以分别对主机.端口.版本.操作系统等实施扫描.但是,在实施这些扫描工作之前,需要先简单 ...
- Intersect交集Except差集Union并集实例
int[] oldArray = { 1, 2, 3, 4, 5 };int[] newArray = { 2, 4, 5, 7, 8, 9 };var jiaoJi = oldArray.Inter ...
- jQuery的appendTo案例
案例要求:点击双击第一个下拉列表框的选项可以把对应选项移到第二个下拉列表框中,选中第一个列表框的选项(可多选)单击-->按钮可使被选中项移动到右边下拉列表框中,单击==>按钮时将左边的所有 ...
- 设置同一个域名同一个源通过cdn用不同的端口访问网站设置
下图例子是设置80和88访问,因为80是默认的访问,所以只要设置88就行 进入站点管理-->应用防火墙-->高级设置 这个设置用到了url和host模块 在站点设置里设置要用到的端口:
- python--第九天总结
python 多进程和多线程 多线程可以共享全局变量,多进程不能.多线程中,所有子线程的进程号相同:多进程中,不同的子进程进程号不同. [多进程] Python在2.6引入了多进程的机制,并提供了丰富 ...
- Pandas.Series.dt.dayofweek相关命令
- sqlserver2017 重装过程中出现“无法找到数据库引擎启动句柄”错误的解决办法
sqlserver数据库引擎修改账号名,详情参考:http://blog.51cto.com/djclouds/2089047?utm_source=oschina-app 在SQL Server安装 ...
- SpringBoot集成Jasypt安全框架,配置文件内容加密
我们在SpringBoot项目中的yml或者properties配置文件中都是明文的,相对而言安全性就低了很多.都知道配置文件中的都是一些数据库连接用户名密码啊.一些第三方密钥等信息.所以我们谨慎点, ...
- Django模型层(2)
<!DOCTYPE html><html lang="zh-cn"><head><meta charset="utf-8&quo ...