C言語基礎|配列のしくみ

「配列のしくみ」序章(導入)

C言語を勉強していると、こんな場面がよく出てきます。

  • 5人(あるいは300人!)分の点数をまとめて扱いたい。
  • 1週間分の売上、12か月分の気温、100個のセンサー値…「同じ種類のデータ」がズラッと並ぶ。
  • 「何番目?」で指定して、繰り返し処理で一気に計算したい。

もし毎回 tensu1, tensu2, tensu3... みたいに変数を増やしていくと、書くのもしんどいし、管理もミスりやすいんですよね。
そこで登場するのが 配列(array) です。配列を使うと、同じ型のデータを“ひとまとめ”にして、番号(添字)でスイスイ扱える ようになります。

まず結論:配列ってなに?

配列を一言でいうと、こうです。

同一型の変数(要素)が、直線状に連続して並んだもの

「要素(element)」=配列の中に入っている1個1個の値、と思ってOKです。

例:変数を5個並べると何がつらい?

たとえば「5日分の売上(杯数)」を入力して合計と平均を出したいとします。

方法書き方の雰囲気人数/日数が増えたら
変数を個別に用意cup1, cup2, cup3...変数が増殖して地獄になりがち。
配列を使うcups[0] ~ cups[4]300個でも同じ書き方で回せる。

配列の強さはここで、同じ処理を「繰り返し」でまとめられるのが超重要ポイントです。

サンプルプログラム

やること

  • 5日分の「カフェの売上杯数」を入力
  • 合計と平均を表示

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

Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。

// 5日分の売上(杯数)を読み込んで合計と平均を表示
#include <stdio.h>

int main(void)
{
    int cups[5];       // 5日分の売上(杯数)
    int sum = 0;       // 合計
    int i;             // ループ用

    printf("5日分の売上(杯数)を入力してください。\n");

    for (i = 0; i < 5; i++) {
        printf("%d日目:", i + 1);
        scanf("%d", &cups[i]);
        sum += cups[i];
    }

    printf("合計杯数:%d\n", sum);
    printf("平均杯数:%.1f\n", (double)sum / 5);

    return 0;
}

実行例

5日分の売上(杯数)を入力してください。
1日目:83
2日目:95
3日目:85
4日目:63
5日目:89
合計杯数:415
平均杯数:83.0

このプログラムで出てきた“配列の道具箱”

➀ 配列の宣言(使うための準備)

配列は次の形で宣言します。

目的書式
要素型・配列名・要素数を指定して作る要素型 配列名[要素数];int a[5];

今回の例では、

  • 要素型:int
  • 配列名:cups
  • 要素数:5

なので int cups[5]; です。

要素数は「定数式」が原則ってどういう意味?

この章の基本としては、要素数は 5 や 100 のようにコンパイル時に決まる値にする、という考え方です。
(Cでは条件次第で実行時に決まる可変長配列もありますが、まずは“固定サイズ”でしっかり身につけるのが安心です。)

➁ 添字(index)— 番号は 0 から始まる

配列は 添字 で要素を指定します。

用語意味
先頭要素添字 0cups[0]
末尾要素添字(要素数 - 1)cups[4](要素数5なら)

ここ、めちゃ大事です。
要素数が5でも、添字は 0~4 です。

➂ 図でイメージ:配列は「連続して並ぶ」

int a[5]; を作ると、イメージはこんな感じです。

さらに “連続している” をメモリっぽく描くと

つまり配列は、同じ型の箱がズラッと等間隔で並ぶ感じです。

ループで処理が一気にラクになる理由

今回、入力と合計計算はこの部分でまとめています。

  • for (i = 0; i < 5; i++) で i を 0 から 4 まで動かす
  • cups[i] で「i番目の要素」にアクセスする
i の値指す要素画面表示の「◯日目」
0cups[0]1日目
1cups[1]2日目
2cups[2]3日目
3cups[3]4日目
4cups[4]5日目

この仕組みのおかげで、たとえば「30日分」に増やしても、

  • 配列の要素数
  • ループ回数

を変えるだけで対応しやすくなります。

+= は「左辺に右辺を加えて、左辺に戻す」

sum += cups[i]; は次と同じ意味です。

書き方意味
sum += cups[i];sum = sum + cups[i];

「合計に足し込む」定番の書き方なので、手に馴染ませると強いです。

平均で (double) を付けている理由(超重要)

(double)sum / 5 になっているのは、小数つき平均をちゃんと出すためです。

書き方起きること
sum / 5どっちも整数なので、割り算結果が整数になり小数が切り捨てられる。
(double)sum / 5sum を double に変えてから割るので、小数も保持できる。

つまり (double) は 型変換(キャスト) で、計算の種類を「実数計算」に寄せるための合図です。

scanf と &cups[i] の意味

scanf("%d", &cups[i]); の & は「アドレスを渡す」ために使います。

部品役割
cups[i]i番目の要素そのもの
&cups[i]i番目の要素の“場所”(アドレス)
scanf入力された数値を、その場所に書き込む

配列の要素も、普通の変数と同じく「箱」なので、scanf には 箱の場所 を教えてあげる必要がある、という感覚です。

ありがちなミス:範囲外アクセス(添字の暴走)

配列で怖いのはこれです。

ミス何が起きる?
添字が範囲外cups[5] に入れる配列の外のメモリを壊す可能性がある(バグの温床)
ループ条件ミスi <= 5 で回す最後に i=5 になって範囲外に触れる

安全の基本は 0 以上、要素数未満(i < 要素数)です。

最後に:この記事でつかむべき感覚

  • 配列は「同じ型の箱が連続で並んだセット」
  • 添字は 0 から始まり、末尾は 要素数 - 1
  • for と組むと、「同じ処理」を短く・正確に書ける。
  • += は合計などの“足し込み”で頻出
  • 平均など小数が必要なら、キャストで実数計算にする。

ここが腹落ちすると、次に出てくる「配列とループ」「配列の初期化」「文字列(char配列)」が一気に読みやすくなります。