首页 » C语言解惑 » C语言解惑全文在线阅读

《C语言解惑》10.2 枚举

关灯直达底部

在实际问题中,有些变量的取值被限定在一个有限的范围内。例如,一个星期内只有七天,一年只有十二个月,一个班每周有六门课程等。如果把这些量说明为整型、字符型或其他类型,显然都是不妥当的。为此,C语言提供了一种称为“枚举”的类型。在“枚举”类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围。

应该说明的是,枚举类型是一种基本数据类型,而不是一种构造类型(它不能再分解为任何基本类型),只是枚举的定义与结构的定义十分相似而已。

用关键字enum来表示枚举,枚举是一个被命名为整数常数的集合,这些常数指定了所有的类型已被定义的合法值。其一般形式为:


enum 枚举名 { 枚举表 } 变量表;  

枚举名和变量表是选择项。例如定义一个coin的枚举,money属于这种类型。


enum coin { penny, nickel, dime, quarter, half_dollar, dollar };enum coin money;  

除非进行了初始化,否则第一个枚举符号的值为0,第二个为1,依次类推。因此


printf ( /"%d %d /", penny, dime );  

将在屏幕上显示0和2两个值。由此可见,一个枚举其实是将每个符号用它们所对应的整数来代替。例如:


printf ( /"The number of nickel in a quarter is %d/", quarter+2 );  

按enum定义,quarter=3,所以quarter+2=5。输出为:


The number of nickel in a quarter is 5  

【例10.5】找出下面程序中的错误。


#include <stdio.h>enum weekday{ sun,mou,tue,wed,thu,fri,sat }a;void main(){     sun=5;     thu=1;     printf ( /"wed is %dn/", wed );     printf ( /"sat is %dn/", sat );}  

【解答】枚举值是常量,不是变量。不能在程序中用赋值语句再对它赋值。


//改正的程序#include <stdio.h>enum weekday{ sun = 5,mou,tue,wed,thu = 1,fri,sat }a;void main(){     printf ( /"wed is %dn/", wed );     printf ( /"sat is %dn/", sat );}  

程序运行结果如下:


wed is 8sat is 3  

【例10.6】找出下面程序中的错误。


#include <stdio.h>enum weekday{ sun,mou,tue,wed,thu,fri,sat }a,b,c;void main(){     a=/"mou/";     b=/"wed/";     c=/"fri/";     printf ( /"a is %dn/", a );     printf ( /"b is %dn/", b );     printf ( /"c is %dn/", c );}  

【解答】枚举元素是整型常量,既不是字符常量,也不是字符串常量,所以使用时不能加单或双引号。


//改正的程序#include <stdio.h>enum weekday{ sun,mou,tue,wed,thu,fri,sat }a,b,c;void main(){   a=mou;   b=wed;   c=fri;   printf ( /"a is %dn/", a );   printf ( /"b is %dn/", b );   printf ( /"c is %dn/", c );}  

运行结果如下:


a is 1b is 3c is 5  

【例10.7】下面的程序是否正确?


#include <stdio.h>enum weekday{ sun,mou,tue,wed,thu,fri,sat }a,b,c;void main(){   a=1;   b=3;   c=5;   printf ( /"a is %dn/", a );   printf ( /"b is %dn/", b );   printf ( /"c is %dn/", c );}  

【解答】视编译系统而定。有的系统允许把数值直接赋予枚举变量,而有的系统不允许这样赋值。如一定要把数值赋予枚举变量,则必须用强制类型转换。下面两种语句


b=(enum weekday)3;  b=(enum )3;    

都可将数值3赋给枚举变量b,也就是将序号为3的枚举元素赋予枚举变量b,相当于语句


b=wed;  

【例10.8】分析下面程序的输出结果。


#include <stdio.h>enum fiv { a,b,c,d,e} m[15], j;void main(){     int i;     j=a;      for(i=0;i<15;i++){         m[i]=j;         j++;         if (j>e)  j = a;     }     for(i=0;i<15;i++){         switch(m[i])         {             case a:                      printf(/" %2d  %ct/",i,/'a/');                      break;                      case b:                      printf(/" %2d  %ct/",i,/'b/');                      break;                      case c:                      printf(/" %2d  %ct/",i,/'c/');                      break;                      case d:                      printf(/" %2d  %ct/",i,/'d/');                       break;               case e:                      printf(/" %2d  %cn/",i ,/'e/');                      break;            default:                     break;         }     }} 

【解答】m是枚举数组,下标也是从0开始。为它赋值是从0开始,依次到e,也就是4。然后从0开始再次循环赋值。下标和值的关系如下:


下标0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 值0 1 2 3 4 0 1 2 3 4 0  1  2  3  4  

switch用m数组的值作为跳转依据。m有5个不同的值,对应a,b,c,d,e,打印循环的i值是0~14,并5个一组分别对应字符a,b,c,d,e。由此可以给出如下输出结果。


 0  a    1  b    2  c    3  d    4  e 5  a    6  b    7  c    8  d    9  e10  a   11  b   12  c   13  d   14  e  

【例10.9】编写一个简单的从给定2014年某日得到星期几的程序,要求输入和输出的格式如下:


Input month day:5 25today is sun(7)  

【解答】使用枚举


enum weekday{ mou=1, tue, wed, thu, fri, sat, sun} ;  

定义星期一至星期天,为了兼顾习惯,将周一初始化为1,则周日为7。

因为只考虑2014年全年,这就可以简单地从2014年1月1日是星期几作为依据进行编程。假设给定的月为month,日期为day,先计算month-1的天数,再加上本月的day-1天,就是总天数alldays。求星期几是用%7,但这没有考虑1月1日已经是星期几的条件。假设1月1日为origin_day,则((alldays+origin_day)%7)就得到星期几。注意在枚举中定义星期天为7,这里计算的星期天是0,所以需要转换。可以继续使用已有变量alldays,使用


alldays = ((alldays + origin_day) % 7);if (alldays == 0) return 7;  

语句即可实现。“return alldays”可以满足其他6天。

输出可以设计一个函数


void print_today(today)  

来实现。使用switch将7种情况区分开来即可实现各自的输出。下面给出完整的程序。


#include <stdio.h>enum weekday get_weekday(int, int);void print_today(int);enum weekday{ mou=1, tue, wed, thu, fri, sat, sun};void main(){   int month, day;   enum weekday today;   printf(/"Input month day:/");   scanf(/"%d%d/", &month, &day);   today =     get_weekday(month, day);   print_today(today);}enum weekday get_weekday(int month, int day){   int m[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };   int i=0,  alldays = 0, origin_day = 3;   for( i=1; i < month; i++)   {         alldays += m[i-1];   }   alldays += day-1;   alldays = ((alldays + origin_day) % 7);   if (alldays == 0) return 7;   return alldays;}void print_today(int today){   switch(today)   {       case 1:                 printf(/"today is %s(%d)n/", /"mou/",today);                 break;       case 2:                 printf(/"today is %s(%d)n/", /"tue/",today);                 break;       case 3:                 printf(/"today is %s(%d)n/", /"wed/",today);                 break;       case 4:                printf(/"today is %s(%d)n/", /"thu/",today);               break;       case 5:                printf(/"today is %s(%d)n/", /"fri/",today);               break;       case 6:                printf(/"today is %s(%d)n/", /"sat/",today);               break;       case 7:                printf(/"today is %s(%d)n/", /"sun/",today);               break;   }}  

程序运行示范如下:


Input month day:1 1today is wed(3)Input month day:2 14today is fri(5)Input month day:3 8today is sat(6)Input month day:5 25today is sun(7)Input month day:8 5today is tue(2)Input month day:11 24today is mou(1)Input month day:12 31today is wed(3)