宏的意外行为

时间:2015-07-04 17:54:00

标签: c++ macros

#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。

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

3 个答案:

答案 0 :(得分:3)

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

#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解释为#define f(a,b) ((a)*(b)) ,因此输出6。

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

a

注意一组额外的括号。这可确保在表达式中的任何其他内容之前评估宏。 bpublic void matchBasePairSequence(String line){ // Construct regex Pattern digitsPattern = Pattern.compile(".CG.AA"); Matcher m = digitsPattern.matcher(line); while (m.find()){ System.out.println(m.group()); } } 周围的额外括号可确保首先评估参数。

答案 1 :(得分:0)

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

cout<<2+1 * 3+1

解析

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

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

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

答案 2 :(得分:0)

操作的优先级可以随宏而改变。在你的例子中,它不发送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;
}

你的问题是宏是邪恶的原因之一。只要你能做到,就不要使用它,只有当它成为唯一的解决方案时才使用它们。