C言語基礎|2重ループで作る九九表

はじめに:多重ループは「表」や「マス目」を作る最強の道具

ここまでの繰り返しは、1本のループで完結する“単純ループ”が中心でした。
でも実際のプログラムでは、「行ごとに」「列ごとに」みたいに 繰り返しの中でさらに繰り返す 場面がめちゃくちゃ多いんです。

このように、ループの中にループが入っている形を 多重ループ(nested loop)と呼びます。
入れ子が2段なら 2重ループ、3段なら 3重ループ…という感じです。

その中でも 2重ループは、行と列をもつ「表」を作るときの王道パターンです。

今回はまさにその代表例、九九表(1×1〜9×9)を表示するプログラムで、2重ループの動きをしっかり体に入れていきましょう。

サンプルプログラム:2重ループで九九表を表示

表示メッセージは、元の例とは違う日本語に置き換えています。

プロジェクト名:chap4-17-1 ソースファイル名:chap4-17-1.c

#include <stdio.h>

int main(void)
{
    puts("【九九表(1〜9)】");

    for (int i = 1; i <= 9; i++) {            // 行(1段〜9段)
        for (int j = 1; j <= 9; j++) {        // 列(×1〜×9)
            printf("%3d", i * j);             // 3桁幅でそろえて表示
        }
        putchar('\n');                        // 行の終わりで改行
    }

    return 0;
}

実行結果

【九九表(1〜9)】
  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

2重ループの考え方:外側が「行」、内側が「列」

九九表は「段(行)」と「×の相手(列)」がある表なので、2重ループと相性バツグンです。

  • 外側の for:1段、2段、…、9段(行)を担当
  • 内側の for:×1、×2、…、×9(列)を担当

i と j の役割

変数役割変化のしかた
i行(段)1 → 2 → … → 93段目なら i = 3
j列(掛ける数)1 → 2 → … → 9(毎行リセット)×4なら j = 4

j は i が変わるたびに 1 に戻る」ここが2重ループの大事ポイントです。

for文の書式と意味を整理

for文の書式

for (初期化; 継続条件; 更新) {
    文;
}

for文の3要素

部分何をする?九九の例
初期化最初に1回だけ準備するint i = 1
継続条件真(0以外)の間だけ繰り返すi <= 9
更新1回ごとに状態を進めるi++

内側の for も同じ仕組みで、j を 1〜9 に動かしていきます。

printf と putchar の役割:表を“見やすく”する工夫

九九表が「表っぽく」見えるのは、表示を揃える工夫があるからです。

printf の書式指定

  • %d は整数の表示
  • %3d は 最低3桁幅で表示(足りない分は左に空白)

これで 1 も 81 も同じ幅で出るので、縦にそろいます。

putchar の書式

putchar(文字);
  • 文字を1つだけ表示する関数
  • putchar('\n') は改行

このプログラムで登場する命令(関数)

命令(関数)書式何をする?
putsputs(文字列);文字列を表示し、最後に改行する
printfprintf(書式, 値, ...);値を整形して表示する
putcharputchar(文字);文字を1つ表示する

九九表を作る処理の流れ(文章での図解)

九九表は次の流れで作られています。

外側ループ(i = 1〜9) = 行を作る
  内側ループ(j = 1〜9)= その行に 9 個の値を並べる
    i*j を表示
  内側が終わったら改行(次の行へ)

「内側で横に並べて、外側で縦に積む」
これが2重ループの超基本イメージです。

よくあるミス:改行の位置を間違えると表が崩れる

改行が内側にあるとどうなる?

for (int i = 1; i <= 9; i++) {
    for (int j = 1; j <= 9; j++) {
        printf("%3d", i * j);
        putchar('\n');   // ここにあると1個出すたびに改行される
    }
}

これだと、表じゃなくて縦に長いリストになります。
改行は内側が終わってからが鉄則です。