配列とfor
添字を変数にできるのが配列の本当の価値
前回は scores[0] scores[2] のように、添字を直接書いて取り出しました。しかし配列がありがたいのは、添字に 変数を書ける ところです。
int i = 2;
printf("%d\n", scores[i]);変数を書けるということは、第4章で学んだ for の変数 i をそのまま添字にできるということです。5個でも100個でも、書くコードの量は変わりません。
int scores[5] = {80, 65, 92, 74, 58};
for (int i = 0; i < 5; i++) {
printf("%d科目目 %d点\n", i + 1, scores[i]);
}i は 0 から 4 まで動き、そのまま scores[i] の添字になります。人に見せる番号は1から始めたいので、表示のときだけ i + 1 にしています。内部の番号と、人に見せる番号を分けて考えるのがコツです。
条件は「以下」ではなく「未満」で書く
ループの条件は i <= 5 ではなく i < 5 です。i <= 5 にすると i が 5 のときにも回ってしまい、存在しない scores[5] を読みます。前回話したとおり C は止めてくれないので、ゴミの値が表示されたり、まれにプログラムが落ちたりします。
要素数を n とすると、条件は必ず i < n になります。この形をそのまま覚えてしまってかまいません。1つずれる間違いは、初学者だけでなく実務でも最も多いバグのひとつです。
入力もループで回す
表示だけでなく、入力も同じ形で書けます。
for (int i = 0; i < 5; i++) {
scanf("%d", &scores[i]);
}scanf には & が要るのは第2章のとおりです。scores[i] は int の箱1つなので、ふつうの int 変数と同じように &scores[i] と書きます。
入力のループと表示のループは分けて書きます。まとめてしまうと、全部入力し終わってから一覧を出す、という形にできなくなるからです。
個数を1か所にまとめる
5 という数がコードのあちこちに出てくると、6科目に増やすときの直し忘れが起きます。定数にしておくと1か所で済みます。
#define SUBJECTS 5
int scores[SUBJECTS];
for (int i = 0; i < SUBJECTS; i++) { ... }#define は、コンパイル前に名前を値へ置き換える指示です。#include と同じ仲間で、行の終わりにセミコロンは付けません。
では、入力と表示の2つのループを書いてみましょう。
要件
- 5つの整数を配列 scores に読み込む
- 1科目目 80点 の形で5行表示する
- 表示は for で回す。printf を5行並べない
入出力例
main("80 65 92 74 58") → "1科目目 80点
2科目目 65点
3科目目 92点
4科目目 74点
5科目目 58点"
main("60 70 80 90 100") → "1科目目 60点
2科目目 70点
3科目目 80点
4科目目 90点
5科目目 100点"