C语言enum枚举类型

Last Updated: 2023-04-18 09:44:08 Tuesday

-- TOC --

本文总结C语言的enum枚举类型的使用,并扩展到C++的scoped enum类型。

C语言的enum类型(unscoped)

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
};

以上两种方式定义后,在代码中,从MONSUN,这7个符号都可以直接使用,都表示从1到7。

但还是有区别的:

请看下面的测试代码:

$ 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枚举类型的定义,看起来很像定义structunion,对吧?我故意将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++中,就应该只使用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 --