質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

7回答

5139閲覧

While と forの違いについて

lotpop

総合スコア12

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

1グッド

2クリップ

投稿2016/08/30 03:57

###While と forの違いについて

PHPを学んでいるのですが、
While と forの違い(使い分け)がいまいち良くわかりません。どのように使い分けると良いのかご教示頂けますと有り難いです。
どうぞ、よろしくお願いいたします。

退会済みユーザー👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答7

0

繰り返す回数が決まっているならfor
条件を満たすまで繰り返すならwhile
という風にしています。

投稿2016/08/30 04:10

Kakky7s

総合スコア122

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

どちらでも書きようによっては同じように書けます。
例1

PHP

1for($i = 0; $i < 10; $i++){ 2 // 処理 3} 4 5$i = 0; 6while($i < 10){ 7 // 処理 8 $i++; 9} 10

例2

PHP

1while($flag){ 2 // 処理 3} 4 5for(; $flag; ){ 6 // 処理 7}

ただし一般的な使い分けとしては次のようになります。

for文
・ある値について範囲内で処理を行いたい場合
・ある処理を特定の回数繰り返したい場合

while文
・ある処理を特定の条件の間だけ繰り返したい場合

投稿2016/08/30 05:07

ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

while文でできることはfor文でできると教わりました。

for文は、

PHP

1for(初期化処理; ループを継続する条件; 次のループの前処理) {}

で、while文は、

PHP

1while(ループを継続する条件) {}

ですよね。while文をfor文に書き直すと、

PHP

1for(; ループを継続する条件; ){}

になります。for文をwhile文に書き直すと、

PHP

1初期化処理; 2while(ループを継続する条件) { 3 : 4 (ループ中の処理;) 5 : 6 次のループの前処理 7}

になります。お互いに書き直したソースコードを参照いしていただくと、最初の2つのコードに比べてどのようなループなのかが把握しづらいと思われませんでしたか?

従いまして、使い分ける理由と致しましては、

  • 「for」「while」のキーワードでどのようなループなのかわかる。
  • 「ループを継続する条件」のみのループであればwhile文の方が簡潔に書ける。
  • 「初期化処理」「ループを継続する条件」「次のループの前処理」があるループではfor文の方が簡潔に書ける。

になるかと思います。

余談ではありますが、プロジェクトによっては、今後のプログラム改修の柔軟性を見据えて、「ループ文は全てfor文で書くこと」と定めているところもあります(体験談)。

投稿2016/08/30 04:11

編集2016/08/30 04:13
snowfaller

総合スコア125

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

実際現れるループのパターンはそれほど無いと私は思っています。もし、複雑なループになる場合は、アルゴリズム自体が間違っており、単純なループに分解すべきと考えるからです。それを踏まえて、どのようなループに対してどのような構文を使うべきか考えていきます。

###配列の要素を一つ一つ見る場合

foreachを使いましょう。配列の要素を一つ一つ出力する場合は次のようになります。

PHP

1<?php 2$a = [3, 1, 4, 1, 5, 9, 2, 6]; 3foreach ($a as $v) { 4 echo "$v\n"; 5}

何番目という情報が欲しい場合もforeachで十分です。

PHP

1<?php 2$a = [3, 1, 4, 1, 5, 9, 2, 6]; 3foreach ($a as $k => $v) { 4 echo "$k: $v\n"; 5}

配列の要素を一つ一つ見るだけであれば、for文もwhile文も必要ありません。このforeach文は他の言語でも取り入れられており(言語によっては範囲for文とも言います)、扱う配列がはっきりしておりfor文よりも意味が明確であること、カウンタを途中で増やしてしまうなどの副作用があり得ないことなど、優位点が多いです。積極的に使っていくことをお勧めします。

###数を単純にカウントする場合

range()foreachを組み合わせます。1から10までを全て足す例を見てみましょう。

PHP

1<?php 2$sum = 0; 3foreach (range(1, 10) as $i) { 4 $sum += $i; 5} 6echo "$sum\n";

2ずつ増やしたいという場合でもrange(1, 10, 2)のようにできますので、柔軟に対応できます。逆もrange(10, 1)のようにできますので、問題ありません。

勘のいい人は上をこのように書き変える事ができる事に気付くでしょう。

PHP

1<?php 2$sum = array_reduce(range(1, 10), function($c, $i) { return $c + $i; }, 0); 3echo "$sum\n";

最初の配列にも言えることですが、array_reduce()の他にもarray_filetr()array_map()などを駆使すれば従来ループでしたかったことがだいたいできてしまいます。この方法は関数型プログラミングで配列処理するときの考え方の一つで、C#やRubyなど多くの言語で取り入れられています。お世辞にも他言語に比べるとPHPは使いやすいとは言い難いですが、場合によっては利用価値があると私は思っています。

###条件を確認する度に状態が変わる場合

whileを使うのがいいでしょう。例えば、標準入力から一行ずつ読みとって、逆にする場合を考えます(ASCII文字しか考慮しません)。

PHP

1<?php 2while ($line = fgets(STDIN)) { 3 echo strrev(trim($line)); 4 echo "\n"; 5}

この処理には初期化処理がありません。また、条件文の実行自体がカウンタを回す役目になっているため、更新処理も必要ありません。その意味ではfor文を使うのはいささか冗長です。

###無限ループの場合

これは好みの問題ですので、for (;;) {...}でもwhile (true) {...}でもどちらでも良いでしょう。私はどちらかというとwhile文が好みですが、C/C++な人はwhile(1)だと警告が出る場合があるということでfor文派が多いらしいです。

###漸化式で次々求める場合

漸化式は前の項を元にして今の項を求めるような式です。フィボナッチ数列が有名ですね。こういう場合は、再帰関数を使うととてもすっきりした形に書けます。コラッツの問題において、1になるまでの処理の回数を求める関数を作ってみましょう。

PHP

1<?php 2function collatz($n) { 3 if ($n % 2 == 0) { 4 return $n / 2; 5 } else { 6 return $n * 3 + 1; 7 } 8} 9function count_collatz($n, $c = 0) { 10 if ($n == 1) { 11 return $c; 12 } 13 return count_collatz(collatz($n), ++$c); 14} 15echo count_collatz(27);

このcount_collatz()が再帰関数なのですが、機械的にfor文やwhile文に置き換えることができます。このような置き換えを末尾呼出し最適化といい、プログラミング言語によっては自動的にしてくれる場合があります。しかし、残念ながらPHPはしてくれません。再帰関数は深くなりすぎるとスタックを食い尽くし、プログラムが停止してしまいます。余り深くならない場合のみ用いるべきでしょう。

しかし、数学的な漸化式がはっきりしている場合は、再帰関数を使ったループの方がわかりやすい場合があります。適材適所で使い分けると良いかもしれません。

###条件が揃うまでループする場合

先ほどのコランツの問題ですが、実際に普通のループに書き換えたいと思います。

PHP

1<?php 2function collatz($n) { 3 if ($n % 2 == 0) { 4 return $n / 2; 5 } else { 6 return $n * 3 + 1; 7 } 8} 9function count_collatz($n) { 10 $c = 0; 11 while ($n != 1) { 12 $n = collatz($n); 13 ++$c; 14 } 15 return $c; 16} 17echo count_collatz(27);

このループにおいて重要なのは条件が何であるかということです。for ($c = 0; $n != 1; ++$c) {...}とfor文の方が良いという方がいるかも知れませんが、条件が独立しているのであれば、私はwhile文を使う方がいいと思っています。$c$nは独立しており、それをfor文の中に一緒に書かれてもわかりにくく、複雑になると思うからです。

独立しているのが分かりにくいなら、for (; $n != 1; $n = collatz($n))と提案するかも知れません。しかし、更新部分が大きく、条件部分がわかりにくくなってしまっています。for文はそれほど見やすい構文では無いため、条件以外の部分を複雑にすると重要な条件部分が一目でわかりずらく、可読性が落ちると思われます。初期処理は代入一つ程度、更新部分はインクリメントかデクリメント一つ程度にとどめるべきです。

###その他

これまで上げたループ以外のパターンは思いつきませんでした。少なくとも私はそのような物を書いたことがないのだと思います。複雑な条件、複雑な初期処理や継続処理など、いろいろなパターンがあると思いますが、それらをコードにするよりも、アルゴリズムを分解し、より単純なループになるように設計し直した方が良いと思っています。

ここまでで気付いたかと思いますが、私にとってfor文はいらない子です。長くなりましたが、言いたかったことはこの一言だけだったりします…

投稿2016/08/30 13:22

raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

実行回数が決まっていれば
for文

条件を満たすまで実行を継続
する場合は
while文
を使うのが定石だと思います。

for文でも無限ループなどを
作ることが可能ですが、
本来の使い方ではないと思います。

投稿2016/08/30 09:25

Yatsurugi

総合スコア1628

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

まず、while文とfor文は互換性があるので、
どっちか一方だけでもループを実現可能です。

しかし論理的に等価でも、可読性のために使い分けたいです。

その場合ふつうは、数が決まってるならfor、
それ以外の一般的な条件による反復はwhileで、と使い分けます。

たとえば、九九を表示するループなら、
回す数が決まっているのでforだとか。
キーを押すまで無限ループする場合はwhileだとか。


あえてfor文を使うメリットは、数が決まってる場合、
何回回すのか一行で把握できることです。

しょせんシンタックスシュガーとはいえ、
多重ループになると視認性に差が出ます。

同じ千回のループでも、whileの方は無意味に複雑で、
いかにも凡ミスを誘発しそうですよね?

PHP

1for($i = 0; $i < 10; $i++){ 2 for($j = 0; $j < 10; $j++){ 3 for($k = 0; $k < 10; $k++){ 4 //process 5 } 6 } 7}

PHP

1$i = 0; 2while($i < 10){ 3 $j = 0; 4 while($j < 10){ 5 $k = 0; 6 while($k < 10){ 7 //process 8 $k++; 9 } 10 $j++; 11 } 12 $i++; 13} 14

投稿2016/08/30 11:14

LLman

総合スコア5592

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

終了条件が状態変化である場合がwhile
例)フラグがtrueになったら、読み込みが完了したら、等
上限回数が決まっている場合はfor
私はこんな感じですね。

投稿2016/08/30 04:23

kunai

総合スコア5405

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問