菜鸟资源网站全面焕新升级啦!全新的界面设计,简洁而不失雅致,让您一目了然,轻松上手。我们还对资源分类进行了细致梳理,确保各类资源条理清晰,便于您按需筛选与查找。 立即查看

第十章:枚举和一组预处理的#define 有何不同,了解C++基本语言特性变量和类型

第十章:枚举和一组预处理的#define 有何不同,了解C++基本语言特性变量和类型

  经常遇到这样的问题:为某些属性定义一组可选择的值。例如,文件的打开状态可能会有3种:输入、输出和追加。记录这些状态值的一种方式是定义每种状态都与一个唯一的常量数值相关联。我们可以定义下面这些状态码:   虽然这种方式也可奏效,但是它存在...

当前版本

软件大小

软件语言

是否破解

  经常遇到这样的问题:为某些属性定义一组可选择的值。例如,文件的打开状态可能会有3种:输入、输出和追加。记录这些状态值的一种方式是定义每种状态都与一个唯一的常量数值相关联。我们可以定义下面这些状态码:

#define INPUT_MODE       0// 输入模式
#define OUTPUT_MODE    1 // 输出模式
#defineAPPEND_MODE     2// 追加模式

  虽然这种方式也可奏效,但是它存在一个明显的缺点:没有指出这些值是相关联的。枚举(enumeration)提供了一种替代方法,不但可定义整数数量集,而且还把它们进行了分组。

  枚举的定义包括关键字enum,其后是可选的枚举类型名称,接着是一个用花括号括起来并用逗号分隔的枚举成员(enumerators)列表。我们可把文件打开模式按枚举形式重新定义。

//INPUT_MODE is 0,OUTPUT_MODE is 1,APPEND_MODE is 2
typedef enum tagOPEN MODEs
{
  INPUT MODE,     //输入模式
  OUTPUT MODE,    //输出模式
  APPENDMODE,    //追加模式
}OPEN MODES;

  默认情况下,第一个枚举成员赋值为 0,后面的每个枚举成员赋值比前一个大1。如OPEN MODES枚举类型INPUT MODE等于0,OUTPUT MODE等于1,APPEND MODE 等于 2。

  每个枚举成员都是一个常量。在枚举定义时,可以为一个或多个枚举成员提供初始化值。用来初始化枚举成员的值必须是一个常量表达式。常量表达式是在编译时就能够计算出结果的整型表达式。字面值常量是常量表达式,正如一个通过常量表达式自我初始化的 const 对象也是常量表达式一样。例如,FORMS 枚举定义如下:

// SHAPE_FORM=1,SPHERE_FORM=2,CYLINDER_FORM=3, POLYGON_FORM=4
typedef enum tagFORMS     //形状枚举
    SHAPE_FORM=1,     //三角形
    SPHERE_FORM,      //球形
    CYLINDER_FORM,    //圆柱形
    POLYGON_FORM,     //多边形
} FORMS

在枚举类型 FORMS 中,显式地将 SHAPE_FORM 赋值为1,其他枚举成员隐式初始化:SPHERE_FORM初始化为2,CYLINDER_FORM初始化为3,POLYGONFORM初始化为 4。

接着再看POINTSTYPE枚举类型的定义:

//POINTS2D is 2,POINTS2W is3,POINTS3D is 3, POINTS3W is4
enum POINTS TYPE      //点类型枚举
{
  POINTS2D =2,       //平面二维点
  POINTS2W,
  POINTS3D =3,       //立体三维点
  POINTS3W,
};

  在 POINTSTYPE枚举类型中,枚举成员 POINTS2D显式初始化为 2;POINTS2W默认初始化,它的值比前一枚举成员的值大1,所以POINTS2W初始化为 3;枚举成员POINTS3D显式初始化为3;POINTS3W默认初始化,结果为 4。

  注意:枚举成员值可以不唯一,两个枚举成员可以具有相同的值;不能改变枚举成员的值;枚举成员是一个常量表达式,可用于需要常量表达式的任何地方。

  每个enum都定义唯一的类型。每个enum都定义了一种新的类型。和其他类型一样,可以定义和初始化POINTSTYPE类型的对象,也可以不同的方式使用这些对象。枚举类型对象的初始化或赋值,只能通过其枚举成员或同一枚举类型的其他对象来进行:

POINTS_TYPE pt3d= POINTS3D;             // ok: POINTS3D is a POINTS_TYPE enumerator
POINTS_TYPE pt2w =3;                    // error: pt2w initialized with int
pt2w =polygon;                          // error: polygon is not a Points enumerator
pt2w=pt3d;                              // ok: both are objects of Points enum type

  注意:不能用int数值初始化枚举类型变量,即使初始化的int数值与枚举类型相关联。

  通过#define宏也可以实现枚举类型的部分功能,但是有些功能#define宏是无法编码实现的。像枚举类型具有的类型检查,枚举类型值具有的数据值关联属性等,这些都是#define 宏无法匹敌的。

  我们通过文件打开函数的#define宏实现和枚举类型实现,对比一下两者的优劣。

  第一种实现:#define 宏实现。

#define INPUT_MODE    0    // 输入模式打开
#defineOUTPUT_MODE    1    // 输出模式打开
#defineAPPEND_MODE    2    // 追加模式打开
FILE *File_Open(const char *pszFileName, int nModes);  // 文件打开函数声明
int main()
{
  FILE *hFile =File_Open("a.txt",3);// File_Open 可正常编译通过
  retum 0;
}

  第二种实现:枚举类型实现。

//INPUT MODE  is 0,OUTPUT MODE  is 1, APPEND_MODE is 2
typedef enum tagOPEN_MODES
{
  INPUT MODE,         //输入模式打开
  OUTPUT MODE,       //输出模式打开
  APPEND MODE,       //追加模式打开
}OPEN_MODES;
FILE*File Open(const char*pszFileName,OPEN MODES nModes);//文件打开函数声明
int main()
{
  FILE*hFile =File_Open(”a.txt",3);// File Open无法编译通过,参数错误
  returm 0;
}

  第一种实现方式,虽然File_Open 传入了非法参数,但是依然可以编译通过,不会发出任何报警信息,但是这时函数行为已经无法确定了。
  第二种实现方式,在向函数传入非枚举类型值时,编译器将报出错误“参数不合法”。可以看出,通过枚举类型实现时,实参传入时确实进行了参数检查。
  最后,我们对枚举类型和#define 使用优劣情况进行总结:
  (1) enum 枚举值属于常量,#define 宏值不是常量。
  (2) enum 枚举具有类型,#define 宏没有类型。枚举变量具有与普通变量相同的诸如作用域、值等性质,但宏没有,宏不是语言的一部分,它是一种预处理替换符。枚举类型主要用于限制性输入,例如,某个函数的某参数只接受某种类型中的有限个数值,除此之外的其他数值都不接受,这时候枚举能很好地解决这个问题。因此,能用枚举尽量用枚举。
  (3) 宏没有作用域,宏定义后的代码都可使用这个宏。宏可以被重复定义,这可能导致宏的值被修改,所以不要用宏定义整型变量,建议用枚举或const。
  请谨记
  ● 枚举用于某些限制性输入环境,可限制某个参数接受有限个数组,而#define定义的系列宏无法实现这些功能。
  ● #define宏可以重复定义导致宏值可被修改,所以整型变量的宏尽量用枚举或const 替代。

第十章:枚举和一组预处理的#define 有何不同,了解C++基本语言特性变量和类型
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

常见问题

  • 如何安装和激活?

    每款软件会附带有安装教程,您打开安装包一目了然

  • 程序是否已损坏?文件损坏?还是其他错误?

    有错误问题,请您参考:https://www.xxx.com/error

  • 如何更新?正式激活后会发生什么情况?

    除非安装说明中另有说明,否则官方更新可能会导致无法激活。 要从本网站更新软件,您需要在此处下载此软件的新版本(如果可用),并将其安装在计算机上安装的版本之上(替换)。在这种情况下,您将保存此软件的激活和设置。

  • 如何下载?链接不起作用?

    我们使用百度网盘,132云盘和微软网盘,除了百度网盘,其他两款不限速,如果链接失效,请您联系客服处理

  • 已发布更新。我什么时候升级我的版本?

    所有软件如有更新,我们第一时间推送,视自己情况更新使用

  • 如何更改语言?

    打开“系统偏好设置”->“通用>语言和地区”->应用程序-“+”。 选择应用和语言。此方法适用于大多数应用程序。 Adobe 产品中的语言通常是在产品本身的安装阶段选择的。 游戏中的语言通常会在游戏本身的设置中发生变化。

  • 如何删除软件?

    有很多选择。最简单的方法是使用特殊的实用程序来卸载应用程序,例如App Cleaner Uninstaller 要删除 Adobe 产品,请使用 Creative Cloud Cleaner Tool

  • 需要远程帮助吗?

    网站已开通永久会员的可享受免费远程,如果非永久会员,远程安装另外收费

给TA打赏
共{{data.count}}人
人已打赏
技术教程

第九章:引用难道只是别人的替身,了解C++基本语言特性变量和类型

2024-2-18 11:39:36

技术教程

第十一章:为何struct x1{struct x1 stX};无法通过编译,了解C++基本语言特性变量和类型

2024-2-20 11:02:00

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧