#define还是enum?

可能重复:
为什么#define同样有效时使用枚举?

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

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

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

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

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

  3. 您可以告诉编译器警告您switch语句是否不处理所有可能的枚举值,例如因为您忘记处理某些值或因为枚举已被扩展但您忘记也更新处理枚举值的switch语句(它将但是,如果存在default情况,则不会发出警告,因为未明确处理的所有值都以默认情况结束)。

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

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

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

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

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

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

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

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

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

 #define VALUE_NAME ((TYPE_NAME) 12) 

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

当你有独家选项时, 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

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

仍然如同每个人都说我也想把我加起来作为对Enums的投票。

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

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

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

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