トラック8・🗃️配列

配列とループの黄金コンビ

読む目安 約12分・ゴール:forループで配列全体を走査でき、要素数を安全に管理できる

アプリでこのトピックを学ぶ(無料・登録不要)

このトピックの要点

配列とfor文は、Cでいちばん出番の多い組み合わせです。「同じ処理を、全要素に対して」というパターンは、この形にすべて収まります。

for (int i = 0; i < n; i++) {
    // a[i] に対する処理
}

この5行が体に入ると、合計・平均・最大値・検索・並べ替えまで、ほとんどの処理が同じ骨格で書けるようになります。中身を差し替えるだけで、やれることが次々に増えるからです。

骨格が同じなので、毎回考えるのは「中身」だけになります。t08-08では、この型を3つ正確な形で身につけます。

#include <stdio.h>

int main(void)
{
    int a[5] = {60, 85, 40, 90, 75};
    int sum = 0;

    for (int i = 0; i < 5; i++) {
        sum += a[i];
    }
    printf("合計 %d / 平均 %.1f\n", sum, (double)sum / 5);
    return 0;
}

sum をループの外で宣言しているところに注目してください。中で宣言すると毎回 0 に戻ってしまい、合計になりません。

要素数を1か所で管理する

上のコードには 5 が3か所(宣言・ループ・平均)に散らばっています。人数が6人になったとき、1か所でも直し忘れると事故です。要素数には名前を付けましょう。

#include <stdio.h>

#define N 5      // 要素数に名前を付ける

int main(void)
{
    int a[N] = {60, 85, 40, 90, 75};
    int sum = 0;

    for (int i = 0; i < N; i++) {
        sum += a[i];
    }
    printf("平均 %.1f\n", (double)sum / N);
    return 0;
}

もうひとつ、配列そのものから要素数を計算する定石もあります。

int n = sizeof(a) / sizeof(a[0]);

「全体の大きさ ÷ 1個の大きさ = 個数」という素直な計算です。ただしこれが使えるのは配列を宣言した関数の中だけで、配列を関数に渡した先では使えません。理由は t08-07 で説明します。

なぜ要素数が散らばると危ないのか

配列の宣言は [5] のまま、ループだけ i < 6 に書き換えてしまった——この一手で、プログラムは静かに壊れます。しかも運が良ければ動いてしまうので、テストをすり抜けることがあります。数字を1か所にまとめるのは、単なる整理整頓ではなく安全対策なのです。

while文でも書ける

添字を自分で進める書き方もできますが、初期化・条件・更新が1行にまとまる for のほうが、範囲の間違いに気づきやすくなります。配列の走査は for が基本と覚えておきましょう。

罠・注意

ビット「配列を見たらfor」。この反射ができれば、もう半分マスターだよ

なお、配列の一部だけを処理したいときも同じ形です。開始と終了を変えるだけで、for (int i = 2; i < 5; i++) なら3番目から5番目まで、といった具合に自由に切り取れます。その場合も、両端が 0 と n−1 の内側に収まっているかを必ず確かめてください。

まとめ: for (int i = 0; i < n; i++) が配列処理の基本形。要素数は1か所で管理し、合計用の変数はループの外に置く。

アプリでこのトピックを学ぶ(無料・登録不要)

確認問題

確認問題 1

int a[5]; に対する sizeof(a) / sizeof(a[0]) は何を求めていますか。

  1. 配列全体のバイト数
  2. 配列の要素数
  3. 配列の先頭の値
  4. int型のバイト数
答えを見る

正解:B(配列の要素数)

「全体の大きさ ÷ 1要素の大きさ」なので要素数(この例では5)が求まります。ただしこの計算が使えるのは配列を宣言した関数の中だけで、配列を関数に渡した先では正しい値になりません。

確認問題 2

ループを1周ずつ追って、空欄を埋めてください。sum欄はその周が終わった時点の値です。

#include <stdio.h>

int main(void)
{
    int a[4] = {2, 4, 6, 8};
    int sum = 0;

    for (int i = 0; i < 4; i++) {
        sum += a[i];
    }
    printf("%d\n", sum);
    return 0;
}
周ia[i]sum
1周目022
2周目14?
3周目2?12
4周目38?
答えを見る

空欄の答え(上から順に):6、6、20

sum は 0 から始まり、2 → 6 → 12 → 20 と増えます。3周目の a[2] は 6 です。sum をループの外で宣言しているので、周をまたいで値が積み上がります。

「配列」の目次

  1. 配列とは——箱の行列
  2. 添字と0始まりの理由
  3. 配列とループの黄金コンビ
  4. 境界外アクセスという重大事故
  5. 配列の初期化いろいろ
  6. 多次元配列
  7. 配列を関数に渡す——入口編
  8. 集計・最大値・検索の定石

もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。

完全版の販売ページは準備中です。

ほかのトラック

📚 姉妹教材:手を動かして覚える Linux 教材 — Linuxとインフラの仕組みを地図で学ぶ

Web版