
C言語のきほん|for文とwhile文を使った多重ループを比較する
同じ多重ループでも、書き方で事故率が変わる。forとwhileの“得意な役割分担”を身につけよう。
多重ループはforでもwhileでも書けるけど、向き不向きがある
多重ループは、外側が「行」、内側が「列」を担当する…という考え方でした。
この構造は for でも while でも作れます。動作の本質は同じです。
ただ、書き方の違いがそのまま「読みやすさ」や「ミスの起きやすさ」に直結します。
- for:回数が明確な繰り返しを、短く・見通しよく書ける
- while:条件や終了タイミングが変動する繰り返しを、柔軟に書ける(でも更新忘れで無限ループになりやすい)
さらに、外側と内側で for と while を混ぜて使うと「一番自然な形」にできます。ここが今回のポイントです。
for文の多重ループの特徴
forの二重ループは、初期化・条件・更新が括弧の中にまとまるので、ループの形が一目で分かります。
| 観点 | forの強み |
|---|---|
| 見通し | ループの形が1行で分かる |
| 向いている場面 | 回数や範囲が決まっている(行数、列数が固定) |
| 多重ループでの定番 | 外側も内側もforで行×列を作る |
while文の多重ループの特徴
whileは初期化と更新を自分で書く必要があるぶん、自由度が高い反面、ミスもしやすいです。
| 観点 | whileの特徴 |
|---|---|
| 柔軟性 | 条件が変動するループに強い |
| 注意点 | 更新を書き忘れると無限ループになりやすい |
| 多重ループでの使いどころ | 入力が終わるまでなど、回数が不確定な外側ループ |
図で整理:forとwhileを混ぜると自然になる

この “外側while+内側for” は、実務でもよく出てきます。
サンプルプログラム
例:入力された回数だけ「#」を表示(0以下で終了)
- 外側:入力が続く限り繰り返す(while)
- 内側:指定回数だけ表示(for)
ファイル名:9_9_1.c
// 指定された個数の「#」を繰り返し表示するプログラム
#include <stdio.h>
int main(void)
{
int num;
printf("表示回数を入力してください(0以下で終了)> ");
scanf("%d", &num);
while (num > 0) { // 入力が正の間だけ繰り返す(while)
for (int i = 1; i <= num; i++) { // num回だけ繰り返す(for)
printf("#");
}
printf("\n");
printf("表示回数を入力してください(0以下で終了)> ");
scanf("%d", &num);
}
printf("終了します。\n");
return 0;
}ここが使い分けの気持ちいいところ
- 外側は「いつ終わるか分からない」のでwhile
- 内側は「回数が決まっている」のでfor
この役割分担が自然で、読みやすくなります。
for多重ループとwhile多重ループを同じ処理で書き比べる
ここでは「3行×5列の数表」を両方で書いて、違いを体感します。
for版(回数が明確でスッキリ)
ファイル名:9_9_2.c
// forの二重ループで 3行×5列 を表示するプログラム
#include <stdio.h>
int main(void)
{
for (int row = 1; row <= 3; row++) {
for (int col = 1; col <= 5; col++) {
printf("%d ", col);
}
printf("\n");
}
return 0;
}while版(初期化と更新の位置に注意)
ファイル名:9_9_3.c
// whileの二重ループで 3行×5列 を表示するプログラム
#include <stdio.h>
int main(void)
{
int row = 1; // 外側の初期化
while (row <= 3) { // 外側の条件
int col = 1; // 内側は毎行ごとに初期化が必要
while (col <= 5) { // 内側の条件
printf("%d ", col);
col++; // 内側の更新(忘れると無限ループ)
}
printf("\n");
row++; // 外側の更新(忘れると無限ループ)
}
return 0;
}while版でよくある事故(ここ注意)
- colの初期化を外に置いてしまう
→ 2行目以降、内側ループが回らない(colがすでに6になっているなど) - col++やrow++を書き忘れる
→ 無限ループ
多重ループだと更新が2か所あるので、whileは特に事故りやすいんです。
実践問題:行数ぶんの段を表示
行数を入力し、次のように段を表示してください。
実行例
行数を入力してください > 4
1
1 2
1 2 3
1 2 3 4解答例
ファイル名:9_9_4.c
// 行数に応じて段を表示するプログラム
#include <stdio.h>
int main(void)
{
int n;
printf("行数を入力してください > ");
scanf("%d", &n);
for (int row = 1; row <= n; row++) {
for (int col = 1; col <= row; col++) { // 行番号と同じ回数だけ表示
printf("%d ", col);
}
printf("\n");
}
return 0;
}解説
内側の継続条件は col <= row。
その行で表示したい個数が row 個だからです。
実践問題:九九の表を表示
解答例
ファイル名:9_9_5.c
// 九九の表を表示するプログラム
#include <stdio.h>
int main(void)
{
printf("* * * 九九の表示 * * *\n");
printf(" |");
for (int col = 1; col <= 9; col++) {
printf("%3d", col);
}
printf("\n");
printf("--------------------------------\n");
for (int row = 1; row <= 9; row++) {
printf("%2d |", row); // 行見出しと区切り線
for (int col = 1; col <= 9; col++) { // 掛け算本体
printf("%3d", row * col);
}
printf("\n");
}
return 0;
}解説(どこで何を表示するか)
- 最初にタイトル行
- 次に上段の列見出し(1〜9)
- その次に横線
- そのあと、外側ループで行(1〜9)
・行頭で row と | を表示
・内側ループで row * col を並べる
「| をどこで出すか」を先に決めると、迷いにくいです。
実践問題:0~9の3つの数の和が指定値になる組
0~9の3つの整数 (a, b, c) の和が入力した合計値になる組み合わせをすべて表示し、通り数も表示してください。
解答例
ファイル名:9_9_6.c
// 0~9の3つの数の和が指定値になる組を全探索するプログラム
#include <stdio.h>
int main(void)
{
int target;
int count = 0;
printf("合計値を入力してください。> ");
scanf("%d", &target);
for (int a = 0; a <= 9; a++) {
for (int b = 0; b <= 9; b++) {
for (int c = 0; c <= 9; c++) {
if (a + b + c == target) {
printf("(%d, %d, %d)\n", a, b, c);
count++;
}
}
}
}
printf("合計値が%dになる組み合わせは%d通りです。\n", target, count);
return 0;
}解説
三重ループは「全パターンを試す」ための道具です。
0〜9の10通りが3つなので、10×10×10=1000通りを全部チェックしています。
ifで一致したものだけ表示して数えます。
実践問題:forとwhileを組み合わせる二重ループ
セット回数を入力し、その回数だけ次を繰り返してください。
- 0以下が入力されるまで、正の整数を何回でも入力できる
- 入力された正の整数の合計を表示する
- これをセット回数ぶん繰り返す
解答例
ファイル名:9_9_7.c
// forとwhileを組み合わせて、セットごとに合計を求めるプログラム
#include <stdio.h>
int main(void)
{
int times;
printf("セット回数を入力してください > ");
scanf("%d", ×);
for (int t = 1; t <= times; t++) {
int n;
int sum = 0;
printf("---- %dセット目 ----\n", t);
printf("整数値を入力してください(0以下で終了)> ");
scanf("%d", &n);
while (n > 0) {
sum += n;
printf("整数値を入力してください(0以下で終了)> ");
scanf("%d", &n);
}
printf("合計値 = %d\n\n", sum);
}
return 0;
}解説(役割分担がキレイ)
- 外側for:セット回数が決まっている(回数主役)
- 内側while:0以下が出るまで入力(条件主役)
この分担は、まさに「forとwhileの使い分け」の実戦例です。
実践問題:菱形を表示
ファイル名:9_9_8.c
// 入力nに応じて菱形を表示するプログラム(奇数・偶数対応)
#include <stdio.h>
int main(void)
{
int n;
printf("*の数を入力してください > ");
scanf("%d", &n);
if (n <= 0) {
printf("エラー:1以上を入力してください。\n");
return 0;
}
// 偶数なら最大は n-1、奇数なら最大は n
int maxStars = (n % 2 == 0) ? (n - 1) : n;
// 上り(1,3,5,...,maxStars)
for (int stars = 1; stars <= maxStars; stars += 2) {
int spaces = (n - stars) / 2; // n幅で中央寄せ
for (int s = 0; s < spaces; s++) printf(" ");
for (int k = 0; k < stars; k++) printf("*");
printf("\n");
}
// 下り(maxStars-2,...,3,1)
for (int stars = maxStars - 2; stars >= 1; stars -= 2) {
int spaces = (n - stars) / 2;
for (int s = 0; s < spaces; s++) printf(" ");
for (int k = 0; k < stars; k++) printf("*");
printf("\n");
}
return 0;
}解説(菱形は3つの部品でできてる)
1行ごとにやっていることは毎回同じです。
- 先頭にスペースを出す(中央寄せ)
- 星を stars 個出す
- 改行
外側ループは stars の値を 1→3→5… と増やし、次に減らしていくだけです。
内側ループは「スペースをspaces回」「星をstars回」出す担当です。
実行結果例1(奇数のnを入力した場合:n=7)
*の数を入力してください > 7
*
***
*****
*******
*****
***
*実行結果例2(偶数のnを入力した場合:n=6)
*の数を入力してください > 6
*
***
*****
***
*