文档章节

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

idreamo
 idreamo
发布于 2017/03/26 07:45
字数 1372
阅读 20
收藏 0

可以使用枚举类型(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++不允许在同一作用域内对一个变量和一个标记使用同一个名字,因为它把标记和变量名放在同一个名字空间。

© 著作权归作者所有

idreamo
粉丝 17
博文 139
码字总数 224743
作品 0
青岛
产品经理
私信 提问
《Oracle数据库基础与应用教程》一本Oracle入门教材

《Oracle数据库基础与应用教程》书全面讲述了Oracle数据库的日常管理工作内容。全书共14章,包含Oracle简介和安装、Oracle客户端、管理Oracle环境、Oracle体系结构、管理Oracle存储结构、SQL...

airfish2000
2016/08/30
0
0
C语言-第八章、构造数据类型

8_1 结构体的概念和结构体变量 _1.1 结构体的概念 C语言中允许用户自己构造由不同数据类型的数据所组成的集合体,称为结构体。结构体属于数据类型,每一个结构体有一个名字,称为结构体名。一...

南风末
2016/11/05
7
0
那些年,关于 Java 的那些事儿

版权声明:Follow your heart and intuition. https://blog.csdn.net/qq_35246620/article/details/78695893 温馨提示:本系列博文(含示例代码)已经同步到 GitHub,地址为「java-skills」,...

维C果糖
2017/12/02
0
0
关东升的《从零开始学Swift》第2版已经出版

关东升的《从零开始学Swift》第2版已经出版 大家好: 苹果2015WWDC大会发布了Swift2.0,它较之前的版本Swift1.x有很大的变化,所以我即将出版《从零开始学Swift》 《从零开始学Swift》将在《...

tony关东升
2016/02/24
0
0
【书评:Oracle查询优化改写】第14章 结尾章

【书评:Oracle查询优化改写】第14章 结尾章 一.1 相关参考文章链接 前13章的链接参考相关连接: 【书评:Oracle查询优化改写】第一章 http://blog.itpub.net/26736162/viewspace-1652985/ 【书...

技术小胖子
2017/11/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring系列教程八: Spring实现事务的两种方式

一、 Spring事务概念: 事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。...

我叫小糖主
今天
5
0
CentOS 的基本使用

1. 使用 sudo 命令, 可以以 root 身份执行命令, 必须要在 /etc/sudoers 中定义普通用户 2. 设置 阿里云 yum 镜像, 参考 https://opsx.alibaba.com/mirror # 备份mv /etc/yum.repos.d/CentO...

北漂的我
昨天
2
0
Proxmox VE技巧 移除PVE “没有有效订阅” 的弹窗提示

登陆的时候提示没有有效的订阅You do not have a valid subscription for this server. Please visit www.proxmox.com to get a list of available options. 用的是免费版的,所以每次都提示......

以谁为师
昨天
3
0
Java设计模式之外观模式(门面模式)

什么是外观模式   外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。这种类型的设计模式属于结构性模式。为子系统中的一组接口提供了一个统一的访问接口...

须臾之余
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部