在实际编程中,我们经常需要定义一组具有关联性的整数常量,比如一周的天数、颜色选项、程序状态等。
如果直接使用 #define 定义宏常量,不仅繁琐,而且容易造成命名冲突。
枚举(enum) 是C语言提供的一种用户自定义数据类型,允许我们将一组相关的整型常量组织在一起,提高代码的可读性和可维护性。
本章将详细介绍枚举类型的定义、使用以及实际应用场景。
枚举类型使用 enum 关键字定义,语法如下:
enum 枚举名 {
常量1,
常量2,
...
};
例如,定义一个表示星期的枚举:
enum Weekday {
MON, // 默认值为 0
TUE, // 1
WED, // 2
THU, // 3
FRI, // 4
SAT, // 5
SUN // 6
};
枚举常量默认从0开始依次递增。也可以为枚举常量指定值:
enum Color {
RED = 1,
GREEN = 2,
BLUE = 4,
YELLOW = 8
};
未显式指定的枚举常量会在前一个值的基础上递增。
enum Example {
A = 5, // 5
B, // 6
C = 10, // 10
D // 11
};
定义了枚举类型后,可以像使用其他类型一样声明枚举变量:
enum Weekday today;
today = MON; // 赋值枚举常量
printf("%d\n", today); // 输出 0
也可以在定义枚举类型的同时声明变量:
enum Weekday { MON, TUE, WED } w1, w2;
在C语言中,枚举常量本质上是int类型的常量,枚举变量也可以被赋予整数值,但编译器可能发出警告(取决于编译选项)。
enum Weekday day = MON;
int x = day; // 枚举值可以赋给整型变量
day = 10; // 整型值也可以赋给枚举变量(通常允许,但应避免)
printf("%d\n", day); // 输出 10
枚举常量的整数值非常适合用于 switch 语句,提高代码可读性。
#include <stdio.h>
enum Operation {
ADD = 1,
SUBTRACT,
MULTIPLY,
DIVIDE
};
int main() {
int choice;
printf("1. 加法\n2. 减法\n3. 乘法\n4. 除法\n");
printf("请选择: ");
scanf("%d", &choice);
switch (choice) {
case ADD:
printf("执行加法\n");
break;
case SUBTRACT:
printf("执行减法\n");
break;
case MULTIPLY:
printf("执行乘法\n");
break;
case DIVIDE:
printf("执行除法\n");
break;
default:
printf("无效选择\n");
}
return 0;
}
枚举常用于表示状态,使状态转换清晰明了。
#include <stdio.h>
enum State {
STATE_IDLE,
STATE_RUNNING,
STATE_STOPPED,
STATE_ERROR
};
int main() {
enum State currentState = STATE_IDLE;
int command;
while (1) {
printf("当前状态: %d\n", currentState);
printf("请输入命令 (0:启动, 1:停止, 2:重置, 3:退出): ");
scanf("%d", &command);
switch (currentState) {
case STATE_IDLE:
if (command == 0) currentState = STATE_RUNNING;
break;
case STATE_RUNNING:
if (command == 1) currentState = STATE_STOPPED;
else if (command == 2) currentState = STATE_IDLE;
break;
case STATE_STOPPED:
if (command == 0) currentState = STATE_RUNNING;
else if (command == 2) currentState = STATE_IDLE;
break;
case STATE_ERROR:
// 处理错误
break;
}
if (command == 3) break;
}
return 0;
}
枚举常量可以定义为2的幂次,用于位掩码操作。
#include <stdio.h>
enum Options {
OPT_NONE = 0,
OPT_READ = 1 << 0, // 1
OPT_WRITE = 1 << 1, // 2
OPT_APPEND = 1 << 2, // 4
OPT_BINARY = 1 << 3 // 8
};
int main() {
int flags = OPT_READ | OPT_WRITE; // 组合标志
if (flags & OPT_READ) {
printf("读取模式开启\n");
}
if (flags & OPT_WRITE) {
printf("写入模式开启\n");
}
return 0;
}
在C99引入 stdbool.h 之前,常用枚举表示布尔值。
enum Bool {
FALSE,
TRUE
};
enum Bool isEven(int n) {
return (n % 2 == 0) ? TRUE : FALSE;
}
如果只需要一组常量而不需要定义枚举类型变量,可以使用无名枚举。
enum {
MAX_SIZE = 100,
BUFFER_SIZE = 1024,
TIMEOUT = 30
};
int arr[MAX_SIZE]; // 直接使用常量
#include <stdio.h>
enum CalcState {
STATE_START,
STATE_FIRST_NUM,
STATE_OPERATOR,
STATE_SECOND_NUM,
STATE_RESULT
};
int main() {
enum CalcState state = STATE_START;
double num1 = 0, num2 = 0, result = 0;
char op = 0;
char input[10];
while (1) {
switch (state) {
case STATE_START:
printf("请输入第一个数字: ");
scanf("%lf", &num1);
state = STATE_OPERATOR;
break;
case STATE_OPERATOR:
printf("请输入运算符 (+, -, *, /): ");
scanf(" %c", &op);
if (op == '+' || op == '-' || op == '*' || op == '/') {
state = STATE_SECOND_NUM;
} else {
printf("无效运算符\n");
}
break;
case STATE_SECOND_NUM:
printf("请输入第二个数字: ");
scanf("%lf", &num2);
switch (op) {
case '+': result = num1 + num2; break;
case '-': result = num1 - num2; break;
case '*': result = num1 * num2; break;
case '/':
if (num2 != 0) result = num1 / num2;
else printf("除数不能为0!\n");
break;
}
state = STATE_RESULT;
break;
case STATE_RESULT:
printf("结果: %.2f\n", result);
printf("是否继续? (y/n): ");
scanf(" %c", input);
if (input[0] == 'y' || input[0] == 'Y') {
state = STATE_START;
} else {
printf("程序结束\n");
return 0;
}
break;
}
}
return 0;
}
int 相同,但取决于编译器,不建议依赖特定大小。枚举类型是C语言中提升代码可读性和可维护性的重要工具,尤其适合表示状态、选项和固定集合。 合理使用枚举可以使代码更加清晰,减少魔法数字的出现。下一章我们将学习文件操作,实现数据的持久化存储。