ようこそ ゲスト さん、新規登録(無料)して気になる疑問を解決しませんか?

質問

質問者:grapher 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という結果になったのですがこれもどうしてでしょうか?ぜひ詳しく教えてくださいお願いします。
質問投稿日時:08/05/02 22:19
質問番号:3993265
この質問に対する回答は締め切られました。
最新から表示回答順に表示良回答のみ表示

回答

良回答10pt

回答者:Tacosan インクリメント, デクリメントや (複合) 代入演算子で変数の値を変えた場合, その変数の変更前の値は「新しい値を決めるため」にのみ使うことができます. この制約が守られていないプログラムがどのように動作するかは決められておらず, どのように動作しようとも (そして動作しなくても) よいとなっています.
このことから, インクリメントやデクリメントについては「その変数は他の場所で現れてはならない」ということになります.
今のプログラムでは a[k++] = ... の文で, 左辺でインクリメントした k が右辺でも現れてしまっています. それがおかしな振舞いをしている本質的な問題です.
種類:アドバイス
どんな人:一般人
自信:参考意見
回答日時:08/05/03 00:53
回答番号:No.3
この回答へのお礼ありがとうございます。よく分かりました。

回答

良回答20pt

回答者:moritan2 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になっていたと思われます。
このような書き方をすると期待通りの結果が得られる保障が無いので、してはいけない書き方とされています。
種類:回答
どんな人:経験者
自信:自信あり
回答日時:08/05/03 00:23
回答番号:No.2
この回答へのお礼そういうことだったんですね!よく分かりました。ありがとうございます。

回答

 

回答者:asuncion > a[k++]=(k>5 || k++<6)? 10: 20;

一つの文の中で k を2回インクリメントしていることについての、
処理系による解釈の違いが出ているのだと思います。
種類:アドバイス
どんな人:一般人
自信:参考意見
回答日時:08/05/02 22:38
回答番号:No.1
この回答へのお礼解答ありがとうございます。がんばってみます。
 
最新から表示回答順に表示良回答のみ表示