目录
一、定义
二、详解
三、举例说明
一、定义
如果一个变量只有几种可能的值,则可以定义为枚举 (enumeration) 类型,所谓 “ 枚举 ” 就是指把可能的值一一列举出来,变量的值只限于列举出来的值的范围内。
声明枚举类型用 enum 开头。例如:
enum Weekday { sun, mon, tue, wed, thu,fri, sat };
以上声明了一个枚举类型 enum Weekday。然后可以用此类型来定义变量。例如:
enum Weekday workday, weekend;
workday 和 weekend 被定义为枚举变量,花括号中的 sun,mon,… ,sat 称为枚举元素或枚举常量。它们是用户指定的名字。枚举变量和其他数值型量不同,它们的值只限于花括号中指定的值之一。例如枚举变量 workday 和 weekend 的值只能是 sun 到 sat 之一。
workday = mon; //正确, mon是指定的枚举常量之一
weekend = sun; //正确, sunon是指定的枚举常量之一
weekday = monday; //不正确, monday不是指定的枚举常量之一
枚举常量是由程序设计者命名的,用什么名字代表什么含义,完全由程序员根据自己的需要而定,并在程序中作相应处理。
也可以不声明有名字的枚举类型,而直接定义枚举变量例如:
enum { sun, mon, tue, wed, thu, fri, sat } workday, weekend;
声明枚举类型的一般形式为
enum[枚举名] {枚举元素列表};
其中,枚举名应遵循标识符的命名规则,上面的Weekday就是合法的枚举名。
二、详解
(1)C 编译对枚举类型的枚举元素按常量处理,故称枚举常量。不要因为它们是标识符(有名字)而把它们看作变量,不能对它们赋值。例如:
sun = 0; mon = 1; //错误,不能对枚举元素赋值
(2)每一个枚举元素都代表一个整数,C 语言编译按定义时的顺序默认它们的值为 0,1,2,3,4,5 …。在上面的定义中,sun 的值自动设为 0,mon 的值为 1,… , sat 的值为 6。如果有赋值语句:
workday = mon;
相当于
workday = 1;
枚举常量是可以引用和输出的。例如:
printf("%d", workday);
将输出整数 1。
也可以人为地指定枚举元素的数值,在定义枚举类型时显式地指定,例如:
enum Weekday { sun = 7, mon = 1, tue, wed, thu, fri, sat } workday, weekend;
指定枚举常量 sun 的值为 7,mon 为 1,以后顺序加 1,sat 为 6。
由于枚举型变量的值是整数,因此 C99 把枚举类型也作为整型数据中的一种,即用户自行定义的整数类型。
(3)枚举元素可以用来作判断比较。例如:
if (workday == mon)…
if (workday > sun)…
枚举元素的比较规则是按其在初始化时指定的整数来进行比较的。如果定义时未人为指定,则按上面的默认规则处理,即第 1 个枚举元素的值为 0,故 mon > sun,sat > fri 。
通过下面的例子可以了解怎样使用枚举型数据。
三、举例说明
举例:口袋中有红、黄、蓝、白、黑 5 种颜色的球若干个。每次从口袋中先后取出 3 个球,问得到 3 种不同颜色的球的可能取法,输出每种排列的情况。
解题思路:球只能是 5 种颜色之一,而且要判断各球是否同色,可以用枚举类型变量处理。设某次取出的 3 个球的颜色分别为 i,j,k。根据题意, i,j,k 分别是5种色球之一,并要求 3 球颜色各不相同,即:i ≠ j,i ≠ k,j ≠ k 。可以用穷举法,即把每一种组合都试一下,看哪一组符合条件,就输出 i,j,k。
用 n 累计得到 3 种不同色球的次数。外循环使第 1 个球的颜色 i 从 red 变到 black。中循环使第 2 个球的颜色 j 也从 red 变到 black。如果 i 和 j 同色则显然不符合条件。只有 i 和 j 不同色 ( i ≠ j ) 时才需要继续找第 3 个球,此时第 3 个球的颜色 k 也有 5 种可能( red 到 black ),但要求第 3 个球不能与第 1 个球或第 ⒉个球同色,即 k ≠ i,k ≠ j。满足此条件就得到了 3 种不同色的球。输出这种 3 色组合的方案。然后使 n 加 1,表示又得到一次 3 球不同色的组合。外循环全部执行完后,全部方案就已输出完了。最后输出符合条件的总数 n。
如何输出 red,black 等颜色的单词。不能写成 “ printf(“%s”, red); ” 来输出字符串 " red "。可以采用“ printf(“%s”, "red"); ” 的方法输出。
为了输出 3 个球的颜色,显然应经过 3 次循环,第 1 次输出 i 的颜色,第 ⒉次输出 j 的颜色,第 3 次输出 k 的颜色。在 3 次循环中先后将 i,j,k 赋予 pri。然后根据 pri 的值输出颜色信息。在第 1 次循环时,pri 的值为 i,如果 i 的值为 red,则输出字符串 "red",其他类推。
#include<stdio.h>
enum Color //声明枚举类型
{
red,
yellow,
blue,
white,
black
};
enum Color i, j, k, pri; //定义枚举变量i,j,k,pri;
int main()
{
int n;
n = 0;
for (i = red; i <= black; i = (Color)(i + 1)) //外循环使i的值从red变到black
{
for (j = red; j <= black; j = (Color)(j + 1)) //中循环使j的值从red变到black
{
if (i != j) //如果二球不同色
{
for (k = red; k <= black; k = (Color)(k + 1)) //内循环使k的值从red变到black
{
if ((k != i) && (k != j)) //如果3球不同色
{
n = n + 1;
printf("%-4d", n);
for (int loop = 1; loop <= 3; loop++) //先后对3个球进行处理
{
switch (loop) //loop的值从1到3
{
case 1:pri = i; //loop的值为1时,把第1个球的颜色赋给pri
break;
case 2:pri = j;
break;
case 3:pri = k;
break;
default:
break;
}
switch (pri) //根据球的颜色输出相应的文字
{
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;
default:
break;
}
}
printf("\n");
}
}
}
}
}
printf("\ntotal:%5d\n", n);
}
运行结果:
程序分析:
在程序各行的注释中已说明了各语句的作用,请仔细分析。请弄清楚在输出时怎样输出 "red","yellow" 等文字。要注意:输出的字符串 "red" 与枚举常量 red 并无内在联系,输出 "red" 等字符完全是人为指定的。
枚举常量的命名完全为了使人易于理解,它们并不自动地代表什么含义。例如,不因为命名为 red,就代表 “ 红色 ”,用其他名字也可以。用什么标识符代表什么含义,完全由程序设计者决定,以便于理解为原则。
有人说,不用枚举常量而用常数 0 代表 “红”,1 代表 “黄” ……不也可以吗?是的,完全可以。但显然用枚举变量 (red,yellow 等)更直观,因为枚举元素都选用了令人 “ 见名知义 ” 的名字。此外,枚举变量的值限制在定义时规定的几个枚举元素范围内,如果赋予它其他值,就会出现出错信息,便于检查。