在C中使用什么而不是魔术数字

Kri*_*nan 6 c constants

我目前在我的代码中使用静态const,而不是使用"static const"与"#define"vs"enum"中提到的" magic numbers ".

void checkInvalidResponse (uint8_t response)
{
    static const uint8_t INVALID_RESP = 0xFF;

    if (response == INVALID_RESP)
    {
        /* Code for invalid response */
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我认为使用静态const会占用INVALID_RESP的编译代码中的内存.该语句还将转换为从内存执行LOAD然后执行比较的机器代码,而不是与作为指令的一部分提供的值进行比较.它是否正确?如果是这样,那么这个解决方案在速度和内存方面不是最佳的吗?

我目前正在更改代码以使用#defines

void checkInvalidResponse (uint8_t response)
{
    #define INVALID_RESP 0xFF

    if (response == INVALID_RESP)
    {
        /* Code for invalid response */
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,由于#define没有范围,#define的剪切和粘贴方面的行为是否会在多个编译器中保持一致?例如,如果稍后重新定义INVALID_RESP,那么重新定义后的行中的任何代码都会使用新值吗?

我看过的另一种方法是使用枚举.

void checkInvalidResponse (uint8_t response)
{
    typedef enum
    {
        INVALID_RESP = 0xFF
    } resp_t;

    if ((resp_t)response == INVALID_RESP)
    {
        /* Code for invalid response */
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,对枚举的类型转换将分配比所需更多的内存(处理器将执行32位(?)比较而不是8位比较).

在代码中使用而不是使用幻数的最佳方法是什么?

小智 3

我认为在所有情况下,编译器,至少在打开 -O2 的情况下,都会生成相同的代码。欺骗编译器做蠢事已经变得相当困难了。

通常,幻数在公共标头中定义,并在整个代码中根据需要使用。

对你来说更大的问题是,这重要吗?这是否位于代码的关键路径中,并且您将在很高比例的时间内执行此操作?光看名字我就猜不到。

将定义移至头文件将使您的代码不那么分散注意力。在 中checkInvalidResponse,读者并不关心 到底代表什么INVALID_RESPONSE,只关心测试通过或失败。