6日でできる 新C言語入門|forの2重ループで表や図形を表示する方法

行と列を組み合わせれば、表も図形も作れる。
forの2重ループを理解して、規則的な表示を自在に書けるようになろう。

C言語でfor文を学ぶと、同じ処理を決まった回数だけ繰り返せるようになります。さらに、for文の中にもう1つfor文を書くと、表のような行と列のある表示や、記号を並べた図形を作れるようになります。このような書き方をforの2重ループ、またはfor文のネストと呼びます。

2重ループは、最初は少し複雑に見えるかもしれません。しかし、考え方はとてもシンプルです。外側のfor文が行を進め、内側のfor文がその行の中で列を進めます。つまり、外側が縦方向、内側が横方向を担当するイメージです。

たとえば、九九の表を表示する場合、外側のfor文で1の段、2の段、3の段というように段を進めます。そして、内側のfor文で1から9までを掛けながら、1行分の計算結果を表示します。1行分が終わったら改行し、次の段へ進みます。

このように、forの2重ループを使うと、規則的な並びを持つ表示をとても書きやすくなります。九九の表、座標の表示、三角形の図形、入力された行数に応じた表示など、いろいろな出力に応用できます。

この記事では、forの2重ループの基本構造から、九九の表、行列状の表示、図形描画、入力値を使った応用例まで、サンプルプログラムを使いながらやさしく解説していきます。

forの2重ループは、外側と内側で役割を分ける

forの2重ループは、for文の中にさらにfor文を書く構造です。基本の形は次のようになります。

for (外側の初期化式; 外側の条件式; 外側の増分式) {
    for (内側の初期化式; 内側の条件式; 内側の増分式) {
        実行したい処理
    }
}

外側のfor文と内側のfor文には、それぞれ役割があります。

ループ主な役割表示でのイメージ
外側のfor文行を進める何行表示するかを決める
内側のfor文列を進める1行の中で何個表示するかを決める
内側の処理実際に表示する数値や記号を表示する
内側の後の改行次の行へ移る1行分の表示が終わったら改行する

2重ループでは、外側のfor文が1回進むたびに、内側のfor文が最初から最後まで実行されます。ここがとても大切です。

たとえば、外側が9回、内側も9回なら、内側の処理は合計で81回実行されます。九九の表が9行9列になるのも、この考え方によるものです。

図:forの2重ループの基本構造

この図から分かること

この図から分かるのは、2重ループでは外側のfor文と内側のfor文が別々の役割を持っているということです。

外側のfor文は行を進め、内側のfor文はその行の中の列を進めます。1行分の内側の処理が終わると改行し、外側のfor文が次の行へ進みます。この流れを理解すると、表や図形を表示するプログラムが読みやすくなります。

まずは基本的な2重ループの動きを見てみよう

2重ループの動きを理解するために、九九の表を表示するプログラムを見てみましょう。九九の表は、行と列の組み合わせがとても分かりやすいため、2重ループの練習に向いています。

プロジェクト/ファイル名: Lesson27_1/main.c

#include <stdio.h>

int main(void) {
    int row, col;

    // 外側のfor文で九九の段を1から9まで進める
    for (row = 1; row <= 9; row++) {
        // 内側のfor文で掛ける数を1から9まで進める
        for (col = 1; col <= 9; col++) {
            printf("%2d ", row * col);
        }

        // 1段分の表示が終わったら改行する
        printf("\n");
    }

    return 0;
}

実行結果

 1  2  3  4  5  6  7  8  9
 2  4  6  8 10 12 14 16 18
 3  6  9 12 15 18 21 24 27
 4  8 12 16 20 24 28 32 36
 5 10 15 20 25 30 35 40 45
 6 12 18 24 30 36 42 48 54
 7 14 21 28 35 42 49 56 63
 8 16 24 32 40 48 56 64 72
 9 18 27 36 45 54 63 72 81

このプログラムでは、rowが九九の段を表し、colが掛ける数を表しています。

rowが1のとき、内側のfor文でcolが1から9まで進みます。そのため、1×1から1×9までの結果が1行に表示されます。次にrowが2になると、2×1から2×9までが表示されます。この流れをrowが9になるまで繰り返すことで、九九の表全体を表示できます。

九九の表では外側が段、内側が掛ける数になる

九九の表を2重ループで考えると、外側と内側の役割がとても分かりやすくなります。

変数役割変化のしかた
row九九の段1から9まで進む
col掛ける数各段の中で1から9まで進む
row * col表示する計算結果掛け算の答えになる

たとえば、rowが3のときは、内側のcolが1から9まで動きます。

rowcolの変化表示される内容
11から91の段
21から92の段
31から93の段
91から99の段

このように、外側のrowが1つ決まるたびに、内側のcolが1から9まで全部動きます。これが2重ループの基本的な流れです。

printfの書式で表の見た目を整える

九九の表では、printfの中で%2dを使っています。

printf("%2d ", row * col);

%2dは、整数を2文字分の幅で表示する指定です。九九の結果には1桁の数と2桁の数が混ざるため、幅をそろえると表として見やすくなります。

もし%dだけで表示すると、数値の桁数によって位置が少しずれて見えることがあります。表のように並べたい場合は、表示幅を指定すると見た目を整えやすくなります。

書式指定表示の特徴
%d数値をそのまま表示する
%2d2文字分の幅で数値を表示する
%3d3文字分の幅で数値を表示する

表をきれいに表示するには、2重ループだけでなく、printfの表示幅も大切です。

改行の位置が表の形を決める

2重ループで表を表示するとき、改行を書く位置はとても重要です。

九九の表では、改行のためのprintfを内側のfor文の外側、外側のfor文の中に書いています。

for (row = 1; row <= 9; row++) {
    for (col = 1; col <= 9; col++) {
        printf("%2d ", row * col);
    }

    printf("\n");
}

この位置に改行を書くことで、1段分を横に表示してから次の行へ移れます。

もし改行を内側のfor文の中に書いてしまうと、1つの数値を表示するたびに改行されてしまい、表の形になりません。表や図形を作るときは、どこで1行が終わるのかを考えながら改行の位置を決めることが大切です。

行列状の表示で2重ループをさらに確認する

次に、行と列の関係をもう少し直接的に確認できるプログラムを見てみましょう。ここでは、行番号と列番号を組み合わせて座標のように表示します。

プロジェクト/ファイル名: Lesson27_2/main.c

#include <stdio.h>

int main(void) {
    int i, j;

    // 外側のfor文で行を1から4まで進める
    for (i = 1; i <= 4; i++) {
        // 内側のfor文で列を1から5まで進める
        for (j = 1; j <= 5; j++) {
            printf("[%d,%d] ", i, j);
        }

        // 1行分の表示が終わったら改行する
        printf("\n");
    }

    return 0;
}

実行結果

[1,1] [1,2] [1,3] [1,4] [1,5]
[2,1] [2,2] [2,3] [2,4] [2,5]
[3,1] [3,2] [3,3] [3,4] [3,5]
[4,1] [4,2] [4,3] [4,4] [4,5]

このプログラムでは、iが行番号、jが列番号の役割を持っています。九九の表ではrowとcolを使いましたが、考え方は同じです。

外側のfor文で行を進め、内側のfor文でその行の中の列を進めています。行と列の考え方が分かると、2重ループの動きがかなり理解しやすくなります。

図:2重ループで表を表示する流れ

この図から分かること

この図から分かるのは、2重ループを使うと、行と列を持つ表を規則的に表示できることです。

外側の変数が行を表し、内側の変数が列を表します。1行の中では内側のfor文が左から右へ進み、1行が終わると外側のfor文が次の行へ進みます。九九の表も座標の表も、この基本の流れで作られています。

図形の表示にも2重ループを使える

2重ループは、表だけでなく図形の表示にも使えます。記号を規則的に並べる処理では、外側のfor文で行数を決め、内側のfor文でその行に表示する記号の数を決めます。

次のプログラムでは、★を使って右下がりの三角形を表示します。

プロジェクト/ファイル名: Lesson27_3/main.c

#include <stdio.h>

int main(void) {
    int i, j;

    // 1行目から5行目まで繰り返す
    for (i = 1; i <= 5; i++) {
        // 行番号と同じ数だけ★を表示する
        for (j = 1; j <= i; j++) {
            printf("★");
        }

        // 1行分の表示が終わったら改行する
        printf("\n");
    }

    return 0;
}

実行結果

★
★★
★★★
★★★★
★★★★★

このプログラムでは、外側のiが行番号を表しています。内側のjは、各行で★を何個表示するかを決めています。

iが1なら★を1個、iが2なら★を2個、iが5なら★を5個表示します。内側の条件がj <= iになっているため、行が進むほど表示される★の数が増えていきます。

図形表示では内側の条件が形を決める

図形を表示するときは、内側のfor文の条件がとても重要です。

for (j = 1; j <= i; j++) {
    printf("★");
}

この条件では、jがi以下の間だけ★を表示します。そのため、iの値が大きくなるほど、1行に表示される★の数も増えます。

iの値jの動き表示される★の数
111個
21, 22個
31, 2, 33個
41, 2, 3, 44個
51, 2, 3, 4, 55個

表を表示するときは、内側の回数が固定されていることが多いです。一方、図形を表示するときは、内側の回数を行番号に合わせて変えることで、三角形のような形を作れます。

入力された値に合わせて表示する行数を変える

2重ループでは、ユーザーが入力した値を使って表示する行数を変えることもできます。入力値に応じて繰り返し回数を決めれば、固定ではない出力も作れます。

プロジェクト/ファイル名: Lesson27_4/main.c

#include <stdio.h>

int main(void) {
    int n, i, j;

    printf("表示する行数を入力してください:");
    scanf("%d", &n);

    // 1行目からn行目まで繰り返す
    for (i = 1; i <= n; i++) {
        // 1からiまでの数字を表示する
        for (j = 1; j <= i; j++) {
            printf("%d ", j);
        }

        // 1行分の表示が終わったら改行する
        printf("\n");
    }

    return 0;
}

実行結果

Visual Studioでscanfを使う場合、設定によって警告が表示されることがあります。学習用として動作確認する場合は、必要に応じてSDLチェックの設定も確認しておきましょう。

表示する行数を入力してください:4
1
1 2
1 2 3
1 2 3 4

このプログラムでは、入力されたnの値によって、外側のfor文の繰り返し回数が変わります。nに4を入力すれば4行、nに6を入力すれば6行表示できます。

このように、2重ループは固定の表や図形だけでなく、入力値に応じた柔軟な表示にも使えます。

2重ループでは変数の役割をはっきりさせる

2重ループでは、複数の変数が登場します。どの変数が何を表しているのかを整理しておくことが大切です。

変数名の例よくある役割
row行を表す
col列を表す
i外側のループで使うことが多い
j内側のループで使うことが多い
n入力された行数や最大値を表すことが多い

九九の表ではrowとcolのような名前を使うと、段と掛ける数の役割が分かりやすくなります。座標表示や図形表示ではiとjを使うことも多いです。

大切なのは、外側が何を担当しているのか、内側が何を担当しているのかを自分で説明できることです。

2重ループでよくあるミス

2重ループは便利ですが、最初のうちはいくつかのミスが起こりやすいです。

よくあるミス内容
改行の位置を間違える表や図形の形が崩れる
外側と内側の変数を混同する行と列の意味が分かりにくくなる
条件式の範囲を間違える表示回数が多すぎたり少なすぎたりする
内側のfor文の初期化を忘れる各行で内側の処理が正しく始まらない
処理回数を意識しない繰り返し回数が大きくなりすぎる

特に、改行の位置は重要です。表を作る場合、改行は内側のfor文が終わったあとに書くことが多いです。これにより、1行分を横に表示してから次の行へ進めます。

処理回数が増えることにも注意する

2重ループでは、外側の回数と内側の回数が掛け合わされます。

たとえば、九九の表では外側が9回、内側が9回なので、計算結果を表示する処理は9×9で81回実行されます。

外側の回数内側の回数内側の処理の合計回数
3回4回12回
4回5回20回
9回9回81回
100回100回10000回

学習用の小さなプログラムでは問題になりにくいですが、回数が大きくなると処理量も増えます。将来的に配列や大量データを扱うときには、2重ループの処理回数も意識できるとよいです。

図:2重ループで図形を作るイメージ

この図から分かること

この図から分かるのは、2重ループを使うと、行ごとに表示する個数を変えながら図形を作れるということです。

外側のfor文で何行表示するかを決め、内側のfor文でその行に何個表示するかを決めます。内側の条件を工夫すると、三角形や四角形など、いろいろな形を作れるようになります。

2重ループは表、図形、配列処理の土台になる

forの2重ループは、表示を整えるだけの技術ではありません。行と列を扱う考え方は、今後学ぶ2次元配列や表形式データの処理にもつながります。

たとえば、成績表、座席表、ゲームのマップ、画像のピクセル処理など、行と列の考え方を使う場面はたくさんあります。2重ループの基本を理解しておくと、こうした内容にも進みやすくなります。

2重ループに慣れるための見方

2重ループを読むときは、次の順番で確認すると分かりやすくなります。

確認すること見るポイント
外側のfor文何行分繰り返すか
内側のfor文1行の中で何回繰り返すか
表示している内容数値、座標、記号など何を出しているか
改行の位置どこで次の行へ移るか
変数の役割行を表すのか、列を表すのか

最初はコードだけを見ると難しく感じるかもしれませんが、外側は行、内側は列と考えると整理しやすくなります。

九九の表、座標表示、三角形の表示のように、目で結果を確認しやすいプログラムから練習すると、2重ループの感覚をつかみやすくなります。少しずつ試しながら、行と列の繰り返しに慣れていきましょう。