【第5回】C言語の繰り返し処理:for文・while文・do-while文の使い分け
1. はじめに:同じ処理を効率よく繰り返そう
前回は、if 文や switch 文による条件分岐、そしてユーザー入力を受け取る scanf の使い方を確認しました。
プログラムを作っていくうえで、「同じ処理を何度も繰り返し実行したい」「配列のすべての要素を順番に処理したい」という場面は非常に多く登場します。手動で何行も同じコードを書く代わりに、繰り返し処理(ループ)を使うことで、スマートで効率的なプログラムを書くことができます。
今回は、C言語における代表的なループ構文である for 文、while 文、do-while 文の仕組みと、ループを制御する break / continue の使い方を確認していきましょう。
2. for 文の基本構文と配列の走査
あらかじめループ回数が決まっている場合に使用する基本の構文が for 文です。
基本構文
for (初期化式; 条件式; 変化式) {
処理;
}
実装サンプル:サーバー名の配列走査
例えば、管理している複数のサーバーホスト名を配列に格納し、順番に一覧表示するプログラムは以下のように記述できます。
#include <stdio.h>
int main(void)
{
char servers[4][20] = {
"web-server-01",
"web-server-02",
"db-server-01",
"cache-server-01"
};
int i; /* カウンタ変数 */
printf("稼働中サーバー一覧:\n");
for(i = 0; i < 4; i++){
printf("\t[%d] %s\n", i + 1, servers[i]);
}
return 0;
}
3. 多重ループと制御文(break / continue)
多重ループ(ネスト)
if 文と同様に、ループの中にさらに別のループを内包させる(多重ループにする)ことが可能です。
制御文
continue;: 条件を満たした場合、以降の処理をスキップして次のループへ進みます。break;: 条件を満たした場合、以降の処理を行わず現在のループ外へ脱出します。- ※多重ループの場合は、直属の最も内側のループを1つ抜けるだけで、外側のループ処理は継続します。
実装サンプル:2次元配列の文字走査と終端判定
文字列を1文字ずつ走査し、ターミネータ(\0)でループを抜ける処理を2次元配列で実装した例です。
#include <stdio.h>
int main(void)
{
char servers[4][20] = {
"web-01",
"api-02",
"db-01",
"cache"
};
int i, j;
printf("サーバーID詳細走査:\n");
for(i = 0; i < 4; i++){
printf("\t[%d] ", i + 1);
/*
sizeof(servers[i]) は1行あたりのバイト数(20)
*/
for(j = 0; j < 20; j++){
/* ターミネータ('\0')でなければ文字を1文字ずつ表示 */
if(servers[i][j] != '\0'){
printf("%c", servers[i][j]);
continue;
}
/* ターミネータ('\0')だった場合は文字列の終端とみなしループを抜ける */
break;
}
printf("\n");
}
return 0;
}
【文字列の終端】 C言語の文字列は、末尾に必ず終端文字(ターミネータ
\0)が自動で格納されます。この仕組みがあるため、配列のサイズ内に収まっていても文字列の終わりを正確に検知することができます。
4. while 文と do ~ while 文
while 文
条件式を先に評価し、条件を満たしている間(真の間)ループを繰り返します。
while (条件式) {
処理;
}
- 注意点: 処理内で条件式の値が変化するようにしておかないと、無限ループになってしまうため注意が必要です。
do ~ while 文
最初の処理を強制的に1回実行したあとで、条件式の判定を行います。
do {
処理;
} while (条件式);
- 特徴: 条件式の真偽に関わらず、必ず最低1回は処理が実行されます。
実装サンプル:while と do ~ while の比較
同じ処理を while 文と do ~ while 文それぞれの書き方で実装した例です。
#include <stdio.h>
int main(void)
{
char servers[4][20] = {
"web-01",
"api-02",
"db-01",
"cache"
};
int i;
/* while文を用いた場合 */
printf("--- while文による出力 ---\n");
i = 0;
while(i < 4){
printf("\t[%d] %s\n", i + 1, servers[i]);
i++;
}
/* do~while文を用いた場合 */
printf("--- do~while文による出力 ---\n");
i = 0;
do {
printf("\t[%d] %s\n", i + 1, servers[i]);
i++;
} while(i < 4);
return 0;
}
5. 繰り返し処理の使い分け
目的に応じて最適なループ構文を選択することが重要です。
for文: あらかじめループ回数が決まっている場合(配列の要素数ループなど)。while文: ループ回数が不定で、ある特定の条件を満たすまで続けたい場合。do ~ while文: 条件に関係なく、必ず最初に1回は処理を実行したい場合(メニュー画面の表示や入力判定など)。
6. まとめと次回予告
今回は、同じ処理を効率よく実行するための繰り返し処理(for 文・while 文・do-while 文)と、ループを制御する break / continue の使い方を確認しました。
今回学んだ内容を整理すると、次のとおりです。
- 回数が決まっている場合は
for文を使い、カウンタ変数を用いて配列などを効率よく走査できる breakでループを強制終了し、continueで現在の回をスキップして次へ進める- 条件を先に判定する
while文と、必ず1回実行してから判定するdo-while文がある - 用途に合わせて適切なループ構文を使い分けることが大切である
今回の内容を通して、データの集まりを効率よく処理したり、条件に応じたループ制御を行う方法が身についたかと思います。
次回は、処理をまとめて効率よく記述するための「関数」の仕組み(引数・戻り値・変数スコープ)について学びます。実際のコードを書きながら、モジュール化の基本を確認していきましょう。
【お役立ちツールのご案内】
C言語やPHPの学習を進める中で、ご自身の書いたコードや既存のプロジェクトにセキュリティ上のリスクや古い書き方(非推奨関数など)が混ざっていないか気になった際は、安全な字句解析(
token_get_all())で一括スキャンできる当サイトの PHPレガシーコードスキャナー もぜひご活用ください。