C++ Enum和Define语句之间的差异
在C/C++中使用define语句和enum语句有什么区别(在C或C++中使用它们时有什么区别) 例如,一个人应该在什么时候使用C++ Enum和Define语句之间的差异,c++,c,enums,c-preprocessor,C++,C,Enums,C Preprocessor,在C/C++中使用define语句和enum语句有什么区别(在C或C++中使用它们时有什么区别) 例如,一个人应该在什么时候使用 enum {BUFFER = 1234}; 结束 enum定义语法元素 #define是预处理器指令,在编译器看到代码之前执行,因此不是C本身的语言元素 通常,枚举是首选的,因为它们是类型安全的,并且更容易发现。定义更难定位,并且可能具有复杂的行为,例如,一段代码可以重新定义另一段代码生成的#define。这可能很难找到。Define是一个预处理器命令,就像在编辑
enum {BUFFER = 1234};
结束
enum
定义语法元素
#define
是预处理器指令,在编译器看到代码之前执行,因此不是C本身的语言元素
通常,枚举是首选的,因为它们是类型安全的,并且更容易发现。定义更难定位,并且可能具有复杂的行为,例如,一段代码可以重新定义另一段代码生成的
#define
。这可能很难找到。Define是一个预处理器命令,就像在编辑器中执行“全部替换”一样,它可以用另一个字符串替换一个字符串,然后编译结果
Enum是类型的特例,例如,如果您编写:
enum ERROR_TYPES
{
REGULAR_ERR =1,
OK =0
}
存在一个名为ERROR\u TYPES的新类型。
的确,正则_ERR会产生1,但从该类型转换为int应该会产生转换警告(如果您将编译器配置为高详细性) 总结:
它们都很相似,但当使用enum时,您可以进行类型检查,而使用defines则可以简单地替换代码字符串。如果您有一组常量(如“一周中的几天”),则最好使用enum,因为它表明它们是分组的;而且,正如Jason所说,它们是类型安全的。如果它是一个全局常量(比如版本号),那么你就更需要使用
#define
来定义它;尽管这是一个有很多争议的话题。#define
语句是在编译器看到代码之前由预处理器处理的,因此它基本上是一种文本替换(使用参数等实际上更智能一些)
枚举是C语言本身的一部分,具有以下优点
1/它们可能有类型,编译器可以对其进行类型检查
2/由于编译器可以使用枚举,因此可以将它们的符号信息传递给调试器,从而使调试更容易。通常首选枚举,而不是定义使用枚举有意义的地方:
- 调试器可以向您显示
s值的符号名(“enum
”,而不是“openType:OpenExisting
”openType:2
- 您可以从名称冲突中获得更多的保护,但这并不像以前那么糟糕(大多数编译器警告重新定义)
// Yeah, dumb example
enum OpenType {
OpenExisting,
OpenOrCreate,
Truncate
};
void OpenFile(const char* filename, OpenType openType, int bufferSize);
这为您提供了参数的类型检查(您不能轻易地混淆openType和bufferSize),使查找有效值变得更容易,使接口更易于使用。一些IDE甚至可以为您提供intellisense代码完成功能!除了上面列出的优点之外,您还可以将枚举的范围限制为类、结构或命名空间。就我个人而言,我喜欢在一个时间内使范围内的相关符号数量最少使用枚举而不是#defines的另一个原因。枚举优于定义列表的另一个优点是,编译器(至少是gcc)可以在switch语句中未选中所有值时生成警告。例如:
enum {
STATE_ONE,
STATE_TWO,
STATE_THREE
};
...
switch (state) {
case STATE_ONE:
handle_state_one();
break;
case STATE_TWO:
handle_state_two();
break;
};
#define OPT_X1 1 /* introduced in version 1 */
#define OPT_X2 2 /* introduced in version 2 */
在前面的代码中,编译器能够生成一个警告,指出不是所有枚举值都在开关中处理。如果状态是按#define的方式处理的,则不会是这种情况。如果可能,最好使用枚举。使用枚举可以向编译器提供有关源代码的更多信息,预处理器定义是nev编译器可以看到er,因此携带的信息较少
例如,为了实现一组模式,使用枚举可以让编译器捕获开关中缺少的
case
-语句。枚举更多地用于枚举某种类型的集合,如一周中的几天。如果只需要一个常量,const int
(或double等)肯定比enum好。我个人不喜欢#define
(至少不喜欢某些常量的定义),因为它不会给我类型安全性,但如果它更适合你,你当然可以使用它。如果你只想要这个常量(比如缓冲大小)然后我将不使用枚举,而是使用define。我将使用枚举来处理返回值(这意味着不同的错误条件)以及需要区分不同“类型”或“案例”的任何地方。在这种情况下,我们可以使用枚举创建一个新类型,用于函数原型等,然后编译器可以更好地检查代码的完整性。枚举可以将多个元素分组到一个类别中:
enum fruits{ apple=1234, orange=12345};
而#define只能创建不相关的常量:
#define apple 1234
#define orange 12345
<强>定义是预处理器命令,枚举是C语言或C++语言。<强> < /P> 对于这类情况,最好使用enum over#define。一个是类型安全。另一个是,当您有一个值序列时,您只需在enum中给出序列的开头,其他值就会得到连续值
enum {
ONE = 1,
TWO,
THREE,
FOUR
};
而不是
#define ONE 1
#define TWO 2
#define THREE 3
#define FOUR 4
作为一个旁注,仍然有一些情况下,你可能不得不使用“γ”定义(通常是针对某种宏,如果你需要能够构造一个包含常量的标识符),但这是一个宏黑魔法,非常非常罕见,如果你去这些末端,你可能应该使用C++模板。(但是如果你坚持使用C…。
除了所有已经写好的东西外,还有一个说了但没有显示出来,反而很有趣enum action { DO_JUMP, DO_TURNL, DO_TURNR, DO_STOP };
//...
void do_action( enum action anAction, info_t x );
将动作视为一种类型会使事情更清楚。使用define,您可能会编写
void do_action(int anAction, info_t x);
对于积分常量值,我更喜欢
enum
而不是#define
。使用enum
似乎没有什么缺点(不考虑稍微多一些的微小缺点)
#define OPT_X1 1 /* introduced in version 1 */
#define OPT_X2 2 /* introduced in version 2 */
#ifdef OPT_X2
int flags = OPT_X2;
#else
int flags = 0;
#endif