讲解C++中的枚举类型以及声明新类型的方法
C++枚举类型
如果一个变量只有几种可能的值,可以定义为枚举(enumeration)类型。所谓“枚举”是指将变量的值一一列举出来,变量的值只能在列举出来的值的范围内。声明枚举类型用enum开头。例如:
enumweekday{sun,mon,tue,wed,thu,fri,sat};
上面声明了一个枚举类型weekday,花括号中sun,mon,…,sat等称为枚举元素或枚举常量。表示这个类型的变量的值只能是以上7个值之一。它们是用户自己定义的标识符。
声明枚举类型的一般形式为:
enum枚举类型名{枚举常量表列};
在声明了枚举类型之后,可以用它来定义变量。如:
weekdayworkday,week_end;
这样,workday和week_end被定义为枚举类型weekday的变量。
在C语言中,枚举类型名包括关键字enum,以上的定义可以写为:
enumweekdayworkday,week_end;
在C++中允许不写enum,一般也不写enum,但保留了C的用法。根据以上对枚举类型weekday的声明,枚举变量的值只能是sun到sat之一。例如:
workday=mon;week_end=sun;
是正确的。也可以直接定义枚举变量,如:
enum{sun,mon,tue,wed,thu,fri,sat}workday,week_end;
这些标识符并不自动地代表什么含义。
对枚举类型的几点说明:
对枚举元素按常量处理,故称枚举常量。
枚举元素作为常量,它们是有值的,C++编译按定义时的顺序对它们赋值为0,1,2,3,…。也可以在声明枚举类型时另行指定枚举元素的值。
枚举值可以用来做判断比较。
一个整数不能直接赋给一个枚举变量。
【例】口袋中有红、黄、蓝、白、黑5种颜色的球若干个。每次从口袋中任意取出3个球,问得到3种不同颜色的球的可能取法,输出每种排列的情况。
#include<iostream> #include<iomanip>//在输出时要用到setw控制符 usingnamespacestd; intmain() { enumcolor{red,yellow,blue,white,black};//声明枚举类型color colorpri;//定义color类型的变量pri inti,j,k,n=0,loop;//n是累计不同颜色的组合数 for(i=red;i<=black;i++)//当i为某一颜色时 for(j=red;j<=black;j++)//当j为某一颜色时 if(i!=j)//若前两个球的颜色不同 { for(k=red;k<=black;k++)//只有前两个球的颜色不同,才需要检查第3个球的颜色 if((k!=i)&&(k!=j))//3个球的颜色都不同 { n=n+1;//使累计值n加1 cout<<setw(3)<<n;//输出当前的n值,字段宽度为3 for(loop=1;loop<=3;loop++)//先后对3个球作处理 { switch(loop)//loop的值先后为1,2,3 { case1:pri=color(i);break;//color(i)是强制类型转换,使pri的值为i case2:pri=color(j);break;//使pri的值为j case3:pri=color(k);break;//使pri的值为k default:break; } switch(pri)//判断pri的值,输出相应的“颜色” { casered:cout<<setw(8)<<"red";break; caseyellow:cout<<setw(8)<<"yellow";break; caseblue:cout<<setw(8)<<"blue";break; casewhite:cout<<setw(8)<<"white";break; caseblack:cout<<setw(8)<<"black";break; default:break; } } cout<<endl; } } cout<<"total:"<<n<<endl;//输出符合条件的组合的个数 return0; }
运行结果如下:
1redyellowblue2redyellowwhite3redyellowblack ┆ ┆ ┆ 58blackwhitered 59blackwhiteyellow 60blackwhiteblue total:60
不用枚举常量,而用常数0代表“红”,1代表“黄”……也可以。但显然用枚举变量更直观,因为枚举元素都选用了令人“见名知意”的标识符,而且枚举变量的值限制在定义时规 定的几个枚举元素范围如果赋予它一个其他的值,就会出现出错信息,便于检查。
C++typedef声明新类型
在C++中,除了可以声明结构体、共用体、枚举等类型外,还可以用typedef声明一个新的类型名来代替已有的类型如:
- typedefintINTEGER; //指定用标识符INTEGER代表int类型
- typedeffloatREAL; //指定用REAL代表float类型
这样,以下两行等价:
- inti,j;floata,b;
- INTEGERi,j;REALa,b;
这样可以使熟悉FORTRAN的人能用INTEGER和REAL定义变量,以适应他们的习惯。
如果在一个程序中,整型变量是专门用来计数的,可以用COUNT来作为整型类型名:
typedefintCOUNT;//指定用COUNT代表int型 COUNTi,j;//将变量i,j定义为COUNT类型
即int类型在程序中将变量i,j定义为COUNT类型,可以使人更一目了然地知道它们是用于计数的。
也可以声明结构体类型:
typedefstruct//注意在struct之前用了关键字typedef,表示是声明新名 { intmonth;intday;intyear; }DATE;//注意DATE是新类型名,而不是结构体变量名
所声明的新类型名DATE代表上面指定的一个结构体类型。这样就可以用DATE定义变量:
DATEbirthday;DATE*p; //p为指向此结构体类型数据的指针
还可以进一步:
typedefintNUM[100];//声明NUM为整型数组类型,包含100个元素 NUMn;//定义n为包含100个整型元素的数组 typedefchar*STRING;//声明STRING为字符指针类型 STRINGp,s[10];//p为字符指针变量,s为指针数组(有10个元素) typedefint(*POINTER)()//声明POINTER为指向函数的指针类型,函数返回整型值 POINTERp1,p2;//p1,p2为POINTER类型的指针变量
归纳起来,声明一个新的类型名的方法是:
- 先按定义变量的方法写出定义语句(如inti;)。
- 将变量名换成新类型名(如将i换成COUNT)。
- 在最前面加typedef(如typedefintCOUNT)。
- 然后可以用新类型名去定义变量。
再以声明上述的数组类型为例来说明:
- 先按定义数组形式书写:intn[100];
- 将变量名n换成自己指定的类型名:intNUM[100];
- 在前面加上typedef,得到typedefintNUM[100];
- 用来定义变量:NUMn;(n是包含100个整型元素的数组)。
习惯上常把用typedef声明的类型名用大写字母表示,以便与系统提供的标准类型标识符相区别。
关于typedef的几点说明:
- typedef可以声明各种类型名,但不能用来定义变量。用typedef可以声明数组类型、字符串类型,使用比较方便。
- 用typedef只是对已经存在的类型增加一个类型名,而没有创造新的类型。
- 当在不同源文件中用到同一类型数据(尤其是像数组、指针、结构体、共用体等类型数据)时,常用typedef声明一些数据类型,把它们单独放在一个头文件中,然后在需要用到它们的文件中用#include命令把它们包含进来,以提高编程效率。
- 使用typedef有利于程序的通用与移植。有时程序会依赖于硬件特性,用typedef便于移植。