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))ます。

no2 つのインクリメントの間にシーケンス ポイントがないという事実がなければ、2 回インクリメントされるため、実際には未定義の動作が発生します。何が起こるかは誰にもわからないため、表示される出力はすべて有効です。

于 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」をコピーして、最終コードに2回表示され、それぞれのインクリメント++no は、結果が計算される前に発生します。これを修正する方法は、インライン関数を使用することです。

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

最新のコンパイラのほとんどは、テキストの置換を行わずにこのコードを展開します。プリプロセッサの定義と同じくらい高速ですが、直面しているような問題が発生する危険はありません。

于 2012-03-25T00:09:31.033 に答える
0

What happens is a sort of literal substitution of ++no in place of x, it is like you have written:

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

What is the result... it should be undefined behaviour (you get 36 by chance), and g++ with -Wall agrees with me.

于 2012-03-25T00:01:59.560 に答える