- ベストアンサー
forに出来てwhileに出来ないことって
ないですよね? 逆に whileに出来てforに出来ないことはありますよね? 例えばインクリメントしないループなどがそうです。 このような理解であっておりますでしょうか? 本には、 forは繰り返す回数が決まっている時に使い whileは繰り返す回数が決まってない時に使う と書いてありましたが、 僕はwhileですべて間に合うと思うのです。 とするなら、forは何で存在するのかという疑問にぶちあたります。 じっくり考えてもわかりませんでした。 よろしくお願い致します。
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
int i; int j; int k; i = 0; while (i < 3) { j = 0; while (j < 10) { k = 0; while (k < 5) { printf("%d %d %d\n", i, j, k); k++; } j++; } i++; } for(i = 0; i < 3; i++) { for(j = 0; j < 10; j++) { for(k = 0; k < 5; k++) { printf("%d %d %d\n", i, j, k); } } } whileとforを使用した上記のネスティング処理でどちらの 方が読み易いと感じますか? また、処理ステップが多い場合だと変数の初期化や、増分 処理の抜け等のミスを起こす元にもなりますし、ループの 最後を見ないと増分値の値が判らないという事になり処理 の解読が難しくなります。 >僕はwhileですべて間に合うと思うのです。 >とするなら、forは何で存在するのかという疑問にぶちあたります。 ナイフ1本あれば爪を切る事も間に合うのに何故爪切りが 存在するのでしょうか? というのと同じだと思いますが?
その他の回答 (7)
- isle
- ベストアンサー率51% (77/150)
for (A;B;C) { } のCのところはcontinueで飛ばしても必ず実行されます。 whileだけで同じようにしようとすると複雑になります。 Cのところにはインクリメント以外の式も書けますし、,(カンマ)演算子を使えば複数の式を書くこともできます。 Aのところには代入以外の式も書けますし、,(カンマ)演算子を使えば(以下略)。 Bのところには結果として0か0以外の値を返すのであれば、比較式以外の式も書けますし、,(カンマ)演算子を(以下略)。 つまり繰り返す回数が決まっていないときにも状況によってforを使うほうが適してる場合があります。 個人的な感想ですがwhileよりもforを使うほうが遥かに多いです。
- ultraCS
- ベストアンサー率44% (3956/8947)
まあ、見やすい方を使えば良いんだと思いますがね。 コンパイラなどを研究していた側からすると、元々、変化値とエンド値が決まった形でのforでのループはアセンブラとの親和性が良いというのがあります。特に変化値が1であれば、レジスタにエンド値をセットしてループごとにデクリメントしてゼロフラグを検査して終了というのが使えるのでコストが低いというのはあります。まあ、FORTRANのDOループ(UNTILもWHILEも伴わないもの)がその典型です。 ですから、for(i=0; i<10; i++)なんてループは最適化しやすいというのはあるでしょう、もっとも、ループ内でiが変化するような場合は最適化からはずれる場合があります。また、Whileでも、実際には同じ制御構造で対応できるとコンパイラが判断した場合はそのように最適化される場合もあるでしょう。 ただ、少々のコストはプロセッサの進化が吸収してしまうし、最適化技術も進歩しているので、プログラマのレベルでは気にする必要はないでしょう(コンパイラを作る場合は別)。 むしろ、プログラミング時間やデバッグ時間を削減した方がジョブ全体でのコスト削減になるケースは多いので可読性を優先した方が良いと思いますね。 なお、インクリメントしないループでもbreakを使ったり、条件式をくふうすればforてだも可能ですから、ほぼ互換で使えると言っていいでしょう。 ただ、明らかに関数の戻り値で終了する入力のループなどの場合、forを使うのは野暮ったいし可読性が悪いですね。この辺はプロぐむ暦が長くなれば、自然に身に付くはずですし、プログラムをする環境で規制(会社のプログラムルール等)されるものです。
- nuko_punch
- ベストアンサー率40% (10/25)
ソースの見易さの為、状況に応じて使い分けます。 解読しやすいソースはバグの軽減や発見に大いに役立ちます。 経験を積めば分かることです。 このような質問が出ているうちに、何かを取捨するのは早すぎます。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> 僕はwhileですべて間に合うと思うのです。 > とするなら、forは何で存在するのかという疑問にぶちあたります。 その論でいけば if と goto あれば他はなんも要らんことになりますよ。
- shred
- ベストアンサー率35% (25/70)
>forは何で存在するのかという疑問にぶちあたります 確かにwhileとforでは全然見た目が違います。 ですがアセンブリ言語レベルで展開してみるとほとんど同じです。 というか全く同じである可能性が高いです。 ループには初期条件、終了条件、アップデートの3つがあるのが 普通です。 なのでこれらを簡潔に記せるforを取り入れたのでしょう。 そもそも高級言語は人間にとって使いやすくするためなのですしね。
- asuncion
- ベストアンサー率33% (2127/6289)
A; while (B) { /* 何かの処理 */ C; } は、「何かの処理」の部分に continue; がなければ、 for (A;B;C) { /* 何かの処理 */ } と同じ意味です。 「インクリメントしないループ」というのは、 Cのところに何も書かず、「何かの処理」のところに break; あたりを書くことで、 while でも for でも実現できます。 (注)インデントのため、全角空白を使っています。
- endlessriver
- ベストアンサー率31% (218/696)
同じと思います。ただし、forのほうが構造が予め用意されている。 ようは自明な・わかりやすい構造かと思います。 たとえば、forなら初期値、終値やループ指定は始めにかけます。 ということで私はforが好きです。無限ループもfor(;;)で使います。
お礼
皆様のおかげで、ループに対するかなり深い理解が得られました。 本当にありがとうございました。