博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言枚举类型
阅读量:6892 次
发布时间:2019-06-27

本文共 5507 字,大约阅读时间需要 18 分钟。

hot3.png

C语言枚举类型


在讲枚举之前,我们先来看一个案例,它能帮助我们更好的理解C设计枚举的意图。假设我们在程序中要分别表示星期一到星期天这一周,也许我们可以这样做:

#include
#include
#define MON 1#define TUE 2#define WED 3#define THU 4#define FRI 5#define SAT 6#define SUN 7void printf_today(int day);int main(void) { int today = FRI; printf_today(today); return 0;}void printf_today(int day) { char today[10]; switch(day) { case MON: strcpy(today, "monday"); break; case TUE: strcpy(today, "tuesday"); break; case WED: strcpy(today, "wednesday"); break; case THU: strcpy(today, "thursday"); break; case FRI: strcpy(today, "friday"); break; case SAT: strcpy(today, "saturday"); break; case SUN: strcpy(today, "sunday"); break; default: strcpy(today, "unknowday"); } printf("today is %s\n", today);}

上例程序用来打印今天是星期几,定义一系列的宏的好处是,即使把星期对应的数值改掉,也不用修改printf_today()函数中的代码。也就是说,你以后可以把宏定义改成这样:

#define	SUN	0#define	MON	1#define	TUE	2#define	WED	3#define	THU	4#define	FRI	5#define	SAT	6

无论怎么修改宏定义,都不会影响以上程序的功能。但是也有一个缺点,需要定义好多个宏才能完成工作。C语言定义一种新的数据类型,希望它能完成同样的工作,这种新的数据类型叫枚举型。

我们先来看枚举是如何改善以上程序的:

#include
#include
enum days {SUN, MON, TUE, WED, THU, FRI, SAT};void printf_today(int day);int main(void) { int today = FRI; printf_today(today); return 0;}void printf_today(int day) { /*...省略...*/}

以上程序只是简单地把宏定义换成enum days {SUN, MON, TUE, WED, THU, FRI, SAT};枚举定义,运行结果仍然是一样的。从以上程序我们可以看出枚举类型中的成员是一些命名的整型常量。

枚举的概念

枚举是一种自定义的数据类型,它用来存储一系列命名整型常量的值,可以通过成员名字来引用这些值,这些值默认是signed int类型。 虽然枚举能表示一系列的整型常量,但是每次只能使用其中一个具体的常量值。也就是说一个枚举变量的值只能是枚举中的一个命名常量的值。从这个角度理解,枚举更像是定义了一种取值范围有限的整型。

定义枚举类型

下面的代码定义一种枚举类型:

#include
enum fruit {grape, cherry, lemon, kiwi};int main(void) { printf("grape = %d\n", grape); printf("cherry = %d\n", cherry); printf("lemon = %d\n", lemon); printf("kiwi = %d\n", kiwi); return 0;}

输出结果:

grape  = 0cherry = 1lemon  = 2kiwi   = 3

上例定了一个枚举fruit,它包含四个整型常量值,grape, cherry, lemon, kiwi。从输出结果可以看出它们的值依次是0,1,2,3。修改上例程序:

#include
enum fruit {grape, cherry, lemon, kiwi};enum more_fruit {banana = -17, apple, blueberry, mango};int main(void) { printf("grape = %d\n", grape); printf("cherry = %d\n", cherry); printf("lemon = %d\n", lemon); printf("kiwi = %d\n", kiwi); printf("\n"); printf("banana = %d\n", banana); printf("apple = %d\n", apple); printf("blueberry = %d\n", blueberry); printf("mango = %d\n", mango); return 0;}

输出结果:

grape  = 0cherry = 1lemon  = 2kiwi   = 3banana     = -17apple      = -16blueberry  = -15mango      = -14

从以上两例可以看出,枚举中值默认是从0开始的,后一个值在前一个基础上自动加1,你也可以手动指定其中某一个量的值。再次修改程序:

#include
enum fruit {grape, cherry, lemon, kiwi};enum more_fruit {banana = -17, apple, blueberry, mango};enum yet_more_fruit {kumquat, raspberry, peach, plum = peach + 2}; int main(void) { printf("grape = %d\n", grape); printf("cherry = %d\n", cherry); printf("lemon = %d\n", lemon); printf("kiwi = %d\n", kiwi); printf("\n"); printf("banana = %d\n", banana); printf("apple = %d\n", apple); printf("blueberry = %d\n", blueberry); printf("mango = %d\n", mango); printf("\n"); printf("kumquat = %d\n", kumquat); printf("raspberry = %d\n", raspberry); printf("peach = %d\n", peach); printf("plum = %d\n", plum); return 0;}

输出结果:

grape  = 0cherry = 1lemon  = 2kiwi   = 3banana     = -17apple      = -16blueberry  = -15mango      = -14kumquat         = 0raspberry       = 1peach           = 2plum            = 4

上例说明,枚举定义中一个枚举成员值可以引用另一个,正确的讲应该是后面的可以引用前面的。

声明枚举变量

定义枚举类型后,你可以声明一个枚举类型的变量。下面的例子声明了一个枚举变量,枚举类型的定义和变量的声明可以在一个语句中完成:

/*定义类型同时声明变量*/enum fruit {banana, apple, blueberry, mango} my_fruit;/*定义类型*/enum fruit {banana, apple, blueberry, mango};/*声明变量*/enum fruit my_fruit;

虽然在前面我们讲枚举实际上取值范围有限的整型,但这只是C语言推荐的一种类型,它并不会检查枚举类型变量的取值是否是枚举中定义过的值。C语言把这些检查交给程序员去做,这也体验了C高性能的设计决策。如下例所示:

#include
enum fruit {grape, cherry, lemon, kiwi}; int main(void) { enum fruit myf = cherry; myf = 30; printf("myf = %d\n", myf); return 0;}/* 输出结果: myf = 30 */

这样我们就能看到C语言枚举类型的本质就是一个整型,枚举成员只是为了更好的辅助编程,提高可读性和拓展性。枚举成员就是一系列的命名整型常量。它们的值是只读的,不能被修改。另外,在switch语句中使用枚举对编译器比较友好,如果你忘掉在switch中处理一些枚举成员的分支,有的编译器会给你一个警告信息。

你还可以使用typedef来定义枚举类型的别名:

#include
#include
typedef enum { SUN, MON, TUE, WED, THU, FRI, SAT} days;void printf_today(int day);int main(void) { days today = FRI; printf_today(today); return 0;}void printf_today(int day) { /*...省略...*/}

聪明的你,可以再看看下面的程序,或许能得到一些启发:

#include
typedef enum { FALSE, TRUE, false = 0, true } boolean;void printf_bool(boolean b) { if (b) printf("b = %4d, boolean val is TRUE\n", b); else printf("b = %4d, boolean val is FALSE\n", b); }int main(void) { boolean b = TRUE; printf_bool(b); b = FALSE; printf_bool(b); b = -100; printf_bool(b); b = 0; printf_bool(b); b = 0.0; printf_bool(b); b = false; printf_bool(b); b = true; printf_bool(b); return 0;}

上面的程序通过枚举的形式实现了boolean类型,但是它有一个坑,当作条件判断时,如果使用if (b == TRUE)这种语法,会跟意想的有错误。因为TRUE在上面程序员被定义成值为1的常量。b = 100当然不会==1啦。但b == 100关系表达式的值确为真。因为本质是整数,两个为真的整数 == 比较的结果不一定为真,所以应该写成if (b)即可。如下:

#include
typedef enum { FALSE, TRUE, false = 0, true } boolean;void printf_bool(boolean b) { if (b) printf("b = %4d, boolean val is TRUE\n", b); else printf("b = %4d, boolean val is FALSE\n", b); }int main(void) { boolean b; printf_bool(b); b = -100; printf_bool(b); /* 应该写成if (b) */ if (b == TRUE) { printf("b is TRUE\n"); } else { printf("b is FALSE\n"); } return 0;}

转载于:https://my.oschina.net/jockchou/blog/465213

你可能感兴趣的文章
git push origin master:master
查看>>
activiti参考5-任务TASK
查看>>
Android学习笔记(十五)——碎片的生命周期(附源代码)
查看>>
如何在面试中为人才留下好印象
查看>>
sublime text3 FTP直接上传
查看>>
[LeetCode] Single Number III 单独的数字之三
查看>>
java调用.net的webservice
查看>>
android连接Mysql数据库之JDBC方式
查看>>
《嵌入式系统原理与接口技术》——嵌入式系统接口应用基础
查看>>
Word 2010 给公式添加序号
查看>>
网站设计常用技巧收集
查看>>
【javascript激增的思考02】模块化与MVC
查看>>
Echarts学习记录——如何去掉网格线及网格区域颜色
查看>>
Linq初级班 使用Let临时局部聚集变量
查看>>
Visual Studio 使用及调试必知必会
查看>>
JS,Javascript加载与函数执行过程
查看>>
web.xml中load-on-startup的作用
查看>>
python调试方法及性能调试
查看>>
利用winrar自动备份重要资料(续,经验技巧)
查看>>
Winform开发中常见界面的DevExpress处理操作
查看>>