二重ループ(九九)

ループの中にループを置く

成績表を紙に書くところを想像してください。1 人目の行を左から右へ埋めて、改行して 2 人目の行へ移り、また左から右へ埋めます。この「行を進む動き」と「列を進む動き」は別ものなので、ループも 2 つ要ります。外側が行、内側が列です。

ループの中にループを書くことを 入れ子 といいます。書き方は特別ではなく、for の中身にもう 1 つ for を置くだけです。

for (i = 1; i <= 3; i++) { for (j = 1; j <= 4; j++) { printf("%d-%d ", i, j); } printf("\n"); }

内側は毎回ゼロから回り直す

動きを追ってみます。外側の i が 1 になると、内側の j が 1 から 4 まで回りきります。内側が終わって初めて外側の i が 2 に進み、そこで内側の jまた 1 から 回り始めます。

つまり内側の中身は、外側 3 回 × 内側 4 回で合計 12 回動きます。回数がかけ算になるのが入れ子の性質で、外側と内側をそれぞれ 100 回にすると 1 万回になります。手軽に重い処理が書けてしまうので、回数の見積もりは意識してください。

改行の printf("\n") を置く場所も重要です。内側のループの に置くと 1 行ぶんの区切りになり、内側の中に置くと数字が 1 個ずつ縦に並んでしまいます。表を作るときはここが一番の間違いどころです。

ループ変数を使い分ける

外側と内側で同じ変数名を使い回すと、内側が外側のカウンタを壊してしまい、ループが終わらなくなります。外側は i、内側は j と分けるのが C の慣習です。3 重になったら k を使います。

桁をそろえる

表として読ませたいときは、数字の幅をそろえます。第2章で学んだ書式指定に幅を足して %3d と書くと、3 桁ぶんの場所を取り、足りない分は左側が空白で埋まります。1 桁の 1 と 2 桁の 81 が同じ幅になるので、縦の線がきれいにそろいます。

幅を指定しない %d だと、数字の桁数がそのまま列のずれになります。九九なら 1 桁と 2 桁が混ざるので、右へ行くほど列が波打ちます。区切りに空白を 1 つ入れて "%d " と書く手もありますが、これでは桁の違いを吸収できません。成績表のように数字を縦に読ませたい出力では、幅の指定はほとんど必須だと考えてください。

内側の回数を外側で変える

内側のループの条件に、外側の変数を書くこともできます。たとえば for (j = 1; j <= i; j++) とすると、1 段目は 1 個、2 段目は 2 個、と行ごとに個数が変わり、三角形の形になります。九九の表で同じ計算が 2 度出てくる部分を省いた、いわゆる半分の表もこの書き方で作れます。内側の回数は外側ごとに決め直されている、と理解していれば自然に書けます。

では、入れ子の定番である九九の表を作ってみましょう。行が段、列がかける数です。

要件

  1. 1行目に 九九の表 と表示する
  2. 外側のループで段、内側のループでかける数を回す
  3. かけ算の結果は printf("%3d", i * j) の形で表示する
  4. 1つの段を出し終えたら改行する

入出力例

main("") → "九九の表 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"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.c
学習モード

メモ

二重ループ(九九)

⌘S で保存