C言語プログラミング:do-whileループを使いこなして、よりスマートなコードを書こう
構文
do {
ループ内の処理;
} while (ループ条件);
解説
ループ条件
:ループを継続するかどうかを判断する論理式を記述します。while
:ループ条件を示すキーワードです。ループ内の処理
:ループ内で繰り返し実行される処理を記述します。{ }
:ループ内の処理を記述する中括弧です。省略することもできますが、可読性を高めるために推奨されます。do
:ループの開始を示すキーワードです。
動作
- ループ内の処理を実行します。
- ループ条件を評価します。
- ループ条件が真の場合、1に戻る。
- ループ条件が偽の場合、ループを終了します。
whileループとの違い
whileループとdo-whileループの主な違いは以下の2点です。
- ループ条件の評価タイミング
- whileループ
ループの前に評価されます。ループ条件が偽の場合、ループ内の処理は1回も実行されません。 - do-whileループ
ループの後に評価されます。ループ条件が偽の場合でも、ループ内の処理は少なくとも1回は実行されます。
- whileループ
- ループ内の処理の最低実行回数:**
- whileループ
ループ条件が真の場合のみ処理が実行されるため、ループ内の処理が0回実行される可能性があります。 - do-whileループ
ループ条件が評価される前に処理が実行されるため、ループ内の処理が少なくとも1回は実行されます。
- whileループ
例
以下のプログラムは、1から10までの整数を順に表示するdo-whileループの例です。
#include <stdio.h>
int main() {
int i = 1;
do {
printf("%d ", i);
i++;
} while (i <= 10);
return 0;
}
出力
1 2 3 4 5 6 7 8 9 10
利点
- 初期化処理などをループの最初に記述する必要がないため、コードが簡潔になる場合があります。
- ループ条件が偽であっても、ループ内の処理を少なくとも1回は実行する必要がある場合に適しています。
- ループ条件が偽であっても、ループ内の処理が1回実行されるため、処理効率がwhileループよりも劣る場合があります。
do-whileループは、ループ条件をループの後に評価するため、ループ内の処理が少なくとも1回は必ず実行されるという特徴があります。この特性を活かして、ループ条件が偽であってもループ内の処理を1回は実行する必要がある場合などに適しています。
一方、ループ条件が偽であってもループ内の処理が1回実行されるため、処理効率がwhileループよりも劣る場合があります。そのため、ループ条件が真であることが確実な場合は、whileループを使用する方が効率的です。
適切なループ構造を選択することは、プログラムの可読性と処理効率を向上させるために重要です。
1から10までの整数を逆順に表示
#include <stdio.h>
int main() {
int i = 10;
do {
printf("%d ", i);
i--;
} while (i >= 1);
return 0;
}
出力
10 9 8 7 6 5 4 3 2 1
ユーザーが入力した数値の合計を求める
#include <stdio.h>
int main() {
int num, sum = 0;
do {
printf("数値を入力してください: ");
scanf("%d", &num);
sum += num;
} while (num != 0);
printf("合計: %d\n", sum);
return 0;
}
実行例
数値を入力してください: 10
数値を入力してください: 5
数値を入力してください: 2
数値を入力してください: 0
合計: 17
パスワード認証を行う
#include <stdio.h>
#include <string.h>
int main() {
char password[100];
do {
printf("パスワードを入力してください: ");
scanf("%s", password);
if (strcmp(password, "secret") == 0) {
printf("ログイン成功!\n");
break;
} else {
printf("パスワードが間違っています。もう一度入力してください。\n");
}
} while (1);
return 0;
}
実行例
パスワードを入力してください: incorrect
パスワードが間違っています。もう一度入力してください。
パスワードを入力してください: another_incorrect_password
パスワードが間違っています。もう一度入力してください。
パスワードを入力してください: secret
ログイン成功!
#include <stdio.h>
#include <stdlib.h>
int main() {
int num;
do {
num = rand() % 100;
printf("%d ", num);
} while (num >= 10);
printf("\n10以下のランダムな数値: %d\n", num);
return 0;
}
出力例
73 24 9 6 5
10以下のランダムな数値: 5
これらの例は、do-whileループの様々な使用方法を示しています。do-whileループは、様々な状況で使用できる汎用的なループ構造です。
whileループ
whileループは、ループ条件が真の場合のみループを継続するループ構造です。do-whileループと異なり、ループ内の処理が0回実行される可能性があります。
利点
- do-whileループよりも簡潔なコードで記述できる場合があります。
- ループ条件が真であることが確実な場合に効率的です。
欠点
- ループ条件が偽の場合、ループ内の処理が1回も実行されない可能性があります。
例
int main() {
int i = 1;
while (i <= 10) {
printf("%d ", i);
i++;
}
return 0;
}
出力
1 2 3 4 5 6 7 8 9 10
forループ
forループは、ループカウンタを初期化し、ループ条件を満たすまで一定間隔でインクリメントしながらループを継続するループ構造です。do-whileループやwhileループよりも、ループの範囲を明確に記述できるという利点があります。
利点
- ループカウンタを自由に操作できる。
- ループの範囲を明確に記述できる。
欠点
- ループ条件が複雑な場合、whileループやdo-whileループよりも記述が煩雑になる場合があります。
例
int main() {
for (int i = 1; i <= 10; i++) {
printf("%d ", i);
}
return 0;
}
出力
1 2 3 4 5 6 7 8 9 10
goto文
goto文は、プログラムの制御フローを任意の場所にジャンプさせる文です。ループ構造を構成するためにgoto文を使用することはできますが、非構造化プログラミングとなるため、可読性が低くなり、保守が難しくなるという欠点があります。
利点
- 複雑なループ構造を記述できる。
欠点
- 保守が難しくなる。
- 非構造化プログラミングとなり、可読性が低くなる。
例
int main() {
int i = 1;
loop:
printf("%d ", i);
i++;
if (i > 10) {
goto exit;
}
goto loop;
exit:
return 0;
}
出力
1 2 3 4 5 6 7 8 9 10
再帰
再帰は、関数を自分自身を呼び出すことでループ構造を構成する手法です。do-whileループやwhileループよりもエレガントなコードで記述できる場合があります。
利点
- エレガントなコードで記述できる。
欠点
- スタックオーバーフローが発生する可能性があります。
- 複雑な再帰呼び出しは、理解しにくく、デバッグが難しい場合があります。
例
void printNumbers(int n) {
if (n == 0) {
return;
}
printf("%d ", n);
printNumbers(n - 1);
}
int main() {
printNumbers(10);
return 0;
}
10 9 8 7 6 5 4 3 2 1