4.5.15.枚举

转载至朱老师课件


4.5.15.枚举
4.5.15.1、枚举是用来干嘛的?
(1)枚举在C语言中其实是一些符号常量集。直白点说:枚举定义了一些符号,这些符号的本质就是int类型的常量,每个符号和一个常量绑定。这个符号就表示一个自定义的一个识别码,编译器对枚举的认知就是符号常量所绑定的那个int类型的数字。
(2)枚举中的枚举值都是常量,怎么验证?
(3)枚举符号常量和其对应的常量数字相对来说,数字不重要,符号才重要。符号对应的数字只要彼此不相同即可,没有别的要求。所以一般情况下我们都不明确指定这个符号所对应的数字,而让编译器自动分配。(编译器自动分配的原则是:从0开始依次增加。如果用户自己定义了一个值,则从那个值开始往后依次增加)
4.5.15.2、C语言为何需要枚举
(1)C语言没有枚举是可以的。使用枚举其实就是对1、0这些数字进行符号化编码,这样的好处就是编程时可以不用看数字而直接看符号。符号的意义是显然的,一眼可以看出。而数字所代表的含义除非看文档或者注释。
(2)宏定义的目的和意义是:不用数字而用符号。从这里可以看出:宏定义和枚举有内在联系。宏定义和枚举经常用来解决类似的问题,他们俩基本相当可以互换,但是有一些细微差别。
4.5.15.3、宏定义和枚举的区别
(1)枚举是将多个有关联的符号封装在一个枚举中,而宏定义是完全散的。也就是说枚举其实是多选一。
(2)什么情况下用枚举?当我们要定义的常量是一个有限集合时(譬如一星期有7天,譬如一个月有31天,譬如一年有12个月····),最适合用枚举。(其实宏定义也行,但是枚举更好)
(3)不能用枚举的情况下(定义的常量符号之间无关联,或者无限的)用宏定义。
总结:宏定义先出现,用来解决符号常量的问题;后来人们发现有时候定义的符号常量彼此之间有关联(多选一的关系),用宏定义来做虽然可以但是不贴切,于是乎发明了枚举来解决这种情况。

4.5.15.3、枚举的定义和使用

#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);
*/	
} 



/*
 *测试结论记录
 *******************************************************************
 1、编译以下代码
	enum week w1;		
	w1 = TUE;		
	printf("%s\n", w1);		
出现警告,enum.c:28: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘unsigned int’ 
分析:典型的格式化输出和类型不匹配,从警告信息可以看出enum变量的类型为unsigned int
	既然是unsigned int,那自然使用%d打印是正确的了。

2、不能有重名的枚举类型。即在一个文件中不能有两个或两个以上的enum被typedef成相同的别名。
分析:这很好理解,因为将两种不同类型重命名为相同的别名,这会让gcc在还原别名时遇到困惑。比如你定义了
typedef int INT;	typedef char INT; 那么INT到底被译为int还是char呢?
3、不能有重名的枚举成员。
分析:经过测试,两个struct类型内的成员名称可以重名,而两个enum类型中的成员不可以重名。实际上从两者的成员
在访问方式上的不同就可以看出了。struct类型成员的访问方式是:变量名.成员,而enum成员的访问方式为:成员名。
因此若两个enum类型中有重名的成员,那代码中访问这个成员时到底指的是哪个enum中的成员呢?
两个#define宏定义是可以重名的,该宏名真正的值取决于最后一次定义的值。编译器会给出警告但不会error

 ********************************************************************
 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值