C与C++中的enum类型使用

转载 2013年12月02日 23:27:57

1.enum常量与enum变量

对于enum类型,定义enum时在{}中定义的属于enum常量,这些量不可以被更改,同时可以在程序中任意地方声明一个enum变量,但enum变量必须用enum常量进行赋值

enum myenum

{

first, //enum常量

second //enum常量

};

.......

enum enumVar = first; //enum变量用enum常量进行赋值初始化,这里注意要在一个命名空间内。

2.在C语言中对于enum类型:

K&R的The   C   Programmingh   Language   2nd,书中说:“尽管可以声明enum类型的变量,但编译器不检查这种类型的变量中存储的值是否为该枚举的有效值。不过,枚举变量提供这种检查,因此枚举比#define更具优势。”枚举变量提供这种检查,什么意思?枚举变量会自己检?当然不是,作者也许想说程序员自己可以写个程序检查付给枚举变量的值是否为该枚举的有效值。

/* 包含头文件 */ 
#include 
<stdio.h>

/* 枚举类型 */
enum months{JAN = 1, FEB};

/* 函数原型 */
void enumeration(enum months m);

main()
{
    
enum months a = 2; 
    
enum months b = 50;        /* C中不需要强制转换为enum months类型 */

    enum months c = JAN;

    enumeration(a);
    enumeration(b);

    
return 0;
}

/* enumeration函数:检测枚举变量存储的值是否为该枚举的有效值 */
void enumeration(enum months m)
{
    
switch (m)
    {
    
case JAN:
        printf(
"JAN: %d\n", JAN);
        
break;

    
case FEB:
        printf(
"FEB: %d\n", FEB);
        
break;

    
default:
        printf(
"%d不是该枚举的有效值!\n", m);
        
break;
    }
}


而这段代码如果改为C++源文件编译,却不能通过。原因如下:

根据C标准的规定,枚举常量的类型为int,枚举变量的类型应该与char、有符号或无符号整型兼容。因此,枚举变量可以接受 char、有符号或无符号整型数,而不限于仅从此枚举类型所定义的枚举常量中取值。由于上述原因,在C語言中无法从語法上保证枚举变量只能在定义的枚举成员中取值,只能由程序员自身保证不使用除枚举成员之外的值。

关于這一点,很多介绍C语言的书上或者资料上的描述是不正确的,应该加以注意。

但是,如果给枚举变量赋枚举成员之外的值,有的编译器可能会对此产生警告,有的则不會。因为这种行为不违反C标准的规定,编译器对此如何反应都是有道理的。

然而对于C++来说,编译器会禁止给枚举变量赋予枚举成员之外的值。这是因为C++是一种强类型语言,枚举类型不等同于 int 等其它类型。虽然枚举类型可以隐式转化为 int 等类型,但是 int 等类型却不能自动转化为枚举类型,除非使用强制类型转化。因此,如果不使用强制类型转化的话,给枚举变量赋值则只能从枚举成员中选择。对于枚举类型要避免使用强制类型转换。原因如下:
 
The   C++   Programming   Language上说:   
如果某个枚举中所有枚举值非负,枚举的表示范围为[0 : 2^k-1];其中2^K是使所有枚举成员位于此范围内的最小的2的幂;如果是负的,就是[-2^k : 2^k-1]。 因此对一个给定的整数值,如果使用强制类型转换,而其值又不在枚举的表示范围以内,其行为是未定义的。

// 包含头文件  
#include <iostream.h>

int main()
{
    
enum months{JAN = 1, FEB, MAR};

    
//enum months a = 1;              //cannot convert from 'const int' to 'enum main::months'
    enum months a = (enum months)1;
    cout 
<< "a: " << a << endl;    //输出: a: 1

    
enum months b = (enum months)10;
    cout 
<< "b: " << b << endl;    //输出: b: 10 虽然输出10,但结果是未定义的,因为此枚举的表示范围为:0~3

    
return 0;
}
3.枚举类型的作用域问题

在C++中使用枚举类型不需要像C#中那样需要类型名作为标识符的一部分,如HTTP在C#中需要用TransProtocol::HTTP。这样在大型项目中将可能会出现命名冲突的问题,通常主要有几种解决方法。

1) 加前缀。例如,为TransProtocol的第一个成员都增加一个前缀ETP_,即:

enum TransProtocol { ETP_HTTP, ETP_FTP };

2) 使用命名空间,例如

namespace TransProtocol { enum TransProtocol { HTTP, FTP }; }

这样,在用到HTTP或FTP时就需要在前面加上域标识符TransProtocol::HTTP。

3) 将enum定义为类的嵌套类型。

class DataTransfer

{

public:

enum TransProtocol { HTTP, FTP };

......

};

DataTransfer::TransProtocol prot = DataTransfer::HTTP;

其实,后两种方案用法基本相同,可以根据引用所定义枚举的范围选择使用,不推荐使用第1种方法。



相关文章推荐

C++学习之enum类型

ENUM概况enum枚举类型是C/C++中的一种数据类型,与struct和class一样是用户自定义的类型,其特点在于enum类型的变量取值是有限的,是可以一一列举出来的。 ENUM定义C++ enu...
  • xywlpo
  • xywlpo
  • 2011年05月30日 09:52
  • 33952

C/C++使用心得:enum与int的相互转换

如何正确理解enum类型? 例如: enum Color { red, white, blue}; Color x; 我们应说x是Color类型的,而不应将x理解成enumerati...
  • lihao21
  • lihao21
  • 2011年09月27日 13:03
  • 46497

C++11学习笔记(3)—— enum

1.简介 以往的enum类型将枚举成员的作用域暴露在枚举变量之外,用户不需要指定枚举类型就可以直接使用枚举的内容,这就有可能会造成名字的冲突,为了解决该你问题,C++11引入了强类型的枚举类型(st...

深入理解C++枚举类型enum

参考:http://blog.csdn.net/weiwenhp/article/details/8476767 http://blog.csdn.net/mtfxabc/article/detail...
  • nawuyao
  • nawuyao
  • 2016年10月07日 11:04
  • 1557

深入理解C++枚举类型enum

为啥需要枚举类型 编程语言中的所有特性都是为了满足某种需求,达到某个目的还出现.不会莫名其妙的出现在那. 枚举可以用来保存一组属性的值.enum的全称是enumeration意思是列举 看着这句...
  • weiwenhp
  • weiwenhp
  • 2013年01月07日 16:02
  • 44847

C++中的enum

enum

C++之enum枚举量声明、定义、使用与枚举类详解

众所周知,C/C++语言可以使用#define和const创建符号常量,而使用enum工具不仅能够创建符号常量,还能定义新的数据类型,但是必须按照一定的规则进行,下面我们一起看下enum的使用方法。 ...

C++ enum的使用学习,一些基础内容的理解

版本:gcc-4.8.1   语言:C++11   说实话我个人在写C++内容的时候很少用到C的知识,比如string,我很少用到char*的写法,在项目里感觉char*这样的写法反而是比较多的。...

C++ enum类型遍历

C++ enum类型遍历

关于C/C++中 Class, Struct, enum的定义声明位置

 struct 和 enum定义的数据类型的作用域是本文件中。所以:a. 当一个struct的数据类型定义定义在.h文件中,.h文件被多个.c包含,这些.c文件又一起连接时,不会出现数据类型重复定义的...
  • dreamxu
  • dreamxu
  • 2010年09月06日 15:52
  • 7637
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C与C++中的enum类型使用
举报原因:
原因补充:

(最多只允许输入30个字)