首页 > 解决方案 > 为什么宏的结果与 C 中的函数不同

问题描述

在下面的代码中,它用于获取二叉树的高度。以[1,2]作为输入,如果使用宏定义MAX,结果1是不正确的。使用函数 max 时,结果 2 是正确的。造成差异的原因是什么?

  1
 /
2

#define MAX(a,b) a>b?a:b
int max (int a, int b) {
    return a>b?a:b;
}
int maxDepth(struct TreeNode* root){
    if (root == NULL) return 0;
    else {
        int left = maxDepth(root->left);
        int right = maxDepth(root->right);
        return max(left, right) + 1;
        //return MAX(left, right) + 1; // incorrect
    }
}

标签: crecursionmacros

解决方案


您不正确的表达式:return MAX(left, right) + 1;将扩展为:

 return left>right?left:right + 1;

添加一些括号来澄清错误:

 return (left>right) ? (left) : (right + 1);

我认为您可以通过以下方式解决它:

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

但要小心!由于宏参数的双重评估,即使这也不适用于所有情况!

宏是个坏消息。


PS Roberto 询问了一个宏仍然不起作用的示例:

基本上,任何时候声明都会产生副作用。

#include <stdio.h>
#define MAX(a,b) ((a>b)?(a):(b))
int main(void)
{
    int A = 3;
    int B = 4;
    printf("Bigger value is %d", MAX(2*A++, B) );
    
    printf("A : %d\nB : %d\n", A, B);
    return 0;
}

幼稚的阅读会表明这2*A++将是6,并留下A价值4(后增量)。但是,因为表达式在宏中2*A++被计算了两次,所以宏返回8A最终变成5,代码中甚至还有未定义的行为。


推荐阅读