Last Updated: 2023-04-18 09:44:08 Tuesday
-- TOC --
本文总结C语言的enum枚举类型的使用,并扩展到C++的scoped enum类型。
C语言的enum枚举类型跟直接使用#define差不多,定义enum枚举类型与定义struct或union很相似。
为什么说enum枚举类型跟#define
差不多?
#define MON 1
#define TUE 2
#define WED 3
#define THU 4
#define FRI 5
#define SAT 6
#define SUN 7
与下面的enum枚举类型比较:
enum DAY {
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
以上两种方式定义后,在代码中,从MON
到SUN
,这7个符号都可以直接使用,都表示从1到7。
但还是有区别的:
#define
定义的内容只是文本替换,没有类型的概念;请看下面的测试代码:
$ cat test_enum.c
#include <stdio.h>
enum seq {
A, // default is zero.
B,
C=5,
D,
};
int main(void) {
enum seq a = A;
enum seq b = B;
enum seq c = C;
enum seq d = D;
printf("%d %d %d %d\n", a, b, c, d);
return 0;
}
$ clang -Wall -Wextra test_enum.c -o enum
$ ./enum
0 1 5 6
这是我第一次使用clang编译代码,clang与gcc在Linux平台下是竞争关系,这很nice,clang的参数基本上与gcc一样,迁移无压力,唯一能看出区别的地方,是这两个编译器生成的输出大小有点不一样。
enum枚举类型的定义,看起来很像定义struct或union,对吧?我故意将ABCD竖着写出来的。:)
注意A默认从0开始,然后逐个+1,中间任意位置也可以指定一个特定的值,这个位置后面的符号根据前面的值做+1。
代码中,直接使用ABCD,他们就像是#define定义的macro,但不是文本替换。
枚举变量与一个int变量差不多,请看如下代码:
$ cat test_enum.c
#include <stdio.h>
enum seq {
A, // default is zero.
B,
C=5,
D,
};
int main(void) {
enum seq a = 1;
printf("%d\n", a);
enum seq b = 99;
printf("%d\n", b);
enum seq c = -1;
printf("%d\n", c);
int d = D;
printf("%d\n", d);
return 0;
}
$ gcc -Wall -Wextra test_enum.c -o enum
$ ./enum
1
99
-1
6
看起来enum枚举类型的作用,就是比直接使用#define更方便一些了,我在自己编程实践中,确实也很少用到enum枚举类型。
C语言中的enum枚举类型,在C++的概念范畴类,叫做unscoped enum类型,unscoped的含义很容易理解,enum枚举类型中定义的ABCD,就如全局可用的int。
在C++中,就应该只使用scoped enum类型,除非是为了跟C代码交互。
而C++另外定义了一个scoped enum类型,请看下面的测试代码:
$ cat test_enum.cpp
#include <cstdio>
enum class seq {
A, // default is zero.
B,
C=5,
D,
};
int main(void) {
enum seq a = seq::A;
enum seq b = seq::B;
enum seq c = seq::C;
enum seq d = seq::D;
printf("%d %d %d %d\n", a,b,c,d);
//enum seq a2 = 1; // error, int cannot convert to enum class seq
//int b2 = seq::B; // error, enum class seq cannot convert to int
return 0;
}
在C++中,所谓的scoped enum,就是要类型匹配,type match。enum类型的变量,只能有enum值,非enum类型的变量,不能有enum的值。
C++中的type非常严格,以上代码最后注释掉的两行,都会触发编译错误。
本文链接:https://cs.pynote.net/sf/c/202208031/
-- EOF --
-- MORE --