9.6 使用枚举类型

 

9.6 使用枚举类型

在C语言中,如果一个变量只有几种可能的值,则可以定义为枚举(enumeration)类型。所谓“枚举”就是指把可能的值一一列举出来,变量的值只限于列举出来的值的范围内。以下将详细介绍如何使用枚举类型。

第9章 用户自己建立数据类型

声明枚举类型

声明枚举类型用 enum 开头。例如:

enum Weekday {sun, mon, tue, wed, thu, fri, sat};

以上声明了一个枚举类型 enum Weekday。然后可以用此类型来定义变量。例如:

enum Weekday workday, weekend;

其中,workdayweekend 被定义为枚举变量,花括号中的 sun, mon, …, sat 称为枚举元素或枚举常量。它们是用户指定的名字。枚举变量和其他数值型量不同,它们的值只限于花括号中指定的值之一。

使用枚举变量

例如,枚举变量 workdayweekend 的值只能是 sunsat 之一:

workday = mon; // 正确,mon是指定的枚举常量之一
weekend = sun; // 正确,sun是指定的枚举常量之一
weekend = 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,依此类推。如果有赋值语句:

    workday = mon;
    

    相当于:

    workday = 1;
    

    枚举常量是可以引用和输出的。例如:

    printf("%d", workday); // 将输出整数1
    

  3. 显式指定枚举元素的数值: 也可以在定义枚举类型时显式地指定枚举元素的数值,例如:

    enum Weekday {sun = 7, mon = 1, tue, wed, thu, fri, sat} workday, weekend;
    

    指定枚举常量 sun 的值为7, mon 为1,以后顺序加1,tue 的值为2,依此类推。

  4. 枚举元素的比较: 枚举元素可以用来作判断比较。例如:

    if (workday == mon)…
    if (workday > sun)…
    

    枚举元素的比较规则是按其在初始化时指定的整数来进行比较的。如果定义时未人为指定,则按上面的默认规则处理,即第1个枚举元素的值为0,故 mon > sunsat > fri

使用枚举类型的示例

例9.12

口袋中有红、黄、蓝、白、黑5种颜色的球若干个。每次从口袋中先后取出3个球,问得到3种不同颜色的球的可能取法,输出每种排列的情况。

解题思路:球只能是5种颜色之一,而且要判断各球是否同色,可以用枚举类型变量处理。设某次取出的3个球的颜色分别为 i, j, k。根据题意,i, j, k 分别是5种色球之一,并要求3球颜色各不相同,即:i ≠ j, i ≠ k, j ≠ k。可以用穷举法,即把每一种组合都试一下,看哪一组符合条件,就输出 i, j, k

算法表示

#include <stdio.h>

int main() {
    enum Color {red, yellow, blue, white, black};
    // 声明枚举类型 enum Color
    enum Color i, j, k, pri;
    // 定义枚举变量 i, j, k, pri
    int n, loop;
    n = 0;
    for (i = red; i <= black; i++)
        for (j = red; j <= black; j++)
            if (i != j) {
                for (k = red; k <= black; k++)
                    if ((k != i) && (k != j)) {
                        n = n + 1;
                        printf("%-4d: ", n);
                        // 输出当前是第几个符合条件的组合
                        for (loop = 1; loop <= 3; loop++) {
                            switch (loop) {
                                case 1: pri = i; break; // 第1球的颜色赋给pri
                                case 2: pri = j; break; // 第2球的颜色赋给pri
                                case 3: pri = k; break; // 第3球的颜色赋给pri
                                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("Total: %5d\n", n);
    return 0;
}

程序分析: 在程序各行的注释中已说明了各语句的作用。请仔细分析。在输出时,注意输出的字符串 "red" 与枚举常量 red 并无内在联系,输出 "red" 等字符完全是人为指定的。枚举常量的命名完全为了使人易于理解,它们并不自动地代表什么含义。例如,不因为命名为 red,就代表“红色”,用其他名字也可以。用什么标识符代表什么含义,完全由程序设计者决定,以便于理解为原则。

有人说,不用枚举常量而用常数0代表“红”,1代表“黄”……不也可以吗?是的,完全可以。但显然用枚举变量(red, yellow 等)更直观,因为枚举元素都选用了令人“见名知义”的名字。此外,枚举变量的值限制在定义时规定的几个枚举元素范围内,如果赋予它其他值,就会出现出错信息,便于检查。

 

 

 

 

 

 

 

 

  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏驰和徐策

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值