宏的意外行为

Unexpected behavior of macro

#include<bits/stdc++.h>
#define f(a,b) a*b
using namespace std;
int main()
{cout<<f(2*2,3*2);
 return 0;
}

输出 24 而

#include<bits/stdc++.h>
#define f(a,b) a*b
using namespace std;
int main()
{cout<<f(2+1,3+1);
 return 0;
}

输出 6.

如何解释宏的这种繁忙行为?我使用代码块。 提前致谢。

宏是文本替换,因此您的第二个片段集变为:

cout<<2+1 * 3+1

已解析

cout<< 2 + (1 *3) + 1

在你的情况下使用函数而不是宏:

int f(int a, int b) { return a * b; }

宏是一种简单的文本替换机制。在您的示例中,您有以下宏:

#define f(a,b) a*b

当您使用该宏时,文本 a*b 被替换为宏调用,用您用作参数的任何内容替换 ab

在您的第一个示例中,f(2*2,3*2) 变为 2*2*3*2,它会按照您的预期输出 24。但是,在您的第二个示例中,f(2+1,3+1) 变为 2+1*3+1,被解释为 2+(1*3)+1 并因此输出 6.

您可以通过不同方式定义宏来解决此问题:

#define f(a,b) ((a)*(b))

注意多出的一组括号。这确保宏在表达式中的任何其他内容之前被评估。 ab 周围的额外括号确保首先评估参数。

操作的优先级可以随宏改变。在你的例子中,它不发送 3 和 4,它实际上发送 1+2 和 1+3,它像这样扩展:

1+2*1+3

不过,这种东西并不真正属于宏。如果你有 c++11,你可以使用 constexpr:

constexpr int f(int a, int b) {
    return a*b;
}

如果您希望使用运行时值获得更好的运行时性能,而 c++11 不是一个选项,您可以强制内联函数:

inline int f(int a, int b) {
    return a*b;
}

你的问题是宏是邪恶的原因之一。只要可以,就不要使用它,只有在它是唯一的解决方案时才使用它们。