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

how to pass arguments to function and use these arguments in macro function inside it

我想做那样的事情

#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");
}

但是当我使用测试函数时它总是打印 "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

或:

x>0? 1:(0 == 0)

始终为 1。

宏定义有两个基本问题:(1) 它没有保护其参数免受错误关联,(2) 它没有保护结果免受错误关联。

正确的写法是:

#define GREATER_THAN_ZERO(a) ((a) > 0 ? 1 : 0)

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

在这种特殊情况下,?: 运算符是多余的,因为 n > 0 总是 returns 0 或 1,因此您可以只使用:

#define GREATER_THAN_ZERO(a) ((a) > 0)

结果相同。

同样,将结果与 1 进行比较没有任何意义,并表明发生了异常情况。简单写一下就自然多了:

if (GREATER_THAN_ZERO(x))

这隐含地测试它是否非零。请记住,if (n) 等同于 if (n != 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;
    }
}

看起来更简洁,作为内联,应该不会对宏有任何开销...

不过,主要优点是您可以简单地跳过参数或结果的错误关联以及参数的多重评估的任何麻烦!