我想做那样的事情
#define GREATER_THAN_ZERO(a) a>0? 1:0
并在其他函数中使用此宏
void test(int x)
{ if (GREATER_THAN_ZERO(x) == 1) printf("more than zero");
else printf("less than zero");
}
但是当我使用测试功能时,它总是打印“小于零” 注意:这是一个不是真实情况的例子,但我想做类似的事情(在函数中使用宏) 有人可以帮我吗? 编辑 我有像那样的配置文件
#define LED_u8_MODE_0 LED_u8_REVERSE
#define LED_u8_MODE_1 LED_u8_NORMAL
在程序中我有一个宏功能
#define LED_u8_GET_MODE(LED_u8_INDX) (LED_u8_INDX == 0)? LED_u8_MODE_0: \
(LED_u8_INDX == 1)? LED_u8_MODE_1: \
(LED_u8_INDX == 2)? LED_u8_MODE_2: \
(LED_u8_INDX == 3)? LED_u8_MODE_3: 800
然后我在这个函数中使用它
void LED_voidSetLedOnWithIndx(u8 Copy_u8LedIndx)
{
if(LED_u8_GET_MODE(Copy_u8LedIndx) == LED_u8_NORMAL)
{
DIO_voidSetPinValue(Copy_u8LedIndx, DIO_u8_HIGH);
}
else //if(LED_u8_GET_MODE(Copy_u8LedIndx) == LED_u8_REVERSE)
{
DIO_voidSetPinValue(Copy_u8LedIndx, DIO_u8_LOW);
}
}
答案 0 :(得分:6)
我无法用你发布的代码重现这个问题,但是你提到它不是真实的情况,我确实知道了这个问题。
表达式未按预期关联。展开时,表达式为:
x>0? 1:0 == 1
分组为:
x>0? 1:(0 == 1)
相当于:
x>0? 1:0
这仍然按预期工作。但如果你改为:
if (GREATER_THAN_ZERO(x) == 0)
那么你最终会得到:
x>0? 1:0 == 0
或:
x>0? 1:(0 == 0)
总是1。
宏定义存在两个基本问题:(1)它不保护其参数不被错误关联,(2)它不保护结果不被错误关联。
编写它的正确方法是:
#define GREATER_THAN_ZERO(a) ((a) > 0 ? 1 : 0)
(a)
周围的括号允许您将表达式作为参数传递,而不必担心它会重新关联。整个宏体周围的括号允许您在表达式中使用宏而不重新关联。
在这种特殊情况下,?:
运算符是多余的,因为n > 0
始终返回0或1,因此您可以使用:
#define GREATER_THAN_ZERO(a) ((a) > 0)
结果相同。
同样,将结果与1
进行比较没有任何意义,并表明正在发生一些不寻常的事情。简单地写一下就更自然了:
if (GREATER_THAN_ZERO(x))
这隐式地测试它是否为非零。请注意,if (n)
相当于if (n != 0)
。
答案 1 :(得分:0)
评论太大,以便回答:我建议使用不同的格式(但调整了括号):
#define LED_u8_GET_MODE(LED_u8_INDX) \
( \
(LED_u8_INDX) == 0 \
? (LED_u8_MODE_0) \
: (LED_u8_INDX) == 1 \
? (LED_u8_MODE_1) \
: (LED_u8_INDX) == 2 \
? (LED_u8_MODE_2) \
: (LED_u8_INDX) == 3 \
? (LED_u8_MODE_3) \
: 800 \
)
或者你不同意这更容易阅读?
但是,很多三元运算符很难读取和处理,我宁愿考虑使用内联函数替换整个宏:
inline int ledGetMode(int index)
// (if need be, adjust parameter and return value types appropriately)
{
switch(index)
{
case 0:
return LED_u8_MODE_0;
// ...
default:
return 800;
}
}
看起来更干净,并且应该像内联一样,没有任何开销超过宏...
但主要的优点是,您只需跳过参数或结果不良关联以及参数多重评估的任何问题!