如何将参数传递给函数并在其中的宏函数中使用这些参数

-2 c preprocessor c-preprocessor

我想做那样的事

#define GREATER_THAN_ZERO(a) a>0? 1:0
Run Code Online (Sandbox Code Playgroud)

并在另一个函数中使用此宏

void test(int x)
{  if (GREATER_THAN_ZERO(x) == 1) printf("more than zero");
   else printf("less than zero");
}
Run Code Online (Sandbox Code Playgroud)

但是当我使用测试功能时,它总是打印"小于零"注意:这是一个不是真实情况的例子,但我想做那样的事情(在函数中使用宏)任何人都可以帮我吗?编辑我有这样的配置文件

 #define LED_u8_MODE_0          LED_u8_REVERSE
 #define LED_u8_MODE_1          LED_u8_NORMAL
Run Code Online (Sandbox Code Playgroud)

在程序中我有一个宏功能

#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
Run Code Online (Sandbox Code Playgroud)

然后我在这个函数里面使用它

    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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Tom*_*zes 6

我无法用您发布的代码重现问题,但您提到它不是真实的情况,我确实知道了这个问题.

表达式未按预期关联.展开时,表达式为:

x>0? 1:0 == 1
Run Code Online (Sandbox Code Playgroud)

分组如下:

x>0? 1:(0 == 1)
Run Code Online (Sandbox Code Playgroud)

这相当于:

x>0? 1:0
Run Code Online (Sandbox Code Playgroud)

这仍然按预期工作.但如果你改为:

if (GREATER_THAN_ZERO(x) == 0)
Run Code Online (Sandbox Code Playgroud)

然后你最终得到:

x>0? 1:0 == 0
Run Code Online (Sandbox Code Playgroud)

要么:

x>0? 1:(0 == 0)
Run Code Online (Sandbox Code Playgroud)

总是1.

宏定义存在两个基本问题:(1)它不保护其参数不被错误关联,(2)它不保护结果不被错误关联.

写它的正确方法是:

#define GREATER_THAN_ZERO(a) ((a) > 0 ? 1 : 0)
Run Code Online (Sandbox Code Playgroud)

括号中的括号(a)允许您将表达式作为参数传递,而不必担心它会重新关联.整个宏体周围的括号允许您在表达式中使用宏而不重新关联它.

在这种特殊情况下,?:运算符是多余的,因为n > 0总是返回0或1,所以你可以使用:

#define GREATER_THAN_ZERO(a) ((a) > 0)
Run Code Online (Sandbox Code Playgroud)

结果相同.

同样,结果的比较1没有任何意义,并表明正在发生一些不寻常的事情.简单地写一下就更自然了:

if (GREATER_THAN_ZERO(x))
Run Code Online (Sandbox Code Playgroud)

这隐含地测试它是否为非零.记住,if (n)相当于if (n != 0).