在函数内定义/使用宏是一种好的风格/实践吗?

问题描述 投票:0回答:2

我正在开发 STM32 微控制器,在某些功能中,我必须对位进行大量位移、逻辑运算(与、或、异或)、设置/清除位以及写入/读取此代码非常痛苦。

举个例子:假设我必须打开一个带有数字输出的设备,并且我有 5 个传感器需要检查,其中每个传感器都有自己专用的数字输入。其中一些需要为 TRUE,其他需要为 FALSE。

(伪)代码最终将如下所示:

注意:这段代码显然是废话/没有什么真正的功能,它只是为了解释原理。

#define SENSOR1 0
#define SENSOR2 1
#define SENSOR3 2
#define SENSOR4 3
#define SENSOR5 4

void DeviceOn(void) {
   uint8_t DIOPort = ReadDIOPort();
   if((DIOPort & (1 << SENSOR1)) && (!(DIOPort & (1 << SENSOR2))) && (DIOPort & (1 << SENSOR3))) {
      turnOnDevice();
   } else {
      turnOffDevice();
   }
}

如您所见,if 条件变得非常难看,如果涉及更多信号,它会变得越来越难以阅读。

我的想法是在函数内部定义宏,仅由/在该函数内使用,以使代码更具可读性。这看起来像这样。

void DeviceOn(void) {
    #define __POWER_ISOK (DIOPort & (1 << SENSOR1))
    #define __SAFETY_ISOK (!(DIOPort & (1 << SENSOR2)))
    #define __LIGHT_ISON (DIOPort & (1 << SENSOR3))
    #define __COFFEEMUG_ISFULL (DIOPort & (1 << SENSOR4))
    uint8_t DIOPort = ReadDIOPort();
    if(__POWER_ISOK && __SAFETY_ISOK && __LIGHT_ISON && __COFFEEMUG_ISFULL) {
        turnOnDevice();
    } else {
        turnOffDevice();
    }
}

恕我直言,if 条件比第一个示例更具可读性。

这被认为是“良好的编码风格”还是绝对不行?

我希望在函数内定义宏,因为它们在这个函数中使用,并且它使文档更容易:

  • 此代码的读者只需向上滚动到函数的开头,而不必在 C 文件甚至头文件中搜索定义。
  • 数字输入状态变量中位的定义是全局定义的(在 C 文件的开头),因为它们也用于其他函数。

当然,我会全局定义在多个函数中使用的任何宏。当然,我也可以全局定义所有宏,但我认为如果只在一个函数中使用的宏在该函数中定义,这会使代码更具可读性。

从技术上讲,我没有看到任何问题,因为预处理器应该替换构建过程中的宏,还是我错了?

c++ c macros
2个回答
1
投票

Marcos 没有作用域,它们的定义不会在函数末尾结束。

在函数内部定义宏以使其在函数之后保持定义状态是一种不好的做法,因为程序员希望定义在作用域结束时结束。您可以在函数末尾取消定义宏。这是一个很好的做法当首先需要宏时这并不常见。

不必要地使用宏是一种不好的做法。在这种情况下,最好使用常量变量。变量具有类型系统和作用域,这两者都使编写正确的程序变得更容易。

附注包含两个连续下划线的名称保留给语言实现。不要自己定义它们。


0
投票

替代解决方案:

#include <stdbool.h>

void DeviceOn(void)
{
    uint8_t DIOPort = ReadDIOPort();

    bool PowerIsOK       =    DIOPort & 1 << SENSOR1;
    bool SafetyIsOK      = ! (DIOPort & 1 << SENSOR2);
    bool LightIsOn       =    DIOPort & 1 << SENSOR3;
    bool CoffeeMugIsFull =    DIOPort & 1 << SENSOR4;

    if (PowerISOK && SafetyIsOK && LightIsOn && CoffeeMugIsFull)
        turnOnDevice();
    else
        turnOffDevice();
}
© www.soinside.com 2019 - 2024. All rights reserved.