• ベストアンサー

gccとvisualstudio

for(i=0;i<10;i++) a[i]=i; k=5; a[k++]=(k>5 || k++<6)? 10: 20; for(i=0;i<10;i++) printf("%d %d\n",i,); printf("%d\n",k); こういうプログラムを作成してgccでコンパイルして実行したとき, 0 0 1 1 2 2 3 3 4 4 5 10 6 6 7 7 8 8 9 9 7 という結果になったのですが、5 10という結果になったのが理解できません。どうしてこのような結果になったのでしょうか?またvisualstudioで実行した場合a[6]=10という結果になったのですがこれもどうしてでしょうか?ぜひ詳しく教えてくださいお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • moritan2
  • ベストアンサー率25% (168/670)
回答No.2

a[k++]=(k>5 || k++<6)? 10: 20; この式が問題ですね。 この式の中にkが3個でてきますが、実行中にkの値が変化しています。 この式をどの場所から計算するかはコンパイラの自由なので3回出てきたkの値が5なのか6なのか7なのかコンパイラの都合で決まります。gccはおそらく左辺のk++を一番最初に実行し、その後右辺の計算時にはkは6になっていたと考えられます。 VisualStudioは右辺の計算を先にやったために右辺のa[k++]=の計算時にはkはすでに6になっていたと思われます。 このような書き方をすると期待通りの結果が得られる保障が無いので、してはいけない書き方とされています。

grapher
質問者

お礼

そういうことだったんですね!よく分かりました。ありがとうございます。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

インクリメント, デクリメントや (複合) 代入演算子で変数の値を変えた場合, その変数の変更前の値は「新しい値を決めるため」にのみ使うことができます. この制約が守られていないプログラムがどのように動作するかは決められておらず, どのように動作しようとも (そして動作しなくても) よいとなっています. このことから, インクリメントやデクリメントについては「その変数は他の場所で現れてはならない」ということになります. 今のプログラムでは a[k++] = ... の文で, 左辺でインクリメントした k が右辺でも現れてしまっています. それがおかしな振舞いをしている本質的な問題です.

grapher
質問者

お礼

ありがとうございます。よく分かりました。

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.1

> a[k++]=(k>5 || k++<6)? 10: 20; 一つの文の中で k を2回インクリメントしていることについての、 処理系による解釈の違いが出ているのだと思います。

grapher
質問者

お礼

解答ありがとうございます。がんばってみます。

関連するQ&A