日々コーディングしていて思うこと…
「whileっていつ使うの!?」
単純なループならforで処理できる上に、
配列やリストの処理に関してはforeachの方が便利。
同じ反復処理であるが故にwhileを使う場面がイマイチわからない…
実際に現場で目にするコードではforやforeachを使っていることが多いし、
whileを見かけることはほとんどない気がします。
今回はそんなwhileの使い方について考察していこうと思います!
以下に記載するコードはすべてC#です
forを使うべき場面
for、whileともに反復処理を行うという意図は変わらないため、
基本的には同じ処理を両者で置き換えることができます。
例)"No1"~"No5"をコンソールに出力したいとき
for (var i = 1; i <= 5; i++)
{
Console.WriteLine("No" + i);
}
int i = 1;
while (i <= 5)
{
Console.WriteLine("No" + i);
i++;
}
ただ、上記の例をwhileで実装してしまうと
-
i++;
の実装漏れがあると無限ループになり、意図しない処理になってしまう
→ ブロック内の処理が長くなると実装漏れが起きやすい - while内でしか使用せず、以後干渉する必要のない変数
i
が残り続けてしまう
→ whileの処理後、同ブロックで再度i
を宣言することができなくなる
などのデメリットがあります。
特に二つめに関しては、知らず知らずのうちにi
を使い回して予期せぬバグに繋がる可能性があるため要注意です。
つまり、ループ回数を使用するような処理、またはループ回数が明確な処理はforを使うのが適切だと言えます。
whileを使うべき場面
では、whileを使用するのが適切な場面とはどんな状況でしょうか?
一般的には、
ループ回数が明確でないとき と言われています。
次のような場面を考えてみましょう。
- コンソール出力でクイズを作成したい
- ユーザーの入力文字が正解と一致するまで問題文を繰り返し出力する
- 正解と一致した場合は「大正解!」と出力する
以下のように実装できます。
string answer = "";
while (answer != "富士山")
{
Console.Write("日本で一番高い山は? ");
answer = Console.ReadLine();
}
Console.WriteLine("大正解!");
これをforで実装しようとすると
for (string answer = ""; answer != "富士山"; answer = Console.ReadLine())
{
Console.Write("日本で一番高い山は? ");
}
Console.WriteLine("大正解!");
// または
for (string answer = ""; answer != "富士山"; )
{
Console.Write("日本で一番高い山は? ");
answer = Console.ReadLine();
}
Console.WriteLine("大正解!");
となります。
whileを使うメリットとしては、
- ループの継続条件が明確で直感的にわかりやすい
- 変数
answer
の更新がループ本体内で行われることがわかりやすい
でしょうか?
ユーザーが正解を入力するまでの回数は実装段階では特定できないため、forでお馴染みのカウンタ変数での回数制御はできません。
そうなるとたしかに( )
の中はanswer != "富士山"
のみの記述の方がパッと見で継続条件がわかりやすい気はしますね。
処理開始時にループ回数が定まっておらず、ループ回数が処理に関わらないものであればwhileを使うのが良さそう。
ただ、whileを使う場合は無限ループにならないように注意が必要です。
結論
処理開始時にループ回数が
決まっている :for
決まっていない :while
と、一般的に推奨されている使い分けがなんとなく腑に落ちました。
ただ、明確なルールはなく、どちらとも同じ処理を実装できることは変わらないので
「基本はforでいいけど、while使えば可読性や保守性が高くなるケースもあるよ!」
ぐらいの考え方でいいのかもしれませんね😏
参考