C语言系列文章之enum

版权声明:本文为博主 Osprey 原创文章,转载请联系博主! https://blog.csdn.net/weixin_42876465/article/details/88068541

枚举,顾名思义,就是把一个个可能的值列举出来,它们占用的空间是同一个。这个功能和 #define 有些相似,但又不完全一样,#define 是专业替换户,列举可能的值只是它的其中一种运用方式罢了(关于 #define,可以查看 define 小节)。

怎么理解呢?就比如一个玻璃瓶,你规定只能用它装水、饮料、酒这三样东西(枚举所有可能值)。当你装了水之后,如果你想用它装饮料的话,你就只能把水倒掉之后才能再装饮料,否则就变味了(可能还要再清洗一下,说笑的)。同理装酒也是一样的道理,一次只能装一样东西。

还是照旧,先看它的使用:
在这里插入图片描述
这是最常用的枚举。现在来分析一下。

和结构体、联合体不同,每个列举的值后面是逗号而不是分号,这是因为它不是声明的变量,也没有占用多个内存空间,FALSE 和 TRUE 也不是同时挤在同一个空间里面,而是这个空间的值要么是 FALSE,要么是 TURE (注意这里的 TRUE 等于 0x01,而不是 0xFF),不可能是其它值(使用强制转换的话另说)。

比如说在上面的基础上声明一个枚举变量 State:
在这里插入图片描述
对它先后进行两次赋值之后, State 的值就是最后赋值的 TRUE,不会说可能是 FALSE。其实枚举变量和普通的变量没多大区别,只是说程序员在对它进行赋值的时候会受到一些限制:这个变量只能是枚举的那些值,不应该是其他(强制转换能把这枚举变量的值变成其他可能的值,比如说我可以把常数 2 强制转为 State_t 枚举型,这样 State 变量里面存的值就是 2 了,关于强制转换我会用另一小节详细说明)。

如果你把非枚举的值赋值给这个枚举变量的话,那么是会出现警告的:
在这里插入图片描述

而如果你确定这个值 0 是没有问题的(因为 FLASE 就是 0 啊),那么可以使用强制转换(像这样 State = (State_t) 0;),但最好不要这么做,不然你干嘛要用枚举呢?

这里虽然 FALSE 的值就是 0,但是你不能用 0 去赋值,而必须使用 FALSE 赋值,因此我们可以利用这个特性,让编译器去检查这个枚举变量的值,如果我们一时头脑发热将某个没枚举的值赋值给这个枚举变量了,那么编译器是能检查出来的,所以对于某些存储具有固定可能值的变量最好使用枚举变量。另外使用枚举还有一个好处就是,你能在调试窗口看到这个值代表什么:
在这里插入图片描述
这样你就不用去查 0x01 代表什么了。

现在应该大概懂了枚举变量的特点了吧,也应该知道是怎么回事,现在往细了说。

首先,每一个枚举值都会在前一个基础上递增,如果第一枚举值没有指定值,那么就是 0,如果指定是负数,后面的值也会从负数的基础上地递增。
在这里插入图片描述
并且这些值都没有超过 255,所以编译器给它分配的空间大小就是 1 字节。

如果超过了 255,比如有一个枚举值你设置为 256,那么这个枚举变量的大小就是两个字节,因为 256 已经超过一个字节可表示的范围了,这个可通过 sizeof() 验证。
在这里插入图片描述
还有枚举一般使用大写表示,这是因为常数一般采用大写,就像宏 #define 一样采用大写。并且这个名称不能和其他宏或者枚举重复,比如枚举值 ZERO,不能再用宏 #define 去定义一个 ZERO,这个是会报错的(这个错误可以通过全工程搜索解决,一旦发现有两处定义,那么删掉其中之一就可以了),但是如果是几个没有关联的文件之间的宏或者枚举值相同的话倒是无所谓,如果是关联的,那么这几个文件之间的定义只能存其一。比如说 main.c 文件声明(枚举或宏)了一个 ZERO, app.h 也申明(枚举或宏)了一个 ZERO,如果 main.c 用 #include<app.h> 包含了这个文件,那么它们就产生了关联,必然出现冲突,但是如果说你没用 #include 包含 app.h,也没有通过其他文件间接包含 app.h,那么是不会有问题的。这个问题你不用管,交给编译器就行了,如果出现了冲突会告诉你的。
在这里插入图片描述
利用手机碎片化阅读,请关注微信公众号:鱼鹰谈单片机
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42876465/article/details/88068541
今日推荐