再上一篇:7.2 位域
上一篇:7.3 共同体的定义及应用
主页
下一篇:第八章 指针和引用
再下一篇:8.2 指针与数组
文章列表

7.4 枚举类型

《VC++程序设计基础》,讲述C++语言的语法和标准库,以及Visual C++ 函数库和MFC类库的使用,并附相关代码示例。

在程序中要用一个变量weekday来表示一周的星期几,我们可以用整数0,1,2,3,4,5,6分别表示周日,周一,......,周六。如果能定义一个集合: { Sun,Mon,Tue,Wed,Thu,Fri,Sat }

并限定变量weekday只能取这个集合中的某一个值。如:

weekday = Mon;

显然,程序中采用这种表示方式可增加程序的可读性。在C++中提供了这种功能,即可把weekday定义为枚举(enumeration)类型变量。

7.4.1 枚举类型及枚举类型变量

在定义枚举类型变量之前,要先定义枚举类型。定义枚举类型的一般格式为:enum <枚举类型名> {

<枚举量表> };

其中枚举类型名由标识符构成,枚举量表是由逗号隔开的标识符组成。枚举量表中的标识符称为枚举元素或枚举常量。如:

enum weekdays {

Sun,Mon,Tue,Wed,Thu,Fri,Sat

};

定义了一个名为weekdays的枚举类型,它包含了七个元素,这些元素的名字分别为Sun,Mon,Tue,Wed,Thu,Fri,Sat。

枚举类型的元素称为标识符常量,它的命名规则与标识符相同,在程序的执行期间每一个枚举类型的元素是用一个整数来表示的。编译器在编译时,给枚举类型定义中列举的每一个元素指定一个整型常量值。在枚举类型定义中没有规定元素所取的整数值时,把列举元素的序号(从0开始)作为对应元素的值。因此,weekdays的元素Sun,Mon,Tue,Wed,Thu,Fri,Sat的值分别是0,1,2,3,4,5,6。

在定义枚举类型时,可以指定元素的值(必须是一个整数)。如:

enum boolean{ TRUE=1,FALSE=0};

即规定了元素TRUE的值为1,FALSE的值为0。又如:

enum clors {red =5, blue =1, green, black, white,yellow};

则定义元素red为5,blue为1,其后的元素依次顺序加1,即green,,black,white,yellow的值分别为2,3,4,5。不同的枚举元素可以取相同的值,如上面的枚举元素red和yellow取相同的值5,也可以给不同的枚举元素指定相同的值。如:

enum clors {A=2, B =1, C, D, E=2};

五个元素的值分别为2,1,2,3,2。通常,使不同的枚举元素取相同的值是没有实用意义的。

与结构体类同,定义的枚举类型只是自定义了一种新的数据结构,只有说明属于这种类型的变量时才使用这种类型的数据结构。与说明结构体变量类同,说明枚举类型变量的方法也有三种方法。第一种方法是先说明枚举类型,再定义枚举变量,其格式为:

enum <枚举类型名> 《<变量1>, ..., <变量n>》;

或:

<枚举类型名> <变量1>《, ..., <变量n>》;

如:

clors c1,c2;

第二种方法是在定义枚举类型的同时,定义枚举类型变量,格式为:

enum <枚举类型名> {

<枚举量表> }<变量1>《, ..., <变量n>》;

如:

enum col { red, blue ,black}x1, x2,x3;

说明变量x1, x2和x3为col类型的变量。第三种方法是不定义枚举类型名,直接定义枚举类型变量,格式为:

enum {

<枚举量表> } <变量1>《, ..., <变量>》;

如:

enum {

sun, mon ,tue , thu , fri, sat

} day1,day2,day[20] ;

提倡使用第一种或第二种方法来定义枚举类型变量,若采用第三种方法,则在程序中其它地方无法说明与day1同类型的枚举类型的变量。

说明枚举类型变量时,也可以对其进行初始化,如:

col col1=red;

在VC++中只允许将枚举量表中列举的某一个枚举常量作为枚举变量的初始值。7.4.2 枚举类型变量的使用

对枚举类型变量只能使用二种运算符:赋值运算符和关系运算符。可以将在枚举量表中列举的任一枚举常量赋给枚举类型变量,同类型的枚举类型变量之间可以相互赋值。如,对于前面说明的变量day1:

day1 = sun;

day2 = day1;

注意,不同类型的枚举变量之间不能相互赋值,也不能将一个整数赋给枚举类型变量。枚举类型变量只能取其类型定义中所列举的枚举常量中的任一个枚举量值。

枚举类型变量可进行的关系运算是指同类型的枚举类型变量之间的比较运算,或枚举类型变量与一个枚举常量进行的比较运算。比较时,是按其枚举常量所取的序号值的大小进行比较的。如:

day1 = mon;

if ( day1 < tue ) day2=sat; else day2 = day1;

因枚举常量mon的序号为1,而tue的序号为2,所以,关系表达式day1 < tue成立,其值为1。

枚举类型变量不能直接从键盘上输入,如:

cin>>day1;

是不允许的。枚举类型变量可以直接输出,但输出的值是一个整数(对应枚举常量的序号值)。如:

day1 = sun;

cout>>day1;

输出值为0。为了增加程序的可读性,枚举类型变量的输入输出均要用开关语句来转换。

例 7.6 输入0至6,转换为对应的枚举量Sunday,Monday,......,Saturday。程序为:

#include

enum weekday{

Sunday ,Monday ,Tuesday ,Wednesday ,Thursday, Friday , Saturday };void main(void )

{

int i;

weekday day;

cout<<"0:Sun,1:Mon,2:Tue,3:Wen,4:Thu,5:Fri,6:Sat\n";

cin >> i;

if(i <0 || i>6 ) cout<<"输入值不对!";

else{

switch( i){

case 0: day=Sunday; break;

case 1: day=Monday; break;

case 2: day=Tuesday; break;

case 3: day=Wednesday ;break;

case 4: day=Thursday; break;

case 5: day=Friday; break;

case 6: day=Saturday;

}

switch(day){

case Sunday: cout<< "今天是Sunday \n"; break;

case Monday: cout<< "今天是Monday \n"; break;

case Tuesday: cout<< "今天是Tuesday \n"; break;

case Wednesday: cout<< "今天是Wednesday \n"; break;

case Thursday: out<< "今天是Thursday \n"; break;

case Friday: cout<< "今天是Friday\ n"; break;

case Saturday: out<< "今天是Saturday";

}

}

}

从本例可以看出,枚举类型变量的输入输出是不方便的。这是由于枚举类型变量的值在程序中是以枚举量表示的,而在执行程序时是以整数(枚举量的序号)表示的,导致枚举类型变量的值不能直接输入和输出。

例 7.7 设口袋中有红,黄,蓝,白,黑五种颜色的球若干个,每次从口袋中取出3 个不同颜色的球,计算出所有不同的取法。

分析:用枚举量red, yellow, blue, white, black分别表示红,黄,蓝,白,黑五种颜色的球。计算不同的取球方法是一个组合问题。设取出的三个球为i,j,k,它们分别可以取以上五个枚举量之一的值,并且满足条件:i,j和k的值均不相同。可以使用穷举法依次列出每一种取法。程序为:

#include

enum color {

red, yellow, blue, white, black

} ;

void Print( color col)

{

switch (col) {

case red : cout << "red"<<'\t'; break;

case yellow : cout <<"yellow"<<'\t'; break;

case blue : cout <<"blue"<<'\t'; break;

case white : cout << "white"<<'\t'; break;

case black : cout << "black"<<'\t'; break;

default : break;

}

}

void main(void)

{

color i, j, k;

int n = 0;

for ( i = red ; i <= black ; i= (color)((int) i+1) ) //A

for ( j = red ; j <= black ; j=(color)((int)j+1) )

for ( k = red ; k <= black ; k=(color)((int)k+1) )

if ( i!= j && i!= k && j!=k ) { //B

cout <<++n << '\t';

Print(i); Print(j); Print(k);

cout <<"\n";

}

}

程序中用函数Print( )来输出一个枚举变量的值。用变量i,j和k分别表示取出的第一个球,第二个球和第三个球,它们依次取red, yellow, blue, white,black中的一个值。程序中的B行保证取出的三个球的颜色各不相同。由于枚举类型变量只能进行赋值和关系运算,不能进行加1或++运算,所以在程序的A行中的:

i= (color)((int) i +1)

先要将i的值强制转换为整数,完成加1运算后,再一次强制转换为枚举类型的值后,才能将计算结果赋给变量i。

执行程序后的输出如下:

1 red yellow blue

2 red yellow white

3 red yellow black

4 red blue yellow

5 red blue white

6 red blue black

7 red white yellow

8 red white blue

9 red white black

10 red black yellow

......

56 black blue yellow

57 black blue white

58 black white red

59 black white yellow

60 black white blue

习题与思考7

1.定义描述一个人出生日期的结构体变量,包括年、月、日。

2.定义描述通讯录的结构体变量。包括姓名,地址,电话号码,邮编。

3.下面的类型定义语句有错误吗?若有,则指出错误原因。

struct s{

int x,y;

float y,z;

};

4.下面的语句序列中有错误吗?若有,则指出错误原因。

struct {

int a,b,c;

} s1,.s2;

struct s{

int a,b,c;

} s3,.s4;

cin>>s1>>s2;

s3=s1; s4=s2;

cout<

5.为全班同学建立一个通讯录(结构体数组),完成数据的输入和输出。

6.定义描述复数的结构体变量,并实现复数的输入和输出。设计三个函数分别完成复数的加法、减法、乘法运算。

7.定义描述三维坐标点(x,y,z)的结构体变量,完成坐标点的输入输出,求二坐标 点之间的距离。

8.定义全班学生学习成绩的结构体数组,一个元素包括:姓名,学号,C++成绩,英语成绩,数学成绩和这三门功课的平均成绩(通过计算得到)。设计四个函数:全班成绩的输入,求出每一个同学的平均成绩,按平均成绩的升序排序,输出全班成绩表。

9.定义一个描述一周日程的枚举类型(Sunday,Monday,…,Saturday),完成这种枚举类型变量的输入和输出。

10.定义一个描述三种颜色的枚举类型(Red,Blue,Green),输出这三种颜色的全排列。