C语言自定义数据类型(六)使用枚举类型

C语言自定义数据类型系列文章:

C语言自定义数据类型(一)定义和使用结构体变量

C语言自定义数据类型(二)使用结构体数组

C语言自定义数据类型(三)结构体指针

C语言自定义数据类型(四)用指针处理链表

C语言自定义数据类型(五)共用体类型

C语言自定义数据类型(六)使用枚举类型

目录

一、定义

二、详解

三、举例说明


一、定义

如果一个变量只有几种可能的值,则可以定义为枚举 (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 等)更直观,因为枚举元素都选用了令人 “ 见名知义 ” 的名字。此外,枚举变量的值限制在定义时规定的几个枚举元素范围内,如果赋予它其他值,就会出现出错信息,便于检查。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

juechen333

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

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

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

打赏作者

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

抵扣说明:

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

余额充值