当前位置:首页 » 编程软件 » 枚举类型在编译器处理之后

枚举类型在编译器处理之后

发布时间: 2022-08-19 08:41:25

⑴ C++中的枚举类型怎么使用

C++中的枚举类型使用:
1、枚举enum的用途
写程序时,我们常常需要为某个对象关联一组可选alternative属性.例如,学生的成绩分A,B,C,D等,天气分sunny, cloudy, rainy等等。
更常见的,打开一个文件可能有三种状态:input, output和append. 典型做法是,对应定义3个常数,即:
const int input = 1;
const int output = 2;
const int append = 3;
然后,调用以下函数:
bool open_file(string file_name, int open_mode);
比如,
open_file("Phenix_and_the_Crane", append);
这种做法比较简单,但存在许多缺点,主要的一点就是无法限制传递给open_file函数的第2个参数的取值范围,只要传递int类型的值都是合法的。(当然,这样的情况下的应对措施就是在open_file函数内部判断第二个参数的取值,只有在1,2,3范围内才处理。) 使用枚举能在一定程度上减轻这种尴尬(注1),它不但能实现类似于之前定义三个常量的功能,还能够将这三个值组合起来成为独一无二的组。例如:
enum open_modes {input = 1, output, append};
以上定义了open_modes为枚举类型enumeration type。每一个命名了的枚举都是唯一的类型,是一个类型标示器type specifier。例如,我们可以重新写一个open_file函数: bool open_file(string file_name, open_modes om);
在open_modes枚举中,input, output, append称为枚举子enumerator, 它们限定了open_modes定义的对象的取值范围。这个时候,调用open_file函数和之前的方法还是一模一样:
open_file("Phenix_and_the_Crane", append);
但是,如果传递给open_file的第二个参数不是open_modes枚举类型值的话(注1),那么编译器就会识别出错误;就算该参数取值等价于input, output, append中的某个, 也一样会出错哦!例如:
open_file("Phenix_and_the_Crane", 1);
2、枚举的定义
一个枚举是一个类型,可以保存一组由用户刻画的值。定义之类,枚举的使用很像一个整数类型。
枚举的定义具有以下形式,即以关键词enum开头,接着一个可选的枚举名,下来是由大括号{}包含着一个由逗号分隔的枚举子列表enumerators list:
enum [enumeration name] {enumerator1[=value1], enumerator2[=value2], ...};
3、枚举子的类型和取值
枚举子的类型就是它所在的那个枚举,例如前面说到的open_modes枚举中,input,output和append等枚举子的类型都是open_modes。这种做法,其实是为了赋予用户和编译器一些有关该变量拟议中的用途的提示。
默认下,第一个枚举子被赋值0,接下来的枚举子取值是前面一个枚举子的取值+1,例如:
enum weather {sunny, cloudy, rainy, windy};
其中
sunny == 0,
cloudy == 1,

rainy == 2,
windy == 3;
以上是默认情况,有时候我们希望显式地指定某个枚举子的值,那么会出现什么情况呢?看看:
enum some_fruit {apple = 3, orange, banana = 4, bear};
好了,apple == 3, banana == 4; 那么orange和bear呢?记得前面说过一句,默认下”接下来的枚举子取值是前面一个枚举子的取值+1“。既然这两个枚举子没有显式赋值,那么就按照默认规则办事,所以 orange == 4, bear == 5.
从这个例子也可以看出,同一枚举中枚举子的取值不需要唯一。这样有什么用处呢?下面是个简单的例子:
enum some_big_cities {
Guangzhou = 4,
Shenzhen = 4,
Hongkong = 4,
Shanghai = 2,
Beijing = 3,
Chongqi = 3
};
以上简单地按区域,将五个城市按照华南(4),华东(2), 华北(3)的几个城市分类了。
4、枚举变量的定义、初始化和赋值
既然每个枚举都是一个类型,那么由这个类型自然可以声明变量,例如,由前面定义的some_big_cities:
some_big_cities where_I_am;
需要注意的是,在声明where_I_am时没有初始化,如果这时打印where_I_am的值: enum some_big_cities {
Guangzhou = 4,
Shenzhen = 4,
Hongkong = 4,
Shanghai = 2,
Beijing = 3,
Chongqi = 5};
int main(void)
{
some_big_cities wh;
cout<<"the value is: "<<wh<<endl;
return 0;
}
输出将是the value is: 1. 然而,如果声明wh为全局变量,则另一种情况:
enum some_big_cities {Guangzhou = 1 Shenzhen = 1, Hongkong = 1,
Shanghai = 2, Beijing = 3, Chongqi = 5};
some_big_cities wh;
int main(void)
{
cout<<"the value is: "<<wh<<endl;
return 0;
}
输出将是the value is: 0;
以上结果是在Visual C++ 2005 Express中得到,不知道其它编译器情况如何,也不知为什么得到这样的结果。下来再找找资料。
定义一个枚举变量时,可以给它初始化,例如:
some_big_cities wh = Guangzhou;
注意等号右边只能取枚举子中的某一个;特别地,以Guangzhou为例,虽然Guangzhou==4, 但以下初始化是出错的:
some_big_cities wh = 4;
Visual C++ 2005编译器提示:
error C2440: 'initializing' : cannot convert from 'int' to 'some_big_cities'
可见,不能直接地把一个整型赋值给一个枚举变量,因为枚举和整型是不同类型的,除非显式转换。关于枚举与整型的关系,后面再讲。
除了初始化,枚举变量也有赋值运算:
some_big_cities wh;
wh = Guangzhou;
wh = Shanghai;
或者
some_big_cities wh1 = Guangzhou;
some_big_cities wh2 = Shanghai;
wh2 = wh1;
5、枚举的取值范围
如果某个枚举中所有枚举子的值均非负,该枚举的表示范围就是[0:2^k-1],其中2^k是能使所有枚举子都位于此范围内的最小的2的幂;如果存在负的枚举值,该枚举的取值范围就是[-2^k,2^k-1].例如:
enum e1 {dark, light}; //范围0:1
enum e3 {min = -10, max = 1000}; //范围-1024:1023
6、枚举与整型的关系
整型值只能显式地转换成一个枚举值,但是,如果转换的结果位于该枚举取值范围之外,则结果是无定义的。
enum e1 {dark = 1, light = 10};
e1 VAR1 = e1(50); //无定义
e1 VAR2 = e1(3); //编译通过
在这里也说明了不允许隐式地从整型转换到枚举的原因,因为大部分整型值在特定的枚举里没有对应的表示。
至于枚举可以当作特定的整型数来用的例子,从open_modes可以体会。
7、自定义运算符
枚举是用户自定义类型,所以在用户可以为它定义自身的操作,例如++或者<<等。但是,在没有定义之前,不能因为枚举像整型就可以默认使用,例如:
enum SomeCities
{
zhanjiang,
Maoming,
Yangjiang,
Jiangmen,
Zhongshan
};
SomeCities oneCity;
for (oneCity = zhanjiang; oneCity != Zhongshan; ++oneCity)
{
cout<<oneCity<<endl;
}

以上的++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
一个枚举类型的sizeof就是某个能够容纳其范围的整型的sizeof, 而且不会大于sizeof(int), 除非某个枚举子的值不能用int或者unsigned int来表示。
在32位机器中,sizeof(int)一般等于4。前面介绍的所有枚举,例如,
enum SomeCities
{
zhanjiang,
Maoming,
Yangjiang,
Jiangmen,
Zhongshan
};

计算其sizeof, 可能是1,也可能是是4。在我的intel E2160双核、32位机器中,得到4。 -----------------------------------------------------------------------------------
[注1, Begin]
由于通过将整型数显式转换就可能得到对应枚举类型的值,所以声明一个枚举来达到限制传递给函数的参数取值范围还是力不从心的,以下是一个例子:
enum SomeCities
{
zhanjiang=1, //1
Maoming, //2
Yangjiang, //3
Jiangmen, //4
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函数。

java枚举类型

java 枚举类型enum 的使用
最近跟同事讨论问题的时候,突然同事提到我们为什么java 中定义的常量值不采用enmu 枚举类型,而采用public final static 类型来定义呢?以前我们都是采用这种方式定义的,很少采用enum 定义,所以也都没有注意过,面对突入起来的问题,还真有点不太清楚为什么有这样的定义。既然不明白就抽时间研究下吧。
Java 中的枚举类型采用关键字enum 来定义,从jdk1.5才有的新类型,所有的枚举类型都是继承自Enum 类型。要了解枚举类型,建议大家先打开jdk 中的Enum类简单读一下,这个类里面定义了很多protected 方法,比如构造函数,如果要使用这些方法我们可以把枚举类型定义到当前类中。每个枚举类型,都有自己的名字和顺序,当我们输出一个枚举类型的时候,会输入枚举类型的name ,具体可以参考下面的例子。
一、 通常定义常量方法
我们通常利用public final static 方法定义的代码如下,分别用1 表示红灯,3 表示绿灯,2 表示黄灯。

package com.csdn.myEnum;
public class Light {
/* 红灯 */
public final static int RED =1;
/* 绿灯 */
public final static int GREEN =3;
/* 黄灯 */
public final static int YELLOW =2;
}

二、 枚举类型定义常量方法
枚举类型的简单定义方法如下,我们似乎没办法定义每个枚举类型的值。比如我们定义红灯、绿灯和黄灯的代码可能如下:

public enum Light {
RED , GREEN , YELLOW ;
}

我们只能够表示出红灯、绿灯和黄灯,但是具体的值我们没办法表示出来。别急,既然枚举类型提供了构造函数,我们可以通过构造函数和覆写toString方法来实现。首先给Light 枚举类型增加构造方法,然后每个枚举类型的值通过构造函数传入对应的参数,同时覆写toString 方法,在该方法中返回从构造函数中传入的参数,改造后的代码如下:

public enum Light {
// 利用构造函数传参
RED (1), GREEN (3), YELLOW (2);

// 定义私有变量
private int nCode ;

// 构造函数,枚举类型只能为私有
private Light( int _nCode) {
this . nCode = _nCode;
}

@Override
public String toString() {
return String.valueOf ( this . nCode );
}
}

三、 完整示例代码
枚举类型的完整演示代码如下:

package com.csdn.myEnum;

import java.util.EnumMap;
import java.util.EnumSet;

public class LightTest {

// 1. 定义枚举类型
public enum Light {
// 利用构造函数传参
RED (1), GREEN (3), YELLOW (2);

// 定义私有变量
private int nCode ;

// 构造函数,枚举类型只能为私有
private Light( int _nCode) {
this . nCode = _nCode;
}

@Override
public String toString() {
return String.valueOf ( this . nCode );
}
}

/**
* @param args
*/
public static void main(String[] args ) {

// 1. 遍历枚举类型
System. out .println( " 演示枚举类型的遍历 ......" );
testTraversalEnum ();

// 2. 演示 EnumMap 对象的使用
System. out .println( " 演示 EnmuMap 对象的使用和遍历 ....." );
testEnumMap ();

// 3. 演示 EnmuSet 的使用
System. out .println( " 演示 EnmuSet 对象的使用和遍历 ....." );
testEnumSet ();
}

/**
* 演示枚举类型的遍历
*/
private static void testTraversalEnum() {
Light[] allLight = Light.values ();
for (Light aLight : allLight) {
System. out .println( " 当前灯 name : " + aLight.name());
System. out .println( " 当前灯 ordinal : " + aLight.ordinal());
System. out .println( " 当前灯: " + aLight);
}
}

/**
* 演示 EnumMap 的使用, EnumMap 跟 HashMap 的使用差不多,只不过 key 要是枚举类型
*/
private static void testEnumMap() {
// 1. 演示定义 EnumMap 对象, EnumMap 对象的构造函数需要参数传入 , 默认是key 的类的类型
EnumMap<Light, String> currEnumMap = new EnumMap<Light, String>(
Light. class );
currEnumMap.put(Light. RED , " 红灯 " );
currEnumMap.put(Light. GREEN , " 绿灯 " );
currEnumMap.put(Light. YELLOW , " 黄灯 " );

// 2. 遍历对象
for (Light aLight : Light.values ()) {
System. out .println( "[key=" + aLight.name() + ",value="
+ currEnumMap.get(aLight) + "]" );
}
}

/**
* 演示 EnumSet 如何使用, EnumSet 是一个抽象类,获取一个类型的枚举类型内容<BR/>
* 可以使用 allOf 方法
*/
private static void testEnumSet() {
EnumSet<Light> currEnumSet = EnumSet.allOf (Light. class );
for (Light aLightSetElement : currEnumSet) {
System. out .println( " 当前 EnumSet 中数据为: " + aLightSetElement);
}

}
}

执行结果如下:

演示枚举类型的遍历 ......
当前灯 name : RED
当前灯 ordinal : 0
当前灯: 1
当前灯 name : GREEN
当前灯 ordinal : 1
当前灯: 3
当前灯 name : YELLOW
当前灯 ordinal : 2
当前灯: 2
演示 EnmuMap 对象的使用和遍历 .....
[key=RED,value= 红灯 ]
[key=GREEN,value= 绿灯 ]
[key=YELLOW,value= 黄灯 ]
演示 EnmuSet 对象的使用和遍历 .....
当前 EnumSet 中数据为: 1
当前 EnumSet 中数据为: 3
当前 EnumSet 中数据为: 2

四、 通常定义常量方法和枚举定义常量方法区别
以下内容可能有些无聊,但绝对值得一窥
1. 代码:
public class State {
public static final int ON = 1;
public static final Int OFF= 0;
}

有什么不好了,大家都这样用了很长时间了,没什么问题啊。
首先,它不是类型安全的。你必须确保是int
其次,你还要确保它的范围是0 和1
最后,很多时候你打印出来的时候,你只看到 1 和0 ,

但其没有看到代码的人并不知道你的企图,抛弃你所有旧的public static final 常量
2. 可以创建一个enum 类,把它看做一个普通的类。除了它不能继承其他类了。(java 是单继承,它已经继承了Enum),
可以添加其他方法,覆盖它本身的方法
3. switch() 参数可以使用enum 了
4. values() 方法是编译器插入到enum 定义中的static 方法,所以,当你将enum 实例向上转型为父类Enum 是,values() 就不可访问了。解决办法:在Class中有一个getEnumConstants() 方法,所以即便Enum 接口中没有values() 方法,我们仍然可以通过Class 对象取得所有的enum 实例
5. 无法从enum 继承子类,如果需要扩展enum 中的元素,在一个接口的内部,创建实现该接口的枚举,以此将元素进行分组。达到将枚举元素进行分组。
6. 使用EnumSet 代替标志。enum 要求其成员都是唯一的,但是enum 中不能删除添加元素。
7. EnumMap 的key 是enum ,value 是任何其他Object 对象。
8. enum 允许程序员为eunm 实例编写方法。所以可以为每个enum 实例赋予各自不同的行为。
9. 使用enum 的职责链(Chain of Responsibility) . 这个关系到设计模式的职责链模式。以多种不同的方法来解决一个问题。然后将他们链接在一起。当一个请求到来时,遍历这个链,直到链中的某个解决方案能够处理该请求。
10. 使用enum 的状态机
11. 使用enum 多路分发

⑶ C语言问题,关于枚举类型的

与编译器的行为有关,枚举实际上也是一个整形。
但在c/c++强类型的前提下,这是不行的。如果允许,那么你的编译器不够严谨或设置问题。
就拿你的例子说,枚举里只有4个值,但你给赋值超过4,这就是错的。

⑷ C语言enum类型的问题

这个本来就没有错啊!
枚举类型是派生自System.Enum的一种独特的值类型,用于声明一组命名的常数。每种枚举类型均有一种基础类型,此基础类型可以使除char类型以外的任何整型。
枚举元素的默认基础类型为int 默认情况下,第一个枚举元素的值为0,后面每个枚举元素的值依次递增1 。如
emum weekday{sun,mon,tue,wed,thu,fri,sat},在此枚举中,sun的值为0 ,mon为1 以此类推。也可emum weekday{sun=1,mon,tue,wed=sun,thu,fri,sat},强制第一个枚举元素sun的值为1,mon为2,tue为3,而wed又强制为1,依次类推。

⑸ C++枚举类型

函数本身是要求返回枚举类型的,怎么能返回string呢?这一般会报错的,也许某些编译器不会,但至于返回什么,就看那个不报错的编译器怎么处理了。如果是返回枚举类型,那他不是返回一个完整的字符串,而只是返回你定义的枚举类型中那个字符串的值。

⑹ 枚举类型

对于C#中的枚举类型不仅可以提高程序的可读性,而且可以减少因底层值发生改变而导致的程序改动。另外一个好处是枚举类型是强类型,以enum类型作为参数传递时,接受方法必须有一个相同的匹配参数;否则编译器将会报错。

枚举可用在数据的表示,如性别:男,女,和结果的表示,如一个方法的几种可能的返回值.

如何用好枚举? 要彻底,枚举就是枚举,不要认为它是数字或字符串,虽然它们之间可以转换.

枚举如何与其它类型转换?

enum Country
{
中国=1,
美国=2,
}

1.enum 变 string
Country c = Country.中国;
string sc = c.ToString();
Debug.Assert(sc == "中国");

2.enum 变 int
int ic = (int)c;
Debug.Assert(ic == 1);

3.int 变 enum
int ic = 1;
Country c = (Country)i;
Debug.Assert(c == Country.中国);

4.string 变 enum
Country c = (Country)Enum.Parse(typeof(Country), "中国");
Debug.Assert(c == Country.中国);

大概是这样,许多公司使用枚举不多,但枚举在我们公司得到广泛的应用.枚举的好处是易写(写的时候清楚知道应该使用哪个值,而不是去想这里该返回1还是2)易处理(处理的时候对应每个枚举值都清楚知道它的含义,而不是想1代表什么)易读(读的时候含义很直接明了),关于枚举的详细欢迎加QQ群:7229630来讨论.

⑺ 枚举类型的使用

具体的枚举类型的使用可以去msdn去看,从你的错误提示看,都是提示类型不匹配的问题。

enum BAND CurrentBand =Band_MW;
enum BAND band;
band=CurrentBand+1;
以上语法是不对的,因为虽然Band_MW有个数字的序号,但是整形和枚举类型还是不同的,需要进行牵制类型转换。针对这个我写了个小程序。
#include<stdio.h>
enum BAND {Band_LW,Band_MW,Band_FM,Band_SW,Band_OIRT};
void setFrequency (enum BAND band){
printf("%d\n",band);
}
void main(){
enum BAND CurrentBand =Band_MW;
enum BAND band;
band=(BAND)((int)CurrentBand+1);//这里一定要转换。
setFrequency(band);
}
这样是可以的。我还要说一下,我是用的是VS2008,对不同的编译器可能会不同,希望有帮助。

热点内容
怎么翻录加密视频 发布:2025-02-06 21:58:12 浏览:549
逃离塔科夫启动器选什么服务器 发布:2025-02-06 21:44:48 浏览:291
我的世界手机版服务器开服教程 发布:2025-02-06 21:43:01 浏览:271
微信娱乐源码 发布:2025-02-06 21:34:53 浏览:529
编译翻译运行 发布:2025-02-06 21:05:20 浏览:200
安卓源码版本 发布:2025-02-06 20:51:34 浏览:432
安卓系统网络播放器哪个好 发布:2025-02-06 20:42:02 浏览:818
头条缓存的视频格式 发布:2025-02-06 20:32:18 浏览:116
ftp不显示文件夹 发布:2025-02-06 20:30:37 浏览:127
苹果手机解压怎么打开 发布:2025-02-06 20:29:35 浏览:476