我在网站上看到了以下代码。
我无法用11
代替25
或13
来判断结果的结果。
为什么我在考虑25
,因为SQ(5) 5*5
或13
因为
SQ(2) = 4;
SQ(3) = 9;
可能是最终结果13 (9 + 4)
但惊讶地看到结果为11
。
结果如何11
?
using namespace std;
#define SQ(a) (a*a)
int main()
{
int ans = SQ(2 + 3);
cout << ans << endl;
system("pause");
}
答案 0 :(得分:19)
预处理器在源代码上执行简单的文本替换。它对底层语言或其规则一无所知。
在您的示例中,SQ(2 + 3)
展开为(2 + 3*2 + 3)
,评估为11
。
定义SQ
的更有效方法是:
#define SQ(a) ((a)*(a))
现在,SQ(2 + 3)
会扩展为((2 + 3)*(2 + 3))
,并提供25
。
即使这个定义是一种改进,它仍然不是防弹的。如果将SQ()
应用于side effects的表达式,则可能会产生不良后果。例如:
f()
是一个向控制台打印内容并返回int
的函数,则SQ(f())
会导致输出打印两次。i
是int
变量,SQ(i++)
会产生undefined behaviour。有关宏的困难的更多示例,请参阅Macro Pitfalls。
由于这些原因,通常最好使用函数而不是宏。
答案 1 :(得分:6)
#define
扩展就开始了。这就是为什么它们被称为预处理器指令,这里的处理器是将C转换为机器可读代码的编译器。
所以,这就是宏预处理器传递给编译器的原因:
SQ(2 + 3)
扩展为(2 + 3*2 + 3)
所以,这确实是2 + 6 + 3
= 11
。
你怎么能做到你期望的呢?
答案 2 :(得分:3)
C预处理器在编译器解释表达式和C语法之前进行文本替换。因此,在此代码上运行C预处理器会转换:
SQ(2 + 3)
成:
2 + 3*2 + 3
简化为:
2 + 6 + 3
这是11。
答案 3 :(得分:1)
这只是编译前的替代
所以你应该尝试一下:
#define SQ(a) ((a)*(a))
在您的情况下,SQ(2 + 3)
相当于(2+3*2+3)
11
。
但正如我在上面所写的那样纠正它,就像((2+3)*(2+3))
那样5*5 = 25
就是你想要的答案。
答案 4 :(得分:1)
#define preprocesor
语法: #define identifier replacement
#define也可以使用参数来定义函数宏:
<强> # define SQ(a) (a*a)
强>
将在编译时用* a替换任何SQ(a)的出现。 因此,
SQ(2 + 3)将替换为2 + 3 * 2 + 3 在完成替换之后执行计算。 因此回答2 + 3 * 2 + 3 = 11
答案 5 :(得分:1)
对于您的实施,该值将扩展为2+3 * 2+3
,这将导致2 + 6 + 3 = 11。
您应该将其定义为:
#define SQ(x) ({typeof(x) y=x; y*y;})
在gcc
上测试,输入
注意:typeof
是标准C的GNU添加。可能在某些编译器中不可用。