はじめに
こんにちは。
順次、分岐、反復。プログラミングの3種の神器の一つの反復を実現してくれるwhile
にはきょうだい?のdowhile
があります。しかし、使い道が分からないままになっていませんか?(そもそもfor
しか使っていないとか?)
今回はdowhile
の使い道を紹介したいと思います。
dowhileとは
一応、知識を整理するためにまとめます
while
while
はまず( )の中の条件式を比較し、結果が真の場合は{ }の中の処理をします
次に( )の中の条件式を比較し...というのを繰り返します
そのため、条件式によっては処理が一回もされません
while (/* 条件式 */) {
/* 条件が真のときに行う処理 */
}
dowhile
dowhile
はまず{ }の中の処理をし、次に( )の中の条件式を比較します
その結果が真の場合はまた{ }の中の処理をし...というのを繰り返します
そのため、条件式にかかわらず、必ず一回は処理がされます
またwhile
と違い、( )の後ろに「;」が必要です
do {
/* 条件が真のときに行う処理 */
} while (/* 条件式 */);
#include <stdio.h>
int main(void) {
int i = 0;
// while_A
while (i < 3) {
printf("while_A_%d, ", i);
i ++;
}
// >> while_A_0, while_A_1, while_A_2
// while_B
while (i < 3) {
printf("while_B");
i ++;
}
// >> (何も出力されない)
i = 0;
// dowhile_A
do {
printf("dowhile_A_%d, ", i);
i ++;
} while (i < 3);
// >> dowhile_A_0, dowhile_A_1, dowhile_A_2
// dowhile_B
do {
printf("dowhile_B");
i ++;
} while (i < 3);
// >> dowhile_B
return 0;
}
dowhileの使い道
一回は処理がされる特徴を活用できる例を紹介します
ユーザからの入力を検証する場合
whileで書いた場合
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int inputedNum;
system("cls");
printf("あなたの誕生月を入力してください");
scanf("%d", &inputedNum);
while (inputedNum < 0 || inputedNum > 12) {
system("cls");
printf("あなたの誕生月を入力してください");
scanf("%d", &inputedNum);
}
// ...
return 0;
}
間違いではないですが、system("cls");
~ scanf("%d", &inputedNum);
が重複しているのが気になります。今回は重複しているコードが少ないですが、もっと多くなると見にくくなります。
また、int inputedNum = 0;
など、わざとwhile
の条件式の結果が真になるようにしてもいいですが、プログラムの意味合いから考えるといまいちです。今回は「ユーザの入力を検証して、誕生月でない場合はもう一度入力を要求する」という意味合いのコードを書きたいからです。
dowhileで書いた場合
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int inputedNum;
do {
system("cls");
printf("あなたの年齢を入力してください");
scanf("%d", &inputedNum);
} while (inputedNum < 0 || inputedNum > 12);
// ...
return 0;
}
while
で書いた場合の問題を解決できています
一つの#defineに複数の行を定義したい場合
(#define
の詳細な解説は省略します)
これはwhile
との比較ではなく、dowhile
だからこそできることです
ここでは引数に渡された2つの値を入れ替えるアルゴリズムであるSWAP
をマクロで定義するとします
dowhileを使わない場合
#define SWAP(x, y) \
tmp = x; \
x = y; \
y = tmp;
もしこれをif
の中で呼び出すと
int main (void) {
int x = 2, y = 3, z = 1;
if (z)
SWAP (x, y);
return 0;
}
は
int main (void) {
int x = 2, y = 3, z = 1;
if (z)
tmp = x;
x = y;
y = tmp;
return 0;
}
と解釈されるため、エラーやバグになります。
dowhileを使う場合
dowhile
はdo {/* 複数の文 */} while (0);
とすることで一つのブロックとなります
また条件式を0
とすることで{ }の中を一回だけ処理をさせることができます
#define SWAP(x, y) \
do { \
tmp = x; \
x = y; \
y = tmp; \
} while (0)
もしこれをif
の中で呼び出しても
int main (void) {
int x = 2, y = 3, z = 1;
if (z)
SWAP (x, y);
return 0;
}
は
int main (void) {
int x = 2, y = 3, z = 1;
if (z)
do {
tmp = x;
x = y;
y = tmp;
} while (0);
return 0;
}
と解釈され、正常に動きます。(引数が2回解釈されているため完璧なコードではありませんが、ここではdowhileの使い道を紹介したいので詳細な説明は割愛します)
さいごに
いかがでしたでしょうか?
少しでも参考に、そして使うきっかけになれば幸いです。
- 間違いや分かりにくいところがありましたら、遠慮なくコメントしてください。ただし筆者はCの上級者ではないので、その点はご容赦ください。