TODOSでの話だが, JAVA のプログラミングについて,初歩の初歩の質問があって,回答のプログラムを書いた。こんなの ( Enzan.java )。
何しろ,生まれて初めて,ネットを拾い読みしつつ組んだプログラムなので,引き算の答えが負になる場合の処理とか,エラー処理とかなにもやっていないが,まあ,初歩の初歩の回答としては,そのほうがゴチャゴチャしないでわかりやすいかもしれない。プログラムのチェックは, jdk-7u40-nb-7_3_1-windows-i586.exe でやった。
で,昨日,次のものとして, for 文の使い方についての質問があった。 TODOS に回答を書けばいいようなものの,スレッドの流れからどうも書きにくくなってて,JAVA の勉強にはなるから,ここに書いてしまおうかと。
ところで,質問文中に「実行結果があやふやなことになりました」とあるが,締めくくりの } が2つないのもさることながら,これでは,実行以前にコンパイルが通らないと思うのだが,実行というのをコンパイルの意味で使っているのだろうか。しかし,コンパイルでははっきりエラーメッセージが出るはずだから,「あやふや」という表現は当たらないよなあ。
質問文中のプログラムには,まず,何よりもまず最後に } が2つ必要である。さらに,変数の型宣言が for ループの中に入ってしまっているから,これを外に出さないといけない。こんな具合 ( Sample1.java )。これで,コンパイルは通る。これは,私の間違い。もう一度確認してみた。型宣言が中にあっても,一般には通る。しかし, for ループの中が空のときは通らないようだ。
さらに,追記(汗)―― Sample2_1 は通るが, Sample2_2 は通らない。考えるに, JAVA のコンパイラはお利口さんで, for ループが空だと実質何も行わずに無視するのだろう。したがって,インデックスの宣言と値代入が同位置だと, for ループが空の場合,そこが無視されているから,型宣言が行われていないことになって,あとの print 文の変数が未宣言になってエラーが出ると見た。多分,これで正解。したがって,通常は,インデックスの型宣言は for 文の中で構わないことになる。――追記,ここまで。
しかし, (int i=1; 1/i<=500; i++) ってどういう意味だろう。多分,条件と for ループの中でやるべき処理とがごっちゃになったんだろう。しかし, 1/i で i が int だと計算結果も int で 1/2 からはずっと 0 になるわけだから,ナンジャラホイということになってしまう。プログラムを実行可能にするためには,せめて, (int i=1; i<=500; i++) じゃないといけない ( Sample2.java )。
さて,空っぽの for ループの中になにか処理することを入れないといけない。 i をインクリメントさせて, 1/i を加えていくわけだから,計算結果を記憶させる変数が必要だ。彼の考えに沿って行くと, int j=0; を宣言しておいて使うということになるだろう ( Sample3.java )。しかし,これの実行結果は, 1 になる。ここまで来て,「実行結果があやふやなことになりました」というんなら納得できるんだけどな。なんでこんな結果になるかというと,型が int だからだ。 i が整数型だから, JAVA だと, Sample3.java の 1/i の場合, 1/1 以外はすべて 0 になるはずだ。
追記(9/26): (float)i と明示的に書いてやると, 1/(float)i の結果が float になることを知った。
この手の計算なら,小数を扱う必要があるから, float か double を使うべきだろう。桁落ちの発生する float や double での 1 + 1/2 + 1/3 + … + 1/500 の計算結果は,誤差が大きくなって大変にまずいわけだが,初級レベルのプログラミングの for 文の使い方でそんなところまで要求するとは思えないから, float でも使っておけばいい。実行結果は, 6.7928243 になる ( Sample4.java )。
しかし,今回の質問の文章にも,彼は全く悪びれたところがない。この間,りりさんが,「このまま去れられると、別のご相談をしたくなったとき、もう、ここでは応えて貰えないと思いますよ。」と書かれていたのに,この書き方ということは,彼の中では,もう一度来たから「このまま去った」わけではないということなんだろうな。よー分からんが,そういうことなんだろう。
初心者の場合,相談後,教えてもらったことを使って実際の手順がうまくいっても,掲示板の今後の利用者のために結果を詳細に報告と言われても,どう書けばいいかわからないということはある。だから,「解決しました」しか書かない,いや書けない投稿者も存在する。だからそれはそれでいいのだが,前回の文章に「ありがとうございました」の一文を入れるか,今回の文章に「この間は,失礼しました。遅くなりましたが,改めてお礼申します。ありがとうございました」とか書いてから,今回の質問を書けば何も問題ないんだが。そこがないので,私は流れ上スレッドの続きを書きづらい。
私としては,もう一度彼に注意を促しながら,回答をしてもいいのだが。 JAVA の勉強にいい機会だと思って付き合いだしたのだが,なんともすっきりしないことになってきたワイ。
追記(9/27):
りりさんの提案で,彼の投稿をネタに TODOS でトライをやった。「何十も見つかった」という話だったのだが,重複が多かったらしく,9度で打ち止め。9個並べてリンクを貼っておきます。
- JAVAトライ・その1
- JAVAトライ・その2
- JAVAトライ・その3
- JAVAトライ・その4
- JAVAトライ・その5
- JAVAトライ・その6
- JAVAトライ・その7
- JAVAトライ・その8
- JAVAトライ・その9
- JAVAトライ・その10 (9/28追加)
- JAVAトライ・その11 (10/7追加)
- JAVAトライ・その12 (10/7追加)
- JAVAトライ・その13 (10/7追加)
- JAVAトライ・その14 (10/7追加)
- JAVAトライ・その15 (10/9追加)
- JAVAトライ・その16 (10/10追加)
- JAVAトライ・その17 (10/10追加)
- JAVAトライ・その18 (10/11追加)
- JAVAトライ・その19 (10/11追加)
- JAVAトライ・その20 (10/18追加)
- JAVAトライ・その21 (10/22追加)
- JAVAトライ・その22 (10/22追加)
「その23」以降は,「JAVAの話-#2。」にリンクしてある。