このページでは、C言語における「while
と do while
の違い」について解説していきます。
while
も do while
も両方ともループを実現するためのものになりますが、動作に違いがあります。その違いに焦点を当てて解説を行なっていきます。
while
:最初に継続するかどうかを判断する
while
と do while
の決定的な違いは、ループを継続するかどうかを判断するタイミングです。
while
の場合、ループを継続するかどうかの判断が「繰り返す処理
を実行する前」に毎回行われます。
while
は下記のように 継続条件
と 繰り返す処理
を記述することでループを実現し、継続条件
が成立している間、繰り返す処理
の実行が繰り返されることになります。逆に 継続条件
が不成立になった際には、ループを抜け出し、繰り返す処理
の実行が終了することになります。
while (継続条件) {
繰り返す処理
}
例えば下記では、i
が 10
未満である間、printf("%d\n", i)
と i++
の処理が繰り返されることになります(なので、実行すれば 0
〜 9
が出力される)。
int i = 0;
while (i < 10) {
printf("%d\n", i);
i++;
}
前述の通り、while
では「繰り返す処理
を実行する前」にループを継続するかどうかの判断が行われます。もう少し分かりやすくいうと、while
ではループに入る前にも 継続条件
が成立しているかどうかが判断されます。
そして、継続条件
が成立している場合はループに入り、継続条件
が成立していない場合はループに入らないよう制御されます。それ以降は、次の 繰り返す処理
を行う前のタイミングで再び 継続条件
が成立しているかどうかが判断され、その結果に応じてループを続ける or ループを終了するかの制御が行われます。
ですので、先程の例において、i
の初期値を 10
にすると、ループに入る前に i < 10
が成立していないと判断されるためループに入りません。そのため、printf("%d\n", i)
と i++
の処理は1度も実行されないことになります。
int i = 10;
while (i < 10) {
printf("%d\n", i);
i++;
}
また、ループに入る前にも 継続条件
が成立しているかどうかの判断が行われるため、継続条件
で変数を使用している場合、その変数には必ず何かしらの値を初期化 or 代入によって格納しておく必要があります。
もし、これを行わなければ、その変数に不定値が格納されたままで 継続条件
が成立しているかどうかの判断が行われますので、意図した通りにループが動作しないことになります。
例えば下記は、i
が 0
になるまで scanf
で i
に格納する整数の入力を受け付け、i
の値を2乗した結果を printf
で表示する while
ループの例となります。
int i;
while (i != 0) {
scanf("%d", &i);
printf("%d", i * i);
}
上記においては、ループに入る前に i != 0
が成立するかどうかの判断が行われますが、その前に i
の初期化や代入が行われていないため、i
には不定値が格納されていることになります。なので、i != 0
が成立するかどうかの判断は正しく行うことができません。
その不定値がたまたま 0
以外の値であれば、上手く動作するかもしれませんが、不定値が 0
であればループ内の処理は一度も行われないことになります。
このように、特に while
ループの場合、ループに入る前に 継続条件
が成立するかどうかの判断が行われますので、継続条件
の中で使用している変数には「適切な値」を格納しておく必要があります。ループの中で変数に値を格納しているからといって変数を不定値のままにしておくと、上手くループを動作させることができないので注意してください。
do while
:最後に継続するかどうかを判断する
while
では「繰り返す処理
を実行する前」にループを継続するかどうかの判断が行われるのに対し、do while
では「繰り返す処理
を実行した後」にループを継続するかどうかの判断が行われます。
do while
は下記のように 継続条件
と 繰り返す処理
を記述することでループを実現し、継続条件
が成立している間、繰り返す処理
の実行が繰り返されることになります。逆に 継続条件
が不成立になった際には、ループを抜け出し、繰り返す処理
の実行が終了することになります。
do {
繰り返す処理
} while (継続条件);
while (継続条件)
の後ろには ;
が必要なので注意してください(私は結構つけ忘れる…)。
例えば下記では、i
が 10
未満である間、printf("%d\n", i)
と i++
の処理が繰り返されることになります(なので、実行すれば 0
〜 9
が出力される)。
int i = 0;
do {
printf("%d\n", i);
i++;
} while (i < 10);
この例だけ見ると、while
と書き方は異なるものの、ほとんど同じように動作するように感じるかもしれません。
ただ、前述の通り、do while
では「繰り返す処理
を実行した後」にループを継続するかどうかの判断が行われます。したがって、while
とは異なり、ループに入る前には 継続条件
が成立しているかどうかの判断が行われません。
そのため、do while
においては、必ず1度は 繰り返す処理
が実行されることになります。ここが while
と動作が大きく異なる点になります。
ですので、先程の例において、i
の初期値を 10
にしても、ループに入る前には 継続条件
の成立 or 不成立が判断されないため、必ず一度は printf("%d\n", i)
と i++
の処理が実行されることになります。
int i = 10;
do {
printf("%d\n", i);
i++;
} while (i < 10);
while
と do while
とでは、ループを継続するかどうかの判断を行うタイミングが異なるため、while
では 繰り返す処理
が一度も実行されないことがありますが、do while
では 繰り返す処理
が必ず一度は実行されることになります。この点が while
と do while
のどちらを使うかの判断材料となります。
また、while
では、必ずループに入る前に 継続条件
で使用する変数に適切な値を格納しておく必要がありますが、do while
ではループに入った後に 繰り返す処理
の中で 継続条件
で使用する変数に値を格納するのでも正常にループを動作させることができます(もちろん do while
でも変数を初期化しておくに越したことはありません)。
スポンサーリンク
while
と do while
の使い分け
最後に、while
と do while
との使い分けについて解説しておきます。
正直いうと、私は do while
はあまり利用したことはないです。大体 while
でやりたいループは実現することができます。ただ、do while
を使った方がソースコードがスッキリすることがあることは確かですし、やりたいループを実現しやすい場合もあります。
前述の通り、while
と do while
のどちらを使うかの判断材料は下記になると思います。
while
:繰り返す処理
が一度も実行されないことがあるdo while
:繰り返す処理
が必ず一度は実行される
このような違いがあるため、ループを組む際に 繰り返す処理
を必ず一度は実行させるようにしたい場合、do while
を用いた方がソースコードがスッキリすることがあります。
すぐに思いつくのは、繰り返し scanf
でユーザーからの入力受付を行う場合に一度は必ず入力を受け付けたい場合や、ファイルの最後まで繰り返しファイルの中身の読み込みを行う場合などですかね。
例えば、下記は簡単なクイズを出題する場合の do while
の使用例となります。
int ans1, ans2, ans3;
do {
printf("Q1: 1 + 2 = ");
scanf("%d", &ans1);
} while (ans1 != (1 + 2));
do {
printf("Q2: 1 * 2 = ");
scanf("%d", &ans2);
} while (ans2 != (1 * 2));
do {
printf("Q3: 1 %% 2 = ");
scanf("%d", &ans3);
} while (ans3 != (1 % 2));
printf("CLEAR!!!\n");
各ループの中で printf
で出題された計算クイズの答えの入力を scanf
関数で受け付け、入力された値が不正解の間はループを抜けないように制御を行なっています(入力された値が正解であれば、ループを抜けて次のクイズの出題に移る)。
このようなプログラムの場合、各クイズに対して必ず一度は printf
関数と scanf
関数を実行することになります。なので、ループ内の printf
関数と scanf
関数が必ず一度は実行されるよう、do while
でループを作るようにしています。
同様の処理は while
でも実現できますが、この場合は、while
ループの外側で一度 printf
関数と scanf
関数を実行する必要がありますので、ちょっと do while
の時に比べるとソースコードが冗長になってしまうかなぁという印象です。
int ans1, ans2, ans3;
printf("Q1: 1 + 2 = ");
scanf("%d", &ans1);
while (ans1 != (1 + 2)) {
printf("Q1: 1 + 2 = ");
scanf("%d", &ans1);
}
printf("Q2: 1 * 2 = ");
scanf("%d", &ans2);
while (ans2 != (1 * 2)) {
printf("Q2: 1 * 2 = ");
scanf("%d", &ans2);
}
printf("Q3: 1 %% 2 = ");
scanf("%d", &ans3);
while (ans3 != (1 % 2)) {
printf("Q3: 1 %% 2 = ");
scanf("%d", &ans3);
}
printf("CLEAR!!!\n");
また、while
の場合でも、下記のように事前に ans1
と ans2
と ans3
に正解とは異なる値を格納しておけば、ループの外側での printf
関数と scanf
関数の実行も無くすことはできます。
ソースコードは短くなりますが、しっかりコメントを書いておかないと処理が理解しにくいかなぁと思いますし、この書き方をするくらいなら do while
を使えば良いのに…、と私なら感じてしまいますね…。
int ans1 = 0, ans2 = 0, ans3 = 0;
while (ans1 != (1 + 2)) {
printf("Q1: 1 + 2 = ");
scanf("%d", &ans1);
}
while (ans2 != (1 * 2)) {
printf("Q2: 1 * 2 = ");
scanf("%d", &ans2);
}
while (ans3 != (1 % 2)) {
printf("Q3: 1 %% 2 = ");
scanf("%d", &ans3);
}
printf("CLEAR!!!\n");
こんな感じで、ループの中の 繰り返す処理
を一度は必ず行いたい場合、do while
を利用することでスッキリしたソースコードに仕立てることができる場合があります。
基本は while
の方が使用する機会は多いと思いますが、繰り返す処理
を一度は必ず行いたいという場合は、do while
を利用することも検討してみると良いと思います。
まとめ
このページでは、C言語における「while
と do while
の違い」について解説しました。
while
と do while
では、指定した継続条件の成立 or 不成立の判断が行われるタイミングに違いがあります。
while
:繰り返す処理
実行前do while
:繰り返す処理
実行後
この違いにより、while
では 繰り返す処理
が一度も実行されないことがありますが、do while
では 繰り返す処理
が必ず一度は実行されることになります。
そのため、繰り返す処理
を必ず一度は実行するようにしたい際には、do while
を使用することでソースコードがスッキリする場合があります。
ただ、使用する機会 while
の方が多いと思いますので、まずは while
でループを実現し、その後、そのループが 「繰り返す処理
を必ず一度は実行する」ものである場合に、do while
を利用することを検討してみる流れで実装していくのが良いかなぁと思います。
また、今回は while
と do while
の違いについて解説しましたが、for
と while
の使い分けについても下記ページで解説していますので、興味があれば是非読んでみて下さい!
オススメの参考書(PR)
C言語学習中だけど分からないことが多くて挫折しそう...という方には、下記の「スッキリわかるC言語入門」がオススメです!
まず学習を進める上で、参考書は2冊持っておくことをオススメします。この理由は下記の2つです。
- 参考書によって、解説の仕方は異なる
- 読み手によって、理解しやすい解説の仕方は異なる
ある人の説明聞いても理解できなかったけど、他の人からちょっと違った観点での説明を聞いて「あー、そういうことね!」って簡単に理解できた経験をお持ちの方も多いのではないでしょうか?
それと同じで、1冊の参考書を読んで理解できない事も、他の参考書とは異なる内容の解説を読むことで理解できる可能性があります。
なので、参考書は2冊持っておいた方が学習時に挫折しにくいというのが私の考えです。
特に上記の「スッキリわかるC言語入門」は、他の参考書とは違った切り口での解説が豊富で、他の参考書で理解できなかった内容に対して違った観点での解説を読むことができ、オススメです。題名の通り「なぜそうなるのか?」がスッキリ理解できるような解説内容にもなっており、C言語入門書としてもかなり分かりやすい参考書だと思います。
もちろんネット等でも色んな観点からの解説を読むことが出来ますので、分からない点は別の人・別の参考書の解説を読んで解決していきましょう!もちろん私のサイトも参考にしていただけると嬉しいです!
入門用のオススメ参考書は下記ページでも紹介していますので、こちらも是非参考にしていただければと思います。
https://daeudaeu.com/c_reference_book/