第十八章、枚举
无论任何的数据,在计算机内都要用数字来表示。比如在表示性别时,我们用 1 表示男性,用 0 表示女性;表示成功还是失败时我们用 0 表示成功,-1 表示失败等。当我们打开之前写的程序时我们可能会发现我们写过如下的代码:
result = 0;
请问这个 0 是表示成功还是失败呢?当初我们是怎么定义这个 0 的含义呢?
为了提高代码的可读性,提高编写代码的效率。我们通常用标识符来表示数值,常用的方法有两种:
- 使用宏定义代替值,如:
#define SUCCESS (1)、#define ERROR (0)。 - 使用枚举类型,如:
enum {ERROR = 0, SUCCESS = 1};
当我们使用宏定义时。我们上述代码可以写成:
#define SUCCESS (1)
#define ERROR (0)
result = ERROR;
这样程序的可读性就好很多。
当让我们可以使用枚举类型,上面的代码依旧可以写成
enum {ERROR = 0, SUCCESS = 1};
result = ERROR;
以上两种写法都增强了代码的可读性。其中使用宏的方法是预处理阶段进行源码级提换,使用枚举则是在编译阶段进行数据处理。
这一章我们来学习 枚举类型。
1. 枚举
枚举(Enumeration) 是 C 语言中的一种基本数据类型,它主要用于定义一组标识符来代表整数常量。让代码更具可读性和可维护性。
语法:
enum [枚举类型名] {
枚举常量名1[ = 整数常量表达式1],
枚举常量名2[ = 整数常量表达式2],
...
} [变量名 [= 整数表达式]];
说明:
- 枚举有自己的类型,类型名为
enum 枚举类型名。 - 枚举类型名 必须是标识符,可以省略不写,省略不写则只能在声明时直接定义变量,后续不能使用类型名定义该类型的变量。
- 枚举常量 必须是标识符,它代表一个整数常量值,只能取值不能赋值。
- 枚举常量 如果没有给出初始值,则它的值是上一个 枚举常量 的值加 1。
- 第一个 枚举常量 如果没有给出初始值,则它的值是 0。
enum [枚举类型名] {...}部分是类型声明,后面可以定义该类型的变量,也可以直接用分号(;)结束声明。
例如:
// 声明一个枚举类型 WeekDay 表示一周中的星期几。
enum WeekDay {
Mon = 1, // Mon 值为1
Tue, // Tue 值为 2
Wed, // Wed 值为 3
Tru, // Tru 值为 4
Fri, // Fri 值为 5
Sat, // Sat 值为 6
Sun // Sun 值为 7
};
// 声明一个枚举类型 ReturnState,同时定义一个变量 result。
enum ReturnState{
DISABLE, // ERROR 值为 0
ENABLE = 2, // ENABLE 值为 2
OTHER_RESULT = -1 // OTHER_RESULT 值为 -1
} result;
// 声明两个枚举类型的常量值 ERROE 和 SUCCESS。
enum {
ERROR, // ERROR 值为 0
SUCCESS = !ERROR, // SUCCESS 值为 1
};
// 声明两个枚举类型的常量值 RESET 和 SET,同时定义一个变量 x, y;
enum {
RESET = -1, // RESET 值为 -1
SET // SET 值为 -1
} x, y;
使用枚举类型声明变量的语法:
enum 枚举类型名 变量名1 [= 整数表达式1][, 变量名1 [= 整数表达式1]]];
说明:
如果一个枚举类型在声明时没有给出类型名。则可以定义整数类型变量来保存其值。
示例
// filename: enumeration.c
#include <stdio.h>
// 声明一个枚举类型 WeekDay 表示一周中的星期几。
enum WeekDay {
Mon = 1, // Mon 值为1
Tue, // Tue 值为 2
Wed, // Wed 值为 3
Tru, // Tru 值为 4
Fri, // Fri 值为 5
Sat, // Sat 值为 6
Sun // Sun 值为 7
};
// 声明一个枚举类型 ReturnState,同时定义一个变量 result。
enum ReturnState{
DISABLE, // ERROR 值为 0
ENABLE = 2, // ENABLE 值为 2
OTHER_RESULT = -1 // OTHER_RESULT 值为 -1
} result;
// 声明两个枚举类型的常量值 ERROE 和 SUCCESS。
enum {
ERROR, // ERROR 值为 0
SUCCESS = !ERROR, // SUCCESS 值为 1
};
// 声明两个枚举类型的常量值 RESET 和 SET,同时定义一个变量 x, y;
enum {
RESET = 0,
SET = !RESET
} x, y;
int main(int argc, char * argv[]) {
enum WeekDay theday;
int ret = ERROR;
if (ret != SUCCESS) {
printf("result: %d\n", result);
}
x = SET;
printf("x: %d\n", SET);
printf("sizeof(x): %ld\n", sizeof(x));
printf("sizeof(SET): %ld\n", sizeof(SET));
for (theday = Mon; theday <= Sun; theday++) {
printf("theday: %d\n", theday);
}
return 0;
}
编译和运行结果如下:
result: 0
x: 1
sizeof(x): 4
sizeof(SET): 4
theday: 1
theday: 2
theday: 3
theday: 4
theday: 5
theday: 6
theday: 7
从容上述运行结果可知,枚举类型的枚举常量可以当做整数常量来使用。
枚举类型的变量 和 枚举常量 的类型在不同的编译器下使用的内存长度是不一致的。大多数编译器将枚举类型看做是整数(四个字节),但也会有编译器将枚举类型的变量用一个字节保存。具体要看编译器和枚举常量的值来决定。
练习:
声明枚举类型 Season 来表示季节中的 春、夏、秋、冬 四个常量值(用标识符表示)。然后定义变量保存其中的某一个值。