Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Enum和Define语句之间的差异_C++_C_Enums_C Preprocessor - Fatal编程技术网

C++ Enum和Define语句之间的差异

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是一个预处理器命令,就像在编辑

在C/C++中使用define语句和enum语句有什么区别(在C或C++中使用它们时有什么区别)

例如,一个人应该在什么时候使用

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/由于编译器可以使用枚举,因此可以将它们的符号信息传递给调试器,从而使调试更容易。

通常首选枚举,而不是定义使用枚举有意义的地方:

  • 调试器可以向您显示
    enum
    s值的符号名(“
    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