3

これが私の簡単なコードです...

#include<stdio.h>
int main()
{
int i=5;
printf("%d %d %d %d %d ",i++,i--,++i,--i,i);
return 0;
}

gccでは、「4 5 5 5 5」として出力されます

しかし、TCでは、「4 5 5 4 5」として出力されます

printfステートメントでは、単一の式の場合、評価は左から右に評価されますが、通常のステートメントでは左から右に評価されることがわかっています。

ただし、printf に複数の式が含まれている場合、評価はスタック上で行われ、要素は左から右にスタックにプッシュされますが、右から左にポップアウトされ、TC 出力が正当化されます。

どこが間違っているのか訂正してください???

4

5 に答える 5

8

C は、関数の引数を評価する順序を指定していないため、未定義であり、コンパイラは、任意およびランダムを含め、選択した方法で実行できます。Bjarne Stroustrup は、「The C++ Programming Language」第 3 版セクション 6.2.2 でこれを明示的に述べています。

また、彼は理由を次のように述べています。

Better code can be generated in the absence of restrictions on expression evaluation order
于 2011-12-30T16:55:41.453 に答える
3

前のシーケンス ポイントと次のシーケンス ポイントの間でオブジェクトを (このコードでi) 2 回以上変更することは、C では未定義の動作です。ここでは、すべての引数が評価された後の関数呼び出しでシーケンス ポイントが発生します。

于 2011-12-30T17:06:42.657 に答える
3

関数呼び出しの引数が評価される順序は指定されていないと思います。ウィキペディアがこの記事でシーケンスポイントについて述べているように:

引数が評価される順序は指定されていません

于 2011-12-30T16:56:38.957 に答える
0

古いトピックをぶつけますが、gcc と Visual Studio コンパイラがステートメント内の同じ変数の複数の変更に対してどのように機能するかを見つけたので、ここで共有することを考えました.

ここで定義されているコンパイラは、'i' である printf に渡される引数にスタック メソッドの実装を開始します。それはこれらの規則に従います:-

1) 最初にプリインクリメントを実行するため、右法線 i から開始し、次に --i と ++i が実行され、++i の後の i の値は 5 であるため、これらの値 (ポップ) を実装するため、出力は _です。 _ 5 5 5

2) 次に、右から左に続き、ポストのインクリメントを実行します。したがって、i-- と i++ の順に実行されるため、最終的に i の値は 5 に戻りますが、i-- により 4 になりますが、ポストであるため 5 が表示されます。したがって、最終出力は4 5 5 5 5 であり、i の最終値は 5 です。

あなたの疑問を解消できることを願っています。

TC はこれに従わず、人間の論理に従います。

于 2014-03-25T09:53:49.700 に答える
0

この時点での 2 つの答えは、関数の引数の評価の不特定性を呼び起こします。正しい答えは、シーケンス ポイントで区切られていない同じ変数への副作用のために、プログラムが未定義であるということです。

実際、関数の引数の評価順序は指定されていません。これは、ステートメント内でが前に呼び出されるf(g(), h());か、後に呼び出されることを意味します。g()h()

ただし、順序付けされていない副作用 (プログラムなど) は、未定義の動作を引き起こし、あらゆることが発生する可能性があります。

于 2011-12-30T17:07:24.847 に答える