1.枚举是用来干嘛的?
枚举定义了一些符号,这些符号的本质就是int类型的常量,每个符号和一个常量绑定。这个符号就表示一个自定义的一个识别码,编译器对枚举的认知就是符号常量所绑定的那个int类型的数字。
举例:
#include <stdio.h>
// 这个枚举用来表示函数返回值,ERROR表示错,RIGHT表示对
enum return_value
{
ERROR, // 枚举值常量是全局的,直接自己就可以用。
RIGHT,
};
enum return_value func1(void);
int main(void)
{
enum return_value r = func1();
if (r == RIGHT) // 不是r.RIGHT,也不是return_value.RIGHT,跟结构体的使用方法不一样
{
printf("函数执行正确\n");
}
else
{
printf("函数执行错误\n");
}
printf("ERROR = %d.\n", ERROR); // 0
printf("RIGHT = %d.\n", RIGHT); // 1
return 0;
}
enum return_value func1(void)
{
enum return_value r1;
r1 = ERROR;
return r1;
}
2.C语言为何需要枚举
-> C语言没有枚举是可以的。使用枚举其实就是对1、0这些数字进行符号化编码,这样的好处就是编程时可以不用看数字而直接看符号。符号的意义是显然的,一眼可以看出。而数字所代表的含义除非看文档或者注释。
-> 宏定义的目的和意义是:不用数字而用符号。从这里可以看出:宏定义和枚举有内在联系。宏定义和枚举经常用来解决类似的问题,他们俩基本相当可以互换,但是有一些细微差别。
3.宏定义和枚举的区别
-> 枚举是将多个有关联的符号封装在一个枚举中,而宏定义是完全散的。也就是说枚举其实是多选一。
-> 什么情况下用枚举?当我们要定义的常量是一个有限集合时(譬如一星期有7天,譬如一个月有31天,譬如一年有12个月····),最适合用枚举。(其实宏定义也行,但是枚举更好)
4.枚举的定义和使用
#include "stdio.h"
/*
****************************************************************
* enumeration 类型定义
****************************************************************
*/
// 定义方法1,定义类型和定义变量分离开
enum week
{
SUN, // SUN = 0
MON, // MON = 1;
TUE,
WEN,
THU,
FRI,
SAT,
};
enum week today;
// 定义方法2,定义类型的同时定义变量
enum week
{
SUN, // SUN = 0
MON, // MON = 1;
TUE,
WEN,
THU,
FRI,
SAT,
}today,yesterday;
// 定义方法3,定义类型的同时定义变量
enum
{
SUN, // SUN = 0
MON, // MON = 1;
TUE,
WEN,
THU,
FRI,
SAT,
}today,yesterday;
// 定义方法4,用typedef定义枚举类型别名,并在后面使用别名进行变量定义
typedef enum week
{
SUN, // SUN = 0
MON, // MON = 1;
TUE,
WEN,
THU,
FRI,
SAT,
}week;
// 定义方法5,用typedef定义枚举类型别名,并在后面使用别名进行变量定义
typedef enum
{
SUN, // SUN = 0
MON, // MON = 1;
TUE,
WEN,
THU,
FRI,
SAT,
}week;
//错误类型举例
// 错误1,枚举类型重名,编译时报错:error: conflicting types for ‘DAY’
typedef enum workday
{
MON, // MON = 1;
TUE,
WEN,
THU,
FRI,
}DAY;
typedef enum weekend
{
SAT,
SUN,
}DAY;
// 错误2,枚举成员重名,编译时报错:redeclaration of enumerator ‘MON’
typedef enum workday
{
MON, // MON = 1;
TUE,
WEN,
THU,
FRI,
}workday;
typedef enum weekend
{
MON,
SAT,
SUN,
}weekend;
// 结构体中元素可以重名
typedef struct
{
int a;
char b;
}st1;
typedef struct
{
int a;
char b;
}st2;
// #define宏可以重复定义(没有error但是有warning),结果以最后一次定义为准。
#define MACRO1 12
#define MACRO1 24
// 测试代码
int main(int argc, char **argv)
{
printf("%d\n", MACRO1);
// 测试定义方法4,5
week today;
today = WEN;
printf("today is the %dth day in week\n", today);
// 测试定义方法2
today = WEN;
printf("today is the %dth day in week\n", today);
// 测试enum变量的类型
enum week w1;
w1 = TUE;
printf("%d\n", w1);
5.不能有重名的枚举类型。即在一个文件中不能有两个或两个以上的enum被typedef成相同的别名。
-> 这很好理解,因为将两种不同类型重命名为相同的别名,这会让gcc在还原别名时遇到困惑。比如你定义了typedef int INT; typedef char INT;
那么INT到底被译为int还是char呢?
6.不能有重名的枚举成员
-> struct类型成员的访问方式是:变量名.成员
,而enum成员的访问方式为:成员名
。因此若两个enum类型中有重名的成员,那代码中访问这个成员时到底指的是哪个enum中的成员呢?