在前面,我们已经对C语言的结构体有了细致的了解,今天我们继续学习下一个C语言自定义数据类型------枚举类型。
目录
规则二:枚举类型后面的值会在前面值的基础上依次递增1个单位;
规则三:枚举类型的值可被手动指定,且由于规则二存在,这可能会连贯地影响后面枚举常量的值
一、什么是枚举:
枚举,顾名思义就是一一列举,针对某一类群体,把它所有可能的取值一一列举出来。
我们日常生活中其实有很多这样的可以被枚举出来的例子:比如说人的性别有男有女,再例如说颜色有三原色------红色(Red),绿色(Green),蓝色(Blue)......
在C语言里面,我们用enum关键字来声明一个枚举类型。如下是"Color"的枚举类型的声明:
cpp
enum Color
{
RED,
GREEN,
BLUE
};
然后和结构体是一样的,未来如果你想去定义一个枚举类型的变量,你不能说我直接Color c,注意Color,enum Color才是一个完整的数据类型!!!
二、枚举类型的特性:
(1)枚举类型是本质是int:
首先在这里我们要给大家建立一个认识,即:C语言里所有的自定义类型都是在内置类型(int,double,char)的基础上形成的。无论未来你写的自定义类型有多花,最后都得落实到一个具体的自定义类型!
强如枚举类型,也仅仅只是C语言中某个内置类型的抽象结果罢了,而这个内置类型正是我们的int。
有了上面的理解你就能很快地理解下面这段代码的输入和输出:
cpp
#include<stdio.h>
enum Color
{
RED,
GREEN,
BLUE
};
int main()
{
enum Color c1 = RED;
//这里会先打印一个int类型的值:
printf("%d\n", c);
//这里会得到"4"这样的结果:
printf("sizeof(c) == %zd", sizeof(c));
//下面这种写法是允许的:另一方面,对于类型检查很严格的C++编译器这可能不让通过。
int s = GREEN;
enum Color c2 = 30;
return 0;
}
(2)枚举类型值的设计规则:
关于枚举类型值的设计规则,我们一般只想谈以下三点:
规则一:枚举类型的第一个值,如果你不指定的话,往往是0:
cpp
#include<stdio.h>
enum Color
{
RED,
GREEN,
BLUE
};
int main()
{
printf("%d", RED);
return 0;
}
运行结果

规则二:枚举类型后面的值会在前面值的基础上依次递增1个单位;
cpp
#include<stdio.h>
enum Color
{
RED,
GREEN,
BLUE
};
int main()
{
printf("%d\n", RED);
printf("%d\n", GREEN);
printf("%d", BLUE);
return 0;
}
运行结果

规则三:枚举类型的值可被手动指定,且由于规则二存在,这可能会连贯地影响后面枚举常量的值
cpp
#include<stdio.h>
enum Color
{
RED,
GREEN = -1,
BLUE
};
int main()
{
printf("%d\n", RED);
printf("%d\n", GREEN);
printf("%d", BLUE);
return 0;
}
运行结果

(3)枚举类型声明的是常量:
以enum Color为例子,枚举类型里所声明的RED,GREEN...其实是一个个的int类型的常量(因此枚举也叫枚举常量),由于是常量,所以枚举类型的值不能被修改!因此下面这种写法是不被允许的:
cpp
#include<stdio.h>
enum Color
{
RED,
GREEN,
BLUE
};
int main()
{
//ERROR:枚举类型是常量,它的值不能被修改:
BLUE = 10;
}
(4)枚举类型的初始化:
枚举类型本质是int类型,所以一个枚举类型的变量在初始化时,既可以用所声明的枚举常量来初始化,也可以用int类型的字面常量来初始化。
即:下面这两种写法在C语言层面都是正确的(C++编译器对类型检查更严格,可能不让通过):
cpp
//用枚举常量初始化枚举变量:
enum Color c1 = RED;
//用int类型的字符常量来初始化枚举变量:
enum Color c2 = 30;
三、枚举类型的优势:
枚举类型出来的那些东西是常量,嗯......OK既然是常量的话,这好像和#define声明标识符常量也没什么两样啊。
那在这里呢,枚举类型相比#define定义的表示符常量还是有一些不可替代的优势在里面,一般来说枚举类型有以下几点优势:
- 和#define相比,枚举类型有类型检查,而#define的做法是直接替换,不够严谨;
- #define定义的常量在调试阶段会被替换,而枚举常量不会,相较之下,枚举常量更有利于调试。
- 枚举常量的使用更加方便,可以一次性定义多个常量,而#define的标识符常量一次只能定义一个。