C 如何将参数传递给函数并在函数内部的宏函数中使用这些参数
我想做那样的事C 如何将参数传递给函数并在函数内部的宏函数中使用这些参数,c,c-preprocessor,preprocessor,C,C Preprocessor,Preprocessor,我想做那样的事 #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
#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
但当我使用测试函数时,它总是打印“小于零”
注意:这是一个例子,不是真实的例子,但我想做类似的事情(在函数中使用宏)
有人能帮我吗?
编辑
我有这样的配置文件
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);
}
}
我无法重现你发布的代码的问题,但你提到这不是真实的情况,我确实知道这个问题 表达式未按预期进行关联。展开时,表达式为:
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
或:
这总是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)
对于注释来说太大了,因此回答:我建议使用不同的格式(尽管调整了括号):
或者你不同意这更容易阅读
但是,很多三元运算符都很难读取和处理,我宁可考虑用一个内联函数代替整个宏:
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;
}
}
看起来更干净,作为内联的,应该不会有任何开销超过宏
不过,它的主要优点是,您只需跳过参数或结果的不良关联以及参数的多次评估的任何问题 显示一个最小的代码示例,展示引用的问题,读者可以使用它进行复制。如果这不是你的真实情况,那就给出一个不完全愚蠢的真实情况。您引用的宏远比只编写
thing>0
糟糕,并且会激怒代码的读者。还有,为什么是?1:0
?你知道它已经返回了一个布尔值,对吧?显示一个最小的代码示例,它展示了引用的问题,读者可以使用它来复制它。现在,我们只有一个不完整的片段和你的陈述,它导致了一个问题,没有证据表明问题行为是如何产生的。我们可以编写自己的测试来证明或反驳你所说的,但这不是我们的工作。标准保证C中的比较运算符无论如何都返回0或1,因此三元运算符是徒劳的…安全宏应该总是将参数放在括号中,整个宏也应该如此:GTZ(a)((a)>0?1:0)
或者干脆(考虑我之前的评论!):GTZ(a)((a)>0)
@AjayBrahmakshatriya我不知道你在说什么。不需要==1
;
操作符已经返回了一个0
或1
的结果,该结果保证在任何布尔上下文中都能正确运行,我所看到的所有好的编码样式都不鼓励显式比较布尔值。