- ベストアンサー
Javaプログラムで予期せぬ動作が発生する理由
- Javaの再帰的なプログラムで予期しない結果が生じています。カウンターの値が予想と異なる出力がされます。
- ソースコードを見ても、なぜこのような動作が起こるのか理解できません。どうして予測と異なる結果になるのか教えてください。
- 質問者は期待している動作は次のようなものですが、実際には異なる結果が得られます。なぜこのような動作になるのでしょうか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
既に回答が付いていますが、2で割り切れる場合もifブロックの中での再起処理が終わった後にその下の処理が続けて行われるからですね。 下記の様にいくつか簡単な修正方法がありますが、修正後のソースから考えた方が分かりやすいかもしれません。 a. 2で割り切れる場合のifブロックの最後でメソッドを抜ける 例) ------------------------------------ if (counter %2 == 0) { System.out.println("2で割り切れちゃった----------->" + counter); counter++; playSaiki(); return; // この行を追加 } ---------------------------------------- b. ifで場合分けするのは、メッセージの表示部分だけにする 例) ------------------------------------ if (counter %2 == 0) { System.out.println("2で割り切れちゃった----------->" + counter); } else { System.out.println("2で割り切れなかった----------->" + counter); } counter++; playSaiki(); ----------------------------------------
その他の回答 (2)
- 中村 拓男(@tknakamuri)
- ベストアンサー率35% (674/1896)
ちょっと考えればわかるけど、 以下は playSaiki()の先頭に来たときのスタックトレースもどきです。 最初ぐんぐん潜っていって、戻り際にも3個出力するので、 0~7が出力されるのは明らかでしょう。 playSaikiは pSと略記してます。 pS() counter==0 pS() 割切->pS() counter==1 pS() 割切->pS() 割切ず->pS() counter==2 pS() 割切->pS() 割切ず->pS() 割切->pS() counter==3 pS() 割切->pS() 割切ず->pS() 割切->pS() 割切ず->pS()counter==4 pS() 割切->pS() 割切ず->pS() 割切->pS() 割切ず->pS() 割切->pS() counter==5 pS() 割切->pS() 割切ず->pS() 割切->pS() 割切ず->pS() 割切ず->pS() counter==6 pS() 割切->pS() 割切ず->pS() 割切ず->pS() couter==7 pS() 割切ず->pS() counter==8
お礼
スタックトレースもどき、ありがとうございます。 おかげで、視覚的にも問題を理解することができました。 今度またこのように再帰的にプログラミングする際は、自分でしっかり流れを追えるように、スタックトレースみたいなものを書いてみます。
- OKWavex
- ベストアンサー率22% (1222/5383)
偶数で「2で割り切れちゃった」を表示してplaySaiki();を呼んだあとで必ず呼び元に戻って1を加えた奇数で「2で割り切れなかった」を表示するのだから、再帰的呼び出しで4まで処理したあとは呼び元に戻りながら偶数である 4 2 0 の際には常に1を加えた 5 6 7 で 「2で割り切れなかった」を表示しているだけでしょう
お礼
回答ありがとうございます。 なるほど、よび元にもどっていくと、確かに4,2,0のときの下の処理を通ってしまいますね。 理解しました、ありがとうございます。
お礼
回答ありがとうございます。 疑問に答えるだけでなく、改善策まで書いてくれるなんて...ほんとに感謝です。 修正するなら、2つ目のコードの方が無駄が少なくなくなりそうなので、それでやってみます。