0

我不明白为什么结果会是 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;
}

非常感谢 :>

4

4 回答 4

4

在该示例中,预处理器将替换QUADRAT(++no)为。((++no) * (++no))

no如果不是因为两个增量之间没有序列点,那将增加两次,因此您实际上会导致未定义的行为。你看到的任何输出都是有效的,因为没有人知道会发生什么。

于 2012-03-24T23:57:11.650 回答
2

预处理器基本上是一个复制粘贴引擎。请注意,宏不是函数;相反,它是内联扩展的。考虑当宏展开时您的代码会发生什么。

于 2012-03-24T23:56:28.663 回答
1

这一行:

double result = QUADRAT(++no);

扩展为:

double result = ((++no) * (++no));

最终运行的方式相当于:

no = no + 1;
no = no + 1;
result = no * no;

它以这种方式运行,因为增量是在乘法之前执行的:预处理器对您传递的内容进行文本复制,因此它复制“++no”,以便它在最终代码中出现两次,并且每个增量++no 在计算结果之前发生。解决这个问题的方法是使用内联函数:

inline double QUADRAT(double x) { return x * x; }

大多数现代编译器会在不进行文本替换的情况下扩展此代码 - 它们会为您提供与预处理器定义一样快的东西,但不会有遇到您面临的问题的危险。

于 2012-03-25T00:09:31.033 回答
0

发生的是一种用 ++no 代替 x 的文字替换,就像你写的那样:

double result = ((++no) * (++no));

结果是什么......它应该是未定义的行为(你偶然得到 36),并且带有 -Wall 的 g++ 同意我的观点。

于 2012-03-25T00:01:59.560 回答