为什么宏的结果与C中的函数不同

时间:2020-06-22 02:37:47

标签: c recursion macros

在下面的代码中,它用于获取二叉树的高度。以[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
    }
}

1 个答案:

答案 0 :(得分:3)

您不正确的表达式: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))

但是要小心!由于对宏参数进行了两次评估,因此即使在所有情况下也无法使用!

宏观是个坏消息。


附言罗伯托(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++在宏中的计算结果是 两次 ,因此宏返回8,而A最终成为{ {1}},甚至在代码中还有未定义的行为。