枚举与定义语句的区别

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

例如,什么时候应该使用

enum {BUFFER = 1234}; 

过度

 #define BUFFER 1234 

enum定义了一个语法元素。

#define是一个预处理器指令, 编译器看到代码之前执行,因此不是C本身的语言元素。

通常枚举是首选,因为它们是types安全的,更容易发现。 定义很难find并且可能有复杂的行为,例如,一段代码可以重新定义另一个定义的#define 。 这可能很难追查。

#define语句在编译器看到代码之前由预处理器处理,所以它基本上是一个文本replace(实际上它使用参数等更智能一些)。

枚举是C语言本身的一部分,具有以下优点。

1 /他们可能有types,编译器可以键入检查它们。

2 /由于编译器可以使用它们,所以它们上面的符号信息可以传递给debugging器,使debugging更容易。

Define是一个预处理器命令,就像在编辑器中“replace全部”一样,它可以用另一个stringreplace一个string,然后编译结果。

例如,Enum是一个特殊的types,如果你写:

 enum ERROR_TYPES { REGULAR_ERR =1, OK =0 } 

存在称为ERROR_TYPES的新types。 确实REGULAR_ERR的结果是1,但是从这个types转换为int应该会产生一个转换警告(如果你把编译器configuration的很高)。

总结:它们都是相似的,但是在使用枚举的时候,你可以通过types检查来获得利益,通过定义你可以简单地replace代码string。

枚举通常优先于#define,只要使用enum有意义:

  • debugging器可以显示一个enum值(“ openType: OpenExisting ”)的符号名称,而不是“ openType: 2
  • 你可以从名称冲突中得到更多的保护,但是这并没有那么糟糕(大多数编译器都会对#define ition提出警告。

最大的区别是你可以使用枚举types:

 // Yeah, dumb example enum OpenType { OpenExisting, OpenOrCreate, Truncate }; void OpenFile(const char* filename, OpenType openType, int bufferSize); 

这使您可以对参数进行types检查(不能混淆openType和bufferSize),并且可以很容易地find哪些值是有效的,从而使您的接口更容易使用。 一些IDE甚至可以让你完成智能代码!

如果可能,最好使用枚举。 使用枚举为编译器提供了关于源代码的更多信息,编译器从不会看到预处理器的定义,从而携带更less的信息。

例如,为了实现一堆模式,使用枚举可以使编译器在交换机中捕获缺less的case -statements。

枚举可以将多个元素分组在一个类别中:

 enum fruits{ apple=1234, orange=12345}; 

而#define只能创build不相关的常量:

 #define apple 1234 #define orange 12345 

#define是一个预处理器命令,枚举是C或C ++语言。

在这种情况下使用#define的枚举总是更好。 一件事是types安全。 另一个是,当你有一个值的序列,你只需要在枚举的序列的开始,其他值得到连续的值。

 enum { ONE = 1, TWO, THREE, FOUR }; 

代替

 #define ONE 1 #define TWO 2 #define THREE 3 #define FOUR 4 

作为一个侧面说明,还有一些情况下,你可能不得不使用#define(通常为某种macros,如果你需要能够构build一个包含常量的标识符),但这是一种macros观黑魔法,而且非常非常难得的是要走的路。 如果你去这些肢体,你可能应该使用一个C ++模板(但如果你坚持使用C …)。

如果你只想要这个单一的常量(比如缓冲区大小),那么我不会使用枚举,而是一个定义。 我会使用枚举的东西,如返回值(这意味着不同的错误条件),无论我们需要区分不同的“types”或“案件”。 在这种情况下,我们可以使用枚举来创build一个我们可以在函数原型等中使用的新types,然后编译器可以更好地检查代码。

除了所有已经写好的东西,一个说,但没有显示,而是有趣的。 例如

 enum action { DO_JUMP, DO_TURNL, DO_TURNR, DO_STOP }; //... void do_action( enum action anAction, info_t x ); 

考虑到作为一种types的行动使事情更清楚。 使用define,你会写

 void do_action(int anAction, info_t x); 

对于积分常量值,我更喜欢enum #define 。 使用enum似乎没有什么缺点(折扣多一点打字less的缺点),但是你有一个好处,就是enum可以作用域,而#define标识符具有全局作用域。

使用#define通常不是一个问题,但是因为enum没有缺点,所以我就这样做了。

在C ++中,我通常也更喜欢enum const int即使在C ++中, const int可以用来代替文字整数值(不像在C中),因为enum可移植到C(我仍然工作很多)。

如果你有一组常量(比如“星期几”),那么枚举将是可取的,因为它表明它们是分组的; 正如贾森所说,他们是types安全的。 如果它是一个全局常量(比如版本号),那么更多的是使用#define ; 虽然这是很多辩论的主题。

除了上面列出的优点以外,还可以将枚举的范围限制为一个类,结构或命名空间。 就我个人而言,我喜欢在任何时候都有最小数量的相关符号,这是使用枚举而不是#define的另一个原因。

enum超过一个定义列表的另一个好处是编译器(至lessgcc)可以在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的forms完成的,情况就不会如此。

枚举更多地用于枚举某种集合,如一周中的几天。 如果你只需要一个常量, const int (或者double等)比enum要好。 我个人不喜欢#define (至less不是为了定义一些常量),因为它不能给我types安全,但是如果它更适合你,当然可以使用它。

创build枚举不仅可以创build文字,还可以创build对这些文字进行分组的types:这可以增加编译器能够检查的代码的语义。

此外,使用debugging器时,您可以访问枚举文字的值。 #define并非总是如此。

枚举:

1.通常用于多个值

2.枚举中有两个名字是name,另一个是名字name的值必须区分,但value可以是相同的。如果我们没有定义value,那么枚举名的第一个值是0 second value是1,依此类推,除非明确指定值。

他们可能有types和编译器可以键入检查他们

4.使debugging容易

我们可以把它的范围限制在一个class级。

定义:

1.我们只需要定义一个值

它通常将一个stringreplace为另一个string。

它的范围是全球性的,我们不能限制它的范围

总的来说,我们必须使用枚举

没有什么区别。 C标准说枚举具有整型,而枚举常量是inttypes,所以它们可以和其他整型自由混合,没有错误。 (另一方面,如果没有明确的转换就不允许这样的混合,明智地使用枚举可能会遇到某些编程错误。)

枚举的一些优点是数值自动分配,debugging器可以在枚举variables被检查时显示符号值,并且它们遵守块范围。 (当枚举被不加区分地混合时,编译器也会产生非致命的警告,因为这样做可能仍然被认为是坏风格,即使它不是严格违法的。)缺点是程序员很less控制这些非致命的警告。 一些程序员也怨恨不能控制枚举variables的大小。

虽然上面的几个答案build议使用枚举的各种原因,我想指出的是,使用定义在开发接口时具有实际优势。 你可以引入新的选项,你可以让软件有条件地使用它们。

例如:


     #define OPT_X1 1 / *在版本1中引入* /
     #define OPT_X2 2 / *在版本2中引入* /

然后可以用任何版本编译的软件都可以


     #ifdef OPT_X2
     int flags = OPT_X2;
     #其他
     int flags = 0;
     #万一

枚举时,如果没有运行时特征检测机制,这是不可能的。