下面的宏会带来问题吗?
#define sq(x) x*x
如果是,那么如何以及为什么?请帮忙。
是的,它可能会出现问题。除了宏根本不尊重命名空间这一明显事实(这意味着您不能调用其他任何东西sq
)之外,请尝试以下操作:
int result = sq(4) / sq(4);
你应该x * x
用括号括起来,这样它就变成了((x) * (x))
。
另一个问题:
int a = 0;
int result = sq(++a);
这是宏的固有问题,也是应该首选内联函数的原因之一。
我不会给你一个直接的答案(这看起来像是一个家庭作业问题),但我会给你一个例子,希望能让你思考并得出一个正确的答案:
#include <iostream>
#define sq_macro(x) x * x
int sq_function(int x)
{
return x * x;
}
int print_and_ret(int x)
{
std::cout << x << '\n';
return x;
}
int main()
{
std::cout << "Calling sq_macro:\n";
sq_macro(print_and_ret(10));
std::cout << "Calling sq_function:\n";
sq_function(print_and_ret(10));
}
当您运行程序时,宏和函数会给出两种不同的行为。想想什么是宏,什么是函数。
编写宏时过度使用括号。重写宏如下
#define sq(x) ((x)*(x))
如果您不这样做,那么在将宏用作sq(5+4)
要了解问题,请做宏扩展并查看。
正如所指出的,您应该将参数的每次使用都括在括号中以确保正确的行为,例如,当参数类似于i * 2
:
#define sq(x) ((x)*(x))
但还有另一个潜在问题。考虑以下:
result = sq(++i);
这被翻译成:
result = ((++i)*(++i))
当意图可能i
只增加一次时,它会增加两次。这是宏的常见副作用。
一种方法是在调用它时注意这一点,但更好的方法是放入sq()
它自己的内联函数。
所有这些都可能导致麻烦:
int x = 12;
int n = sq(x+3);
int y = sq(x++);
int z = 2 * sq(2 + n) * n;
与一个函数相比sq
。
一方面,运算符优先级会被打乱:
sq(2+2); // author wants 4*4, but gets 2+2*2+2.