目录
枚举类型
枚举常量
枚举类型的特征
命名空间
本节我们来学习表示一定整数值的集合的枚举类型。
枚举类型
老样子,我们先用一段程序引出:
/*显示所选动物的叫声*/
#include<stdio.h>enum animal {Dog, Cat, Monkey, Invalid};
/*显示狗叫*/
void dog(void)
{puts("汪汪!!");
}
/*显示猫叫*/
void cat(void)
{puts("喵喵!!");
}
/*显示猴叫*/
void monkey(void)
{puts("唧唧!!");
}
/*选择动物*/
enum animal select()
{int tmp;do{printf("0—狗 1—猫 2—猴 3—结束");scanf("%d", &tmp);}while(tmp < Dog || tmp > Invalid);return tmp;
}
int main()
{enum animal selected;do{switch(selected = select()){case Dog :dog();break;case Cat :cat();break;case Monkey :monkey();break;}}while(selected != Invalid);return 0;
}
让我们来分析下这段程序:
下面紫色底纹部分是枚举类型的声明,它表示了所有可用值的集合,其中,animal被称为枚举名,写在{ }中的是枚举常量
enum animal {Dog, Cat, Monkey, Invalid};
以枚举类型animal为例,如下图,各枚举常量依次被赋值为0,1, 2,3.
相对于整形能够自由的表示多种类型的整数,枚举类型只能表示有限的数值,而且个数值都会被赋予名称。
另外,枚举名不是类型名,也就是说,类型名不是animal型而是enum animal型。
enum animal selected;
上面上enum animal型变量selected的声明,通过这个声明定义了变了selected的取值范围为0,1,2,3
从下图看,无论是int型还是枚举类型,变量声明的形式都是“类型名 标识符”
select函数的功能是显示动物选项并且返回所选动物,在使用do语句的循环条件表达式,其中使用了枚举常量Invalid(意为“无效的”)不表示任何含义,那么我们去掉它看看会发生什么情况:
循环条件改为:
tmp < Dog || tmp > Monkey + 1
如果加入第4种动物海豹,则循环条件改为:
tmp < Dog || tmp > Seal + 1
即每次增加动物时,都要修改判断循环条件的循环条件表达式,由此可见,看似无用的Invalid实际上有大用处!
枚举常量的数据类型时int型,因此在返回值类型为enum animal型的select函数中,可以返回int型变量tmp的值,为了保险,我们可以将返回值进行如下强制转换:
return (enum animal)tmp;
枚举常量
在上面中,我们按照从0开始的顺序为枚举常量定义了相应的整数值,相应的这些值也能根据需要任意设置,只要在枚举常量的名称后面写上赋值运算符=和值就够了
例如在以下定义种,Fukuoka为0,Saga = 5,Nagasaki为6
enum kyushu {Fukuo, Saga = 5, Nagasaki};
没有给定的枚举常量,其值前为一个枚举常量加1。
如果进行以下声明,那么Shibata和Washio都为0(多个枚举类型允许拥有同样的值)
enum namae {Shibata, Washio = 0};
程序的枚举名也是可以省略的:
enum month {JANUARY = 1, FEBRUARY = 2,/*中略*/, DECEMBER};
通过这种方式声明的枚举常量,可以在如下所示的Switch语句中使用
int month;
/*………………*/
switch(month)
{case JANUARY:
case FEBRUARY:/*— 略—*/
}
枚举类型的特征
使用宏定义实现上面表示月份的枚举类型:
#define JANUARY 1
#define FEBRUARY 2
/*…略…*/
#define DECEMBER 12
这在程序中会占据12行,并且还有逐个定义它们的值
而使用枚举类型来声明,就可以十分简洁,只要JANUARY的值正确,其他值就不会错。
■表示动物的enum animal型,只有定义过的值才有效,即有效值为0、1、2、3,如果变量an是该类型,那么对于一下赋值语句
an = 5;//所赋的值不正确
在一些人性化的编译器将会发出警告信息,提醒赋值给an是未定义的值,这样就更容易发现程序中的错误,但是对于an是int型变量,就不能进行这种检测。
注意:能用枚举类型表示的数据类型,应尽量用枚举类型来表示。
命名空间
枚举名和变量名分别属于不同的命名空间(name space),因此几遍名称相同也能区分,比如人名的中华和地理意义上的中华,虽然名字相同但是性质不同,所以可以区分清楚,如果说我是中华民族的一份子,我们就可以马上明了了。
因此,我们可以将enum animal型的变量名为animal,进行如下声明:
enum animal animal;//声明enum animal型的变量animal
显然,前一个animal是枚举名,后一个animal是变量名
下面,我们将学习新的知识——函数递归。