我不明白为什么结果会是36.有人可以向我解释这里发生了什么以及预处理器的作用是什么?
#include <iostream>
#define QUADRAT(x) ((x) * (x))
using namespace std;
int main()
{
double no = 4.0;
double result = QUADRAT(++no);
cout << result;
return 0;
}
非常感谢:&gt;
答案 0 :(得分:4)
在该示例中,预处理器将QUADRAT(++no)
替换为((++no) * (++no))
。
如果不是因为两个增量之间没有序列点,那么会增加no
两次,所以实际上是在引起未定义的行为。您看到的任何输出都是有效的,因为没人知道会发生什么。
答案 1 :(得分:2)
预处理器基本上是一个复制粘贴引擎。请注意,宏不是一个函数;相反,它是内联扩展的。考虑扩展宏时代码会发生什么。
答案 2 :(得分:1)
这一行:
double result = QUADRAT(++no);
扩展到这个:
double result = ((++no) * (++no));
最终运行的方式相当于:
no = no + 1;
no = no + 1;
result = no * no;
它以这种方式运行,因为增量是在乘法之前执行的:预处理器会对你传递的内容进行文本复制,因此它会复制“++ no”,使其在最终代码中显示两次,并且在计算结果之前,没有发生每个++的增量。解决这个问题的方法是使用内联函数:
inline double QUADRAT(double x) { return x * x; }
大多数现代编译器都会在不进行文本替换的情况下扩展此代码 - 它们会为您提供与预处理器定义一样快的速度,但不会出现像您所面临的那样的问题。
答案 3 :(得分:0)
会发生什么事情是用+代替x的字面替换,就像你写的那样:
double result = ((++no) * (++no));
结果是什么......它应该是未定义的行为(你偶然得到36),并且带有-Wall的g ++与我同意。