这两个宏最大的区别是什么?

时间:2018-03-25 02:26:57

标签: c macros

撰写leetcode 我像这样使用宏:

#define max(a,b) ((a) > (b))?(a):(b)

这是错误的,当我像这样更改宏时,它是正确的

#define max(a,b) (((a) > (b))?(a):(b))

无法弄清楚为什么会有这种不同。这是代码,你可以看一下。

#define UNBALANCED 99

#define max(a,b) (((a) > (b))?(a):(b))
int getHeight(struct TreeNode * root)
{
    if(NULL == root)
        return -1;
    int l = getHeight(root->left);
    int r = getHeight(root->right);
    if(UNBALANCED == l || UNBALANCED == r || abs(l-r) > 1)
        return UNBALANCED;

    return 1 + max(l,r);

}
bool isBalanced(struct TreeNode* root) 
{
    if(NULL == root)
        return true;

    return getHeight(root) != UNBALANCED;



}

The need for parentheses in macros in C

不同

3 个答案:

答案 0 :(得分:1)

前者无法将宏替换与邻近操作数隔离开来。例如:

1 + max(a, b)

扩展为:

1 + ((a) > (b))?(a):(b)

并将该组分组为:

(1 + ((a) > (b))) ? (a) : (b)

然后(1 +((a)>(b)))总是非零,所以总是选择(a)

为防止这种情况发生,扩展为表达式的宏应在其整个表达式周围使用括号,以防止其部分与相邻操作数进行分组。

答案 1 :(得分:0)

宏的第二个版本有额外的括号,使得表达式((a) > (b))?(a):(b)作为一个整体进行评估。需要更多代码来解释为什么第一个错误在你的情况下。另请参阅this

答案 2 :(得分:0)

可以说两者都不正确;如果您想使用宏,如果:

MAX(i++, j++)

从您的示例中生成的三元运算符表达式会导致较小的表达式被评估两次。 Yowch!既然你(以及大多数未来的读者)可能使用GCC或clang,这里有一个更好的例子,它们都支持一些编译器扩展(__typeof__和语句表达式)。

#define MAX(a, b) ({ __typeof__ (a) a__ = (a); \
                     __typeof__ (b) b__ = (b); \
                     (a__ > b__) ? a__ : b__; })