在C/C++编程中,我们除了长使用struct 和class构建自定义类型,还会使用union,enum做相关的事情,union在语法表面上与struct、class没有区别,关键一点是,union中的元素是共用一块内存空间的,有关他的讨论我们之前也做过,这里我们讨论一下enum这个关键字。
相信大家都知道enum只是枚举的意思,有时候也会用到这个东西,但是我们总是会被这个东西的概念搞糊涂,尤其是我们长时间不用它之后。
怎么去理解enum这个东西呢?我们来确定几句话。
1)enum,也是一个用于创建新类型的关键字,这点雨struct、class、union一样,通常我们要使用它们的时候还需要实例化。
2)enum,与语言(C/C++,C#)中的整型(int)有非常直接的关系。如果你敢想,我们可以这么说,用enum创建的类型,就相当于typdef int enumtype;创建出来的一样。只是enum比它多了一些东西。
3)最经典的一句话:“枚举是一个被命名的整型常数的集合”
上面两句话,或许暂时还没有展示出它的意义所在,我们从另外一个角度分析一下:
enum被称为枚举,是C语言为我们编程的时候的某种需求而提出的,这就是状态标示需求。我们需要区分各种各样的状态,并且我们只是想区分它们的不同,而无意要在里面加入什么特别属性,至于程序针对不同状态的不同表现,那完全是另外一件事。
例如,我们想表达一个星期7天。
方法可以是这样:
#define SUNDAY 7;
#define
……
当然到了C++,我们建议这样:
const int
const int MONDAY=1;
……
是的,就想我以前说过,千万不要误会编程语言中所谓的整形(int,char,long)的作用,事实上(特别是C),整形的大部分作用是用来表示状态的。
但是上面这样有一个问题,就是加入我们有一个函数需要星期几的参数,我们无法再函数获取参数那个地方(编译)就能够判断出参数不对,我们给出了23这样的代表星期几的数,是毫无意义的。但是编译器无法排错,因为他只知道那个是整形,当然我们可以再函数内部进行判断这种错误,但这只是增加了无关的功夫。
我认为enum就是针对这种问题个提出的,我们大胆的说吧(虽然不敢确认但是,基本上也是了),enum类型的内部实现是整形int,我们在整形int的基础上,人为限定了范围,并且给特定的数一个特定的名称,以表达其意思:
enum Date
{
};
注意,与struct和class,union不同的是enum的内部元素使用逗号隔开,并且也没有什么所谓类型定义,仔细分析它与struct和class,union的区别。可知这种语法也是正常的。
所以,定义一个enum,关键是给出几个状态,状态后面的int值是可选的,如果没有指定,那么从0开始指定,后一个状态(枚举子)是前一个加1,所以多个迭代子是可以指示一个int数的。
我们在看看,enum使用的时候要注意的问题:
1)如前面所说,enum就是一个在整形上面做限定的类型定义,他的范围为最大和最小枚举子之间,即使我们没有显示给出状态枚举子,但其间的int数一定有效。
2)虽然我们说明了,枚举的就是整形上面做限定和标示,但是我们不能直接将一个整形赋值给枚举变量,即使该int 数在该枚举变量的有效范围内。这种规定是有其道理,因为enum类型本来就是为了限定,所以它就不容许你那么轻易的赋值,当然你可以使用显示的转换方法。
3)将一个超过该枚举类型的整形通过显示转换的方式转换然后赋值给相应变量会导致undefined后果。
当然,我认为当初enum提出的目的就是为了解决上面的问题,但是事实上enum还有很多其他的应用,下面是转载别人的文章:(主要是将enum的各种应用)
1、枚举enum的用途浅例
然后,调用以下函数:
比如,
也一样会出错哦!例如:
2、枚举的定义
枚举的定义具有以下形式,即以关键词enum开头,接着一个可选的枚举名,下来是由大括号{}包含着一个由逗号分隔的枚举子列表enumerators list:
3、枚举子的类型和取值
其中
以上简单地按区域,将五个城市按照华南(4),华东(2), 华北(3)的几个城市分类了。
4、枚举变量的定义、初始化和赋值
int main(void)
{
}
输出将是the value is: 1. 然而,如果声明wh为全局变量,则另一种情况:
enum some_big_cities {Guangzhou = 1 Shenzhen = 1, Hongkong = 1,
some_big_cities wh;
int main(void)
{
}
输出将是the value is: 0;
或者
5、枚举的取值范围
6、枚举与整型的关系
7、自定义运算符
{
};
SomeCities oneCity;
for (oneCity = zhanjiang; oneCity != Zhongshan; ++oneCity)
{
}
以上的++OneCity是没有定义的,在Visual C++ 6 编译下得到如下错误:
error C2675: unary '++' : 'enum main::SomeCities' does not define this operator or a conversion to a type acceptable to the predefined operator
8、Sizeof
enum SomeCities
{
};
计算其sizeof, 可能是1,也可能是是4。在我的intel E2160双核、32位机器中,得到4。
-----------------------------------------------------------------------------------
[注1, Begin]
由于通过将整型数显式转换就可能得到对应枚举类型的值,所以声明一个枚举来达到限制传递给函数的参数取值范围还是力不从心的,以下是一个例子:
enum SomeCities
{
zhanjiang=1, //1
Maoming,
Yangjiang,
Jiangmen,
Zhongshan = 1000 //1000
};
void printEnum(SomeCities sc)
{
cout<<sc<<endl;
}
int main(void)
{
SomeCities oneCity = SomeCities(50); //将50通过显式转换,为oneCity赋值
printEnum(oneCity); //在VC++ 6 编译器下得到50输出
return 0;
}
以上例子说明,虽然SomeCities的定义里没有赋值为50的枚举值,但是,由于50在该枚举的取值范围内,所以通过显式声明得到一个有定义的枚举值,从而成功传递给printEnum函数。