首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

有时需要使变量具有限定的一组值,并可以通过名称来引用这些值。例如一星期的每一天或一年中的各个月份。在C++中有一种特殊的功能来处理这种情况,称为枚举。因为在定义枚举时,实际上是在创建一个新的类型,所以它也称为已枚举的数据类型。下面创建一个利用该理念的例子—— 一个变量可以假定某值对应于一星期的某一天。定义该枚举的语句如下:

enum Weekday {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

这个语句声明一个已枚举的数据类型Weekday,这个类型的变量值只能是花括号中的值,即从Monday到Sunday。如果要把Weekday类型的变量值设置为不在花括号中的值,就会出现错误。列在花括号中的符号名称叫作枚举成员。

实际上,每一天的名称都自动定义为表示一个固定的整数值。列表中的第一个名称Monday,其值为0,Tuesday的值为1,依此类推,Sunday的值为6。可以用下面的语句把today声明为枚举类型Weekday的一个实例:

Weekday today=Tuesday;

类型Weekday的用法跟前面介绍的基本类型相似。这个today的声明还把该变量的值初始化为Tuesday。如果输出today的值,就会显示1。

在默认情况下,枚举声明中每个枚举成员的值都比前面一个枚举成员的值大1,第一个枚举成员的值则是0。如果喜欢从另一个数值开始计数,可以使用下面的语句,使枚举成员的值为1到7:

enum Weekday {Monday=1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

枚举成员不一定有惟一值。可以把Monday和Mon都定义为1,例如下面的语句:

enum Weekday {Monday=1, Mon=1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

该语句允许用Mon或Monday作为一星期中的第一天。然后,用下面的语句设置已声明为类型Weekday的变量yesterday:

yesterday=Mon;

还可以根据列表中以前的枚举成员定义新的枚举成员。把前面的所有代码都放在一个例子中,将类型Weekday声明为:

enum Weekday { Monday, Mon= Monday,

Tuesday = Monday +2, Tues= Tuesday,

Wednesday= Tuesday+2, Wed= Wednesday,

Thursday= Wednesday+2, Thurs= Thursday,

Friday= Thursday+2, Fri= Friday,

Saturday= Friday+2, Sat= Saturday,

Sunday= Saturday +2, Sun= Sunday };

现在,类型为Weekday的变量值可以是从Monday到Sunday,从Mon到Sun,它们对应于整数值0、2、4、6、8、10和12。

如果愿意,可以给所有的枚举成员显式赋值。例如,可以定义下面的枚举:

enum Punctuation {Comma=',', Exclamation='!', Question='?'};

这里把类型为Punctuation的变量的可能值定义为对应符号的数字值。如果查看一下附录A中的ASCII表,就可以看到,这些符号在十进制中分别是44、33和63。这说明不一定必须以升序方式赋值。如果没有显式指定,枚举成员的值就是前一个枚举成员的指定值加1,如第二个Weekday例子所示。

为枚举成员指定的值必须是编译期间的常量,即编译器可以计算出来的常量表达式。这种表达式只包括字面量、以前定义的枚举成员和声明为const的变量。不能使用非const的变量,即使已初始化,也不行。

3.4.1 匿名枚举

在定义枚举的同时声明变量,如果不需要在以后声明这种类型的其他变量,就可以省略枚举类型。例如:

enum {Monday, Tuesday, Wednesday, Thursday,

Friday, Saturday, Sunday} yesterday, today, tomorrow;

这个语句声明了3个变量,它们的值可以假设为从Monday到Sunday。由于没有指定枚举类型,所以不能引用它。以后也不能再声明这种枚举的其他变量,因为这么做需要重复定义,这是不允许的。

匿名枚举类型的一个常见应用是作为定义整数常量的另一种方式。例如:

enum {feetPerYard = 3, inchesPerFoot = 12, yardsPerMiles= 1760 };

这个枚举包含了3个已显式赋值的枚举成员。尽管没有声明这种已枚举的数据类型的变量,但仍可以在算术表达式中使用其中的枚举成员。可以编写下面的语句:

std::cout << std::endl << "Feet in 5 miles = " << 5 * feetPerYard * yardsPerMile;

枚举成员会自动转换为int类型。这看起来似乎是使用枚举来定义整型常量,但在讨论类时就会看到,它提供了在类中包含常量的一种有效方式。现在详细论述一下已枚举的数据类型的转换。

3.4.2 在整型和枚举类型之间强制转换

在混合的算术表达式中,除了枚举成员本身之外,还可以使用枚举类型的变量。已枚举的数据类型会自动转换为相应的类型,但整型类型不能自动转换为枚举类型。如果把变量today声明为前面定义的Weekday类型,则可以使用下面的语句:

today = Tuesday; //Assign an enumerator value

int day_value= today +1; //Calculate with an enumerator type

因为today的值是Tuesday,它对应于1,所以day_value就设置为2。尽管枚举成员Wednesday对应于值2,但下面的语句不会编译:

today = day_value; //Error – no conversion

但是,把这个语句放在显式的强制转换语句中,就可以得到正确的结果:

today = static_cast<Weekday>(day_value); //OK

在进行显式的强制转换时,所强制转换的整数值必须位于枚举成员的取值范围之内,否则结果就是未定义的。这并不意味着它必须对应于某个枚举成员的值,而是说它必须等于或大于最小的枚举成员,且小于或等于最大的枚举成员。例如,定义一个枚举Height,再声明这种类型的一个变量,其代码如下:

enum Height {Bottom, Top=20 } position;

枚举成员Bottom对应于值0,而Top枚举成员对应于值20。因此其取值范围是0到20。可以用下面的语句给变量position赋值:

position= static_cast<Height>(10);

赋予position的值不对应于任何一个枚举成员,但这是一个合法的值,因为它处于枚举成员的最大值和最小值之间。对于前面Punctuation类型的变量,可以把33到63之间的任何整数合法地强制转换为这种类型,并存储它,但在这个例子中,很难看出这么做的目的。

程序示例3.5—— 已枚举的数据类型

在通过比较已枚举的数据类型的变量值和可能的枚举成员以作决策时,枚举是非常有用的。第4章将对此详细介绍。下面仅举一个简单的例子,来演示对已枚举的数据类型的一些 操作:

//Program 3.5 – Exercising an enumeration

#include <iostream>

using std::cout;

int main() {

enum Language{ English, French, German, Italian, Spanish };

//Display range of enumerators

cout << "\nPossible languages are:\n"

<< English << ". English\n"

<< French << ". French\n"

<< German << ". German\n"

<< Italian << ". Italian\n"

<< Spanish << ". Spanish\n";

Language tongue = German;

Cout << "\n Current language is " << tongue;

tongue = static_cast< Language >( tongue +1);

cout << "\n Current language is now " << tongue

<< std::endl;

return 0;

}

这个例子的输出如下:

Possible languages are:

0. English

1. French

2. German

3. Italian

4. Spanish

Current language is 2

Current language is now 3

例子的说明

首先定义了一个枚举Language,代码如下:

enum Language{ English, French, German, Italian, Spanish };

Language类型的变量值可以是花括号中的任何枚举成员值。用下面的语句列出所有可能的值:

Cout << "\nPossible languages are:\n"

<< English << ". English\n"

<< French << ". French\n"

<< German << ". German\n"

<< Italian << ". Italian\n"

<< Spanish << ". Spanish\n";

枚举成员显示为其数字值,这样在输出枚举成员时,同时输出一个文本字符串,说明它对应的语言。

用下面的语句声明并初始化Language类型的一个变量:

Language tongue = German;

这个变量的值显示为2,接着在下一个语句中给它指定新值:

tongue = static_cast< Language >( tongue +1);

在表达式tongue +1中,tongue的值转换为int类型,再给它加上1,得到3,其类型为int。之后通过显式强制转换,把它的类型转换回类型Language,然后存储在tongue中。若没有显式强制转换,该语句就不会编译,因为整数类型不会自动转换为枚举类型。当然,tongue的值显示为3。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论