0
#include<stdio.h>
#include<stdlib.h>
int main() {
int a=3;
//case 1
printf("%d %d %d\n",(--a),(a--),(--a));//output is 0 2 0 
printf("%d\n",a);//here the final value of 'a'
//end of case 1
a=3;
//case 2 
printf("%d\n",(++a)+(a--)-(--a));//output is 5 value of a is 2
printf("%d\n",a);//here the final value of 'a'
//end of case 2
a=3;
//case 3 
printf("%d\n",(++a)*(a--)*(--a));//output is 48  value of a is 2
printf("%d\n",a);//here the final value of 'a'
//end of case 3
//case 4 
int i=3,j;
i= ++i * i++ * ++i;
printf("%d\n",i);//output is 81
i=3;
j= ++i * i++ * ++i;
printf("%d\n",j);//output is 80
//end of case 4
return 0;
}

3時間近く費やしてこれらのアウトプットがどのように出てくるかははっきりしていますが、詳しく知りたいのは、なぜこのような方法で取得または評価されているのかということだけです.

  1. これは、printf が右から左に評価されると判断するのが難しいため、最初に --a が 2 をプッシュし、次に a-- 2 をポストとして再びプッシュし、次に a が 1 になり、次に --a が最初に 0 を作成し、それを次にプッシュします。出力は 0 2 2 になると思いましたが、驚いたことに 0 2 0 だったので、pre increment と decrement を使用したすべての場所に a=0 の最終値が与えられていることがわかりました。なぜこれが起こるのですか?

  2. これを通常の評価と見なし、次に a を 4 として印刷し、次に a-- で再び a を 4 として使用し、再び --aa を 3 として使用して、4+4-3=5 を実行すると、a の最終値が発生します。途中で行われたポストデクリメントから -1 になるため、 a は再び 2 になります なぜこれが起こっているのですか?

  3. この実行は上記と同じで、4 * 4 * 3 = 48 を取り、最終的な値は 2 です。

  4. これはトリッキーではありませんが、詳細に答えたいと思います。最初に i は ++i で 4 になり、i++ で i は 4 になり、次に ++ii で 5 になり、4*4*5 = 80 になります。この場合、私はそれを i 自体に保存するので、i は 80 になり、ポストの増分として 1 +1 になります。したがって、80 を別の変数 j に格納し、それが 80 であり、最終的な i の値が 6 であることがわかった場合、1 つの明確な決定を下すことができます。

したがって、論理的には、これらすべてのケースで物事を印刷して表示するだけで判断しましたが、今後もこれに完全に基づいているものはさらに多くあります。個別の状態または何かとしてインクリメントします。このようなさまざまなプログラムを、印刷を続けることができず、パターンを見つけることができず、誰かがここで詳細に助けてくれます。そして最悪の部分は、私が ideone でコードを実行したところ、完全に異なる出力が得られたことです。興味があれば ideone でテストすることもできます。なぜこれらが起こるのか、誰かが私に教えてください。私はこのことに 3 時間頭を悩ませています専門家.そして、私はgccコンパイラを使用しました.

4

1 に答える 1

4

sequence pointsこれはすべて未定義の動作であり、この場合、同じ式内で変数を複数変更することは許可されていません。したがって、このプログラムの出力にまったく依存することはできません。

c99 ドラフト標準 から6.5.2

前のシーケンス ポイントと次のシーケンス ポイントの間で、オブジェクトの格納値は、式の評価によって最大 1 回変更されます。さらに、以前の値は、保存する値を決定するためにのみ読み取られます。

次のコード例は未定義として引用されています。

i = ++i + 1;
a[i++] = i; 
于 2013-08-09T19:13:42.880 に答える