0

私は他の同様の質問をしましたが、私が直面している状況を理解しようとしています.

だから、これが私の2行のCコードです。

int i=0;
printf("%d %d %d %d %d",i++,i--,++i,--i,i);

GCC と Turbo C Compiler から得た出力を次に示します。

GCC

出力:

-1 0 0 0 0

ターボC

出力:

-1 0 0 -1 0

プレインクリメント演算子を個別に使用してあらゆる種類の実験を試みましたが、両方のコンパイラは同様に機能しますが、上記のprintfステートメントを使用すると出力が異なります。

Turbo C は古くからあるコンパイラであり、現在は廃止され、非標準であることは知っていますが、上記のコードの何が問題なのかまだわかりません。

4

4 に答える 4

8

これは未定義の動作でありi、シーケンスポイントなしで複数回読み取りと変更の両方を行っています。(,関数パラメーターリストのはシーケンスポイントではなく、関数の引数の評価順序も定義されていません。)

コンパイラーは、この状況で必要なものを何でも出力できます。そうしないでください。

このサイトでを検索して、他の同様の問題のホスト全体を見つけて[C] undefined behaviorください。それは非常に啓発的です。

于 2011-05-20T05:15:29.400 に答える
1

Turbo Cはprintf()、変数引数リストの最後の引数から最初の引数までの引数を評価し、その順序で出力します(つまり、最後の値を入力してから、最後の評価がリストの最初の変数引数。フォーマットされた文字列の最初の整数スロットに出力されます)。一方、GCCは最初に、プレフィックス演算子を持つ引数を評価し、それらの結果を連結して、すべてのプレフィックス演算子に適用します(つまり、適用--iされ、最終的には++i等しく0なります。次に、その値を両方に使用します。それらの引数に関連付けられたフォーマット文字列のスロット)。次に、修正後の演算子に移動します(最初i--に、次にi++)、そして最後に、接頭辞または接頭辞演算子なしで変数argsを評価します(つまり、iこの時点での値は単純です0)。他の人が指摘しているように、順序は任意です。

于 2011-05-20T05:17:47.213 に答える
0

関数パラメーターが評価される順序は保証されません。それは未定義の振る舞いです。

この順序はバージョンごとに変わる可能性があり、コンパイルごとに変わる可能性もあります。

于 2011-05-20T05:15:22.613 に答える
0

この場合、 Turbo Cコンパイラの場合の具体的な説明があります。

GCCやその他の現代のコンパイラでは、このようなあいまいさが残るような式に対して未定義の動作があります。

というわけで、 Turbo Cコンパイラの場合の説明です。

printf()は、評価中に右から左への結合性を持ちますが、左から右の通常の方法で印刷します。

最初にiの値は0に初期化され、

右端のiから順に0に置き換えられます。

次に、最後から 2 番目の--iが 0-1 = -1に置き換えられます。

次に、中央のもの++iは -1+1 = 0に置き換えられます。

2 番目のi--は0に置き換えられますが、i の値は -1 になります。

最初のi++は-1に置き換えられますが、i の値は 0 になります。

最後に、次のように左から右に出力します。

-1 0 0 -1 0

したがって、そのような式に対するTurbo Cコンパイラの通常の動作を観察できますが、そのような式に対する他のコンパイラの具体的な規則はありません。

于 2013-09-21T16:19:57.317 に答える