第14章 结构和其他数据形式 14.11 枚举类型

本文详细介绍了C语言中的枚举类型(enum),包括如何声明枚举类型、默认和指定枚举值的方法,以及枚举类型在实际编程中的应用实例。此外还探讨了C与C++中枚举类型的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可以使用枚举类型(enumerated type)声明代表整数常量的符号名称。通过使用关键字enum,可以创建一个新的“类型”并指定它可以具有值(实际上enum常量是int类型的,因此在使用int类型的任何地方都可以使用它)。枚举类型的目的是提高程序的可读性。它的语法与结构的语法相同。

例如:

enum spectrum {red,orange,yellow,green,blue,violet};
enum spectrum color;

color的可能值是red,orange,yellow,等等。然后,可以使用如下所示的语句:

int c;
color = blue;
if(color == yellow)
...;
if(color = red;color<=violet;color++)
...;

虽然枚举常量都是int类型的,但枚举变量较宽松地限定为任一种整数类型,只要该整数类型能保存这些枚举常量。例如,为spectrum枚举的常量在范围0到5之间,因此编译器可以选择使用unsigned char来表示变量color。

顺便提一下,c的某些枚举属性不能延伸至c++中。例如,C允许对枚举变量使用++,而C++不允许。在上面的例子中,您必须把color声明为int类型。这样该代码就即能工作在C下,也能工作在C++下。

14.11.1  enum常量

blue和red到底是什么?从技术上讲,它们是int类型的常量。例如,假设有前面的枚举声明,可以这样使用:

printf("red = %d, orange = %d\n",red,orange);

下面是输出

red = 0, orange = 1

所发生的情况是,red成了一个代表整数0的命名常量。同样,其他标识符也是代表1到5的常量。在使用整数常量的任何地方都能使用枚举常量。例如,在数组声明中可以把它们作为数组大小,在switch语句中,可用它们作作为标签 。

14.11.2  默认值

默认时,枚举列表中的常量被指定为整数值0、1、2等等。因此,以下声明使nina具有值3:

enum kids{nippy,slats,skippy,nina,liz};

14.11.3  指定值

您可以选择常量具有的整数值 ,只须在声明中包含期望的值:

enum levels { low = 100,medium = 500,high = 2000};

如果只对一个常量赋值,而没有对后面的常量赋值,那么这些后面的常量会被赋予后续的值。例如,

enum feline {cat,lynx = 10,puma,tiger};

那么cat的默认为0,lynx、puma和tiger的值分别是10、11和12。

14.11.4  enum的用法

注意,枚举类型是内部使用的。如果想输入color值orange,只能输入1,而不是单词orange。或者,可以读入字符串“orange",并让程序将它转换成值orange。

因为枚举类型是一个整数类型,所以enum变量能像整数变量那样被用在表达式中。这就给case语句提供了一类方便的标签。

程序清单14.15给出了一个使用enum的短例。该例中使用默认方案,将值0赋给red,使它成为指向字符串red的指针的索引。

#include <stdio.h>
#include <string.h>  //为了使用strcmp()
#include <stdbool.h>  //C99特性

enum spectrum{red,orange,yellow,green,blue,violet};
const char *colors[]={"red","orange","yellow","green","blue","violet"};
#define LEN 30

int main(void)
{
    char choice[LEN];
    enum spectrum color;
    bool color_is_found = false;

    puts("Enter a color (empty line to quit): ")
    while(gets(choice)!=NULL && choice[0]!='\0')
    {
        for(color = red;color <= violet; color++)
        {
            if(strcmp(choice,colors[color])==0)
            {
                color_is_found = true;
                break;
            }
        }
        if(color_is_found)
            switch(color)
            {
                case red     :puts("Roses are red.");
                break;
                case orange  :puts("Poppies are orange.");
                break;
                case yellow  :puts("Sunflowers are yellow.");
                break;
                case green   :puts("Grass is green.");
                break;
                case blue    :puts("Bluebells are blue.");
                break;
                case violet  :puts("Violet are violet.");
                break;
            }
            else
                printf("I don't know about the color %s.\n",choice);
            color_is_found = false;
            puts("Next color ,please (empty line to quit ): ");
    }
    puts("Good bye!");

    return 0;
}

如果输入的字符串与一个由colors数组成员 指向的字符相匹配,程序就跳出for 循环。如果该循环找到一个匹配的颜色,程序就用那个枚举变量的值去匹配用作case标签的枚举常量。

下面是一个运行示例:

Enter a color(empty line to quit):
blue
Bluebells are blue.
Next color ,please (empty line to quit): 
purple
I don't know about the color purple.
Next color ,please (empty line to quit): 

Goodbye!

14.11.5  共享的名字空间

C使用术语名字空间(namespace)来表示识别一个名字的程序部分。作用域是这个概念的一部分;名字相同但具有不同作用域的两个变量不会冲突;而名字相同并在相同作用域中的两个变量就会冲突。名字空间是分类别的。在一个特定作用域内的结构标记、联合标记以及枚举标记都共享着一个名字空间,并且这个名字空间与普通变量使用的名字空间是不同的。这意味着,可以在同一个作用域内对一个变量和一个标记使用同一个名字而不会产生冲突。但是不能在同一作用域内使用名字相同的两个标记或名字相同的两个变量。例如,在C中下面的语句不会产生冲突:

struct rect {double x;double y};

int rect;

然而,用两种不同的方式使用同一标记符会造成混乱;而且,C++不允许在同一作用域内对一个变量和一个标记使用同一个名字,因为它把标记和变量名放在同一个名字空间。

转载于:https://my.oschina.net/idreamo/blog/867749

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值