枚举类型

枚举就是将一个变量所有可能的取值都列举出来。枚举类型是一组整型常量的集合,枚举类型所包含的整型常量通常是一组有意义的符号串。枚举类型中包含的整型常量的名称和个数由用户定义。
7.1.1 枚举类型定义枚举类型的定义的一般形式为:


enum
枚举名{枚举常量1,枚举常量2,……}
其中,enum是关键字,是枚举类型的标志。枚举名是由用户定义的标识符,它代表了所定义的枚举类型的名称,定义时枚举名也可以省略
例如:
enumboolean{NO,YES};
表示定义了一个枚举类型enum boolean,它包含了两个枚举常量NOYES
枚举变量的定义有两种形式:
(1)
先定义枚举类型,在定义变量。例如:


enumboolean b1,b2;
表示定义了两个enum boolean枚举类型的变量b1b2,这两个变量只能取NO或者YES这两中取值。
(2)
直接定义枚举类型的变量。例如:


enum{NO,YES}b1,b2;
需要说明几点:
1
枚举类型中的枚举常量必须是用户定义的标识符。
2
枚举常量都有一个序号值;第一个枚举常量序号值为0,第二个为1,依此类推。例如上例中定义的NO的值为0YES的值为1
当然也可以在定义时指定枚举常量的序号值。
例如:
enum season{SPRING=1,SUMMER=2,AUTUMN=3,WINTER=0};
上例定义了一个枚举类型enumseason,它包含SPRINGSUMMERAUTUMNWINTER四个枚举常量,其值分别为1230
如果定义时只指定了一个枚举常量的序号,则其后的枚举常量的序号值按顺序加1
例如:
enum season{SPRING=1,SUMMER,AUTUMN,WINTER};
SUMMER的序号值为2AUTUMN的序号值为3WINTER的序号值为4
3
不同的枚举常量可以有相同的值。
例如:

enum status{LOSS=-1,BYE,TIE=0,WIN};
其中枚举常量LOSS的值为-1,而BYETIE的值都为0WIN的值为1
4
同一个作用域内的枚举类型中不能有相同的枚举常量。
例如:


enum
month{JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC};

enum
holiday{JUL,AUG};
上面定义的枚举类型monthholiday中都有同名枚举常量JULAUG,那么枚举类型monthholiday不能在同一程序(或同一函数)中定义。如果一定要在同一程序内同时定义这两个枚举类型,只有把其中之一中的同名枚举常量JULAUG换名。


为什么使用枚举类型?使用枚举类型(而不直接使用整型常量)来区分整数和其他代码,最大的好处是使得阅读程序的人看到表明自身意义的符号,从而有助于理解程序。
7.1.2 枚举类型变量的引用使用枚举类型变量时,注意其取值范围只限于定义时所列出的枚举常量的值,具体引用说明如下:
1.
枚举数据的输入和输出

一个枚举值不能直接输入输出,但可以作为整数进行输入和输出,但此时输入输出的都是其序号,而不是枚举常量本身。
例如:
scanf(“%d%d”,&d1,&d2);
输入1
0
printf(“%d,%d”,d1,d2);
输出1
0
如果希望输出枚举常量,可以采用类似以下的的代码来实现。
switch(b1)
{

case NO:printf(“NO”); break;
case YES:printf(“YES”);break;
}

由此可见,编写枚举常量的输入和输出是相当繁琐的,有时,可以定义一个字符串数组,用枚举值作为数组下标,把枚举值翻译成相应字符串。例如:
char
name[ ][4]={“NO”,”YES”};
printf(“%s”,name[b1]);

把枚举值翻译成可读串只能靠编程来实现,因此枚举类型常用于不常进行这种转换的场所。
2.
枚举数据的赋值

枚举常量可赋给同类型的枚举变量;同类型的枚举变量之间也可以赋值,但不能把一个整数直接赋给一个枚举类型变量。例如:
b1=1;
是不对的,它们不是同一种类型。应先进行强制类型转换,如:
b1=(enum boolean)1;
相当于把序号值为1的枚举常量赋给b1,即:
b1=YES;
3.
枚举数据可以根据其序号值的大小比较大小。
例如:表达式SPRING>SUMMER
的结果为0,因为SPRING序号值小于SUMMER的序号值。
4.
枚举值可以进行加(减)一个整数n的运算。
其结果为原来取值的前(后)第n和枚举常量的值。
7.1.3 枚举类型举例
7.1
编写一个程序,输入今天是星期几,计算若干天后是星期几。

分析:将星期设计成枚举类型week,它有七个枚举常量SunMonTueWedThuFriSat,分别表示星期天、星期一、……、星期六,序号分别为012……、6。为输出方便定义一个字符串数组weekstring存放代表星期日到星期六名称的字符串。
#include <stdio.h>
char weekstring[ ][10]={“Sun()”,”Mon()”,”Tue()”,”Wed()”,
”Thu()”,”Fri()”,”Sat()”};
enum week {Sun=0,Mon,Tue,Wed,Thu,Fri,Sat};
void main( void)
{
int d;

enum week today,w;

printf(“今天是星期:”);

scanf(“%d”,&today);

printf(“输入天数:”);

scanf(“%d”,&d);

printf(“今天是星期%s\n”,weekstring[today]);

w=(enum week)((today+d)%7);

printf(“%d天后是星期%s\n”,d,weekstring[w]);
}
运行结果:
今天是星期:4
输入天数:8
8天后是星期Fri()

程序中定义week枚举类型变量today存储用户输入的代表今天的星期数的数据,可以看到在输入枚举类型的变量today时,是作为整型数据输入的,用户在运行时只能输入06之间的整数值,否则将会出错。在计算d天后是星期几是,采用表达式w=(enumweek)((today+d)%7),由于枚举类型是作为整型值参与运算,所以这里“%7”运算不可少。
7.2
现有红、黄、蓝、黑和白色球个1只,从中依次取出3个球,编程输出所有可能的取法。
分析:这是从5种颜色的球中任取3个不同色的球的排列问题。定义枚举类型color的枚举常量redyellowbluewhiteblack表示5种不同颜色的球,如下所示:

enum color {red,yellow,blue,white,black};
采用穷举法,即一种可能一种可能的试,找到每一种符合条件的方案。设取出的球分别为ijk,根据题意,ijk分别为5种颜色的球中的每一个,只要ijk取值互不相等,就为一种方案。程序如下:
#include <stdio.h>
enum color {red,yellow,blue,white,black};
void main(void )
{ enum i, j, k, temp;

int n, loop;

n=0;

for(i=red; i<=black; i++)
for(i=red;j<=black; j++)

if(i!=j)

{
for(k=red; k<=black; k++)

if( (k!=i)&&(k!=j))

{
n++;

printf(“%-5d”,n);

for(loop=1; loop<=3; loop++)

{switch (loop)

{
case 1:
temp=i;break;

case 2:
temp=j;break;

case 3:
temp=k;break;

}

switch(temp)

{
case red:
printf(“%-10s”,”red”);break;

case yellow:
printf(“%-10s”,”yellow”);break;

case blue:
printf(“%-10s”,”blue”);break;


case white:
printf(“%-10s”,”white”);break;

case black:
printf(“%-10s”,”black”);break;

}

}

printf(“\n”):

}
}
printf(“total:%d\n”,n);
}
程序中用变量n来累计得到的3个不同颜色球的方案次数。外层循环使第一个球iredblack变化,第二层循环使第二个球j同样从redblack变化。如果ij颜色相同,则不是要取的方案。只有i不等于j时,才需要取第三个球kk同样从redblack变化,但同时要求kij都不相同,满足条件的ijk3中不同颜色球的方案之一。
由于枚举类型数据不能直接输出,为了简化输出的语句数目。设置第四层循环,用循环变量loop控制其循环三次,依次输出ijk变量的取值对应的字符串。
有人要问,这两个例题中不用枚举类型,而直接用整型数据,例如0表示星期日,1表示星期一……不也可以吗?当然,完全可以。但使用枚举类型的数据,首先使得程序更直观,可读性更强;其次,枚举变量的取值限制在定义时的几个枚举常量的范围内,如果赋予一个其他的取值,将会出现错误,这样便于检查。

上一篇: Code::Blocks 如何设置自动提示功能?   下一篇: wxwidgets的应用程序图标和窗口图标

提交疑问

回顶部