#define还是enum?

时间:2010-06-28 17:42:06

标签: c

  

可能重复:
  Why use enum when #define is just as efficient?

用C语言编程时,最好在状态机中使用#define语句或枚举吗?

9 个答案:

答案 0 :(得分:46)

技术上没关系。编译器甚至很可能为这两种情况创建相同的机器代码,但枚举有三个优点:

  1. 使用正确的编译器+调试器组合,调试器将按枚举名称而不是按其编号打印枚举变量。所以“StateBlahBlup”读起来比“41”好得多,不是吗?

  2. 您没有明确地为每个州提供一个数字,如果您允许,编译器会为您编号。假设您已经有20个状态,并且您想在中间添加一个新状态,如果是定义,则必须自己进行所有重新编号。在枚举的情况下,您只需添加状态,编译器将为您重新编号低于此新状态的所有状态。

  3. 您可以告诉编译器警告您switch语句是否不处理所有可能的枚举值,例如:因为你忘了处理某些值,或者因为enum被扩展了但是你忘了也更新处理枚举值的switch语句(如果有default的情况就不会发出警告,因为所有未明确处理的值最终都会默认情况)。

答案 1 :(得分:12)

由于状态是相关元素,我认为最好有一个定义它们的枚举。

答案 2 :(得分:9)

没有确定的答案。 enum为您提供范围和自动值赋值,但不提供对常量类型的任何控制(始终为signed int)。 #define忽略作用域,但允许您使用更好的键入工具:让您选择常量类型(通过使用后缀或通过在定义中包含显式强制转换)。

所以,选择对你来说更重要的东西。对于状态机,enum可能是更好的选择,除非您有充分的理由来控制类型。

答案 3 :(得分:8)

我更喜欢enum。它们更紧凑,更“安全”。您还可以在枚举中暗示订单,这可能对状态机有帮助。如果可能,应该避免使用#defines,因为它们会覆盖源代码中的所有实例,这可能会导致一些难以调试的意外操作。

答案 4 :(得分:2)

#define指令可能会产生许多意想不到的后果,并且不遵循常见的范围规则。有相关数据时使用枚举。

更多信息:http://www.embedded.com/columns/programmingpointers/9900402?_requestid=341945 [C ++材料,但仍然有点相关]

答案 5 :(得分:2)

如果您的编译器支持enum,那么这将是首选。如果做不到这一点,请务必使用#define。所有C ++编译器和现代C编译器都应支持enum,但较旧的编译器(特别是针对嵌入式平台的编译器)可能不支持enum

如果必须使用#define,请确保用括号定义常量,以避免预处理器错误:

#define RED_STATE    (1)
#define YELLOW_STATE (2)
#define GREEN_STATE  (3)

答案 6 :(得分:1)

您可以使用此技巧使编译器检查#define值的类型。

#define VALUE_NAME ((TYPE_NAME) 12)

然而#define的真正问题是它可以在应用程序代码中重新定义。 (当然编译器会警告你。)

答案 7 :(得分:0)

当你有独占选项时,

enum很棒,但你不能使用它们来定义位域标志,如下所示:

#define SQ_DEFAULT 0x0
#define SQ_WITH_RED 0x1
#define SQ_WITH_BLUE 0x2

void paint_square(int flags);

然后你可以用:

画出红蓝色方块
paint_square(SQ_WITH_RED | SQ_WITH_BLUE);

...您无法使用enum

答案 8 :(得分:0)

你可以使用你想要的任何东西。

尽管每个人都在说我也想把我加起来作为Enums的投票。

如果您使用相关数据(如果是状态机),则应始终首选枚举,您也可以在枚举中定义有助于实现状态机的顺序。

进一步的枚举将保证您的程序安全,因为所有枚举只是类型,所以他们也会避免任何可能的混淆。

在状态机或相关数据的情况下不应使用#define。无论如何,这是我的建议,但没有硬性规定。

另外,我想补充一点,即如果将来使用或者如果被其他人阅读,枚举将为您的代码添加更多可读性和可理解性。当你拥有一个非常大的程序并且程序中有很多#defines而不是你用于你的状态机时,这是一个重要的点。

相关问题