在函数内定义/使用宏 - 好 style/practice?
define / use a Macro inside a fcuntion - good style/practice?
伙计们,我有一个问题要问那里的 C/C++ 语法/编码风格专家:
情况:我正在研究 STM32 微控制器,在某些功能中我必须对位、set/clear 位和写入 / 进行大量位移、逻辑运算(和、或、异或)阅读这段代码真的很痛苦。
举个例子:假设我必须打开一个带有数字输出的设备,我有 5 个传感器要检查,每个传感器都有自己专用的数字输入。其中一些需要为 TRUE,其他需要为 FALSE
一个(伪)代码最终看起来像这样:
注意:这段代码显然nonsense/nothing真正起作用了,只是为了解释原理。
#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 文件的开头),因为它们也用于其他函数。
当然,我会全局定义在多个函数中使用的任何宏。当然我也可以全局定义所有的宏,但是我认为如果只在一个函数中使用的宏定义在那个函数中,这样会使代码更具可读性。
技术上我没有看到任何问题,因为预处理器应该替换构建过程中的宏,或者我错了吗?
替代解决方案:
#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();
}
Marcos 没有作用域,它们的定义不会在函数结束时结束。
在函数内部定义宏,这样它们在函数之后仍然定义是一种不好的做法,因为程序员希望定义在作用域结束时结束。您可以取消定义函数末尾的宏。这是一个很好的做法当首先需要宏时这并不经常。
不必要地使用宏是一种不好的做法。在这种情况下,更好的做法是改用常量变量。变量有类型系统和范围,这两者都使编写正确的程序变得更容易。
P.S。包含两个连续下划线的名称保留给语言实现。不要自己定义它们。
伙计们,我有一个问题要问那里的 C/C++ 语法/编码风格专家:
情况:我正在研究 STM32 微控制器,在某些功能中我必须对位、set/clear 位和写入 / 进行大量位移、逻辑运算(和、或、异或)阅读这段代码真的很痛苦。
举个例子:假设我必须打开一个带有数字输出的设备,我有 5 个传感器要检查,每个传感器都有自己专用的数字输入。其中一些需要为 TRUE,其他需要为 FALSE
一个(伪)代码最终看起来像这样: 注意:这段代码显然nonsense/nothing真正起作用了,只是为了解释原理。
#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 文件的开头),因为它们也用于其他函数。
当然,我会全局定义在多个函数中使用的任何宏。当然我也可以全局定义所有的宏,但是我认为如果只在一个函数中使用的宏定义在那个函数中,这样会使代码更具可读性。
技术上我没有看到任何问题,因为预处理器应该替换构建过程中的宏,或者我错了吗?
替代解决方案:
#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();
}
Marcos 没有作用域,它们的定义不会在函数结束时结束。
在函数内部定义宏,这样它们在函数之后仍然定义是一种不好的做法,因为程序员希望定义在作用域结束时结束。您可以取消定义函数末尾的宏。这是一个很好的做法当首先需要宏时这并不经常。
不必要地使用宏是一种不好的做法。在这种情况下,更好的做法是改用常量变量。变量有类型系统和范围,这两者都使编写正确的程序变得更容易。
P.S。包含两个连续下划线的名称保留给语言实现。不要自己定义它们。