プログラムで同じ種類の値がたくさん出てくると、変数を1つずつ用意するのは大変です。
C言語の配列は、同じ型の値を連続した箱に並べてまとめて扱える仕組みです。
本記事では、配列の考え方、宣言のコツ、役立つ場面、そして初心者がつまずきやすい注意点をやさしく解説します。
C言語の配列とは
配列の基本イメージと用語
配列は、同じ型の値を、0から始まる連番の位置(インデックス)で並べたデータの集合です。
配列の各位置に入っている1つ1つの値を要素と呼び、配列名とインデックスを使ってアクセスします。
C言語では要素はメモリ上で連続して配置されます。
用語の整理
用語 | 意味 |
---|---|
配列 | 同じ型の要素を順に並べたもの |
要素 | 配列の中の1つの値 |
添字(インデックス) | 要素の位置を示す番号。0から開始 |
要素数(長さ) | 配列に入る要素の数。最大インデックスは要素数-1 |
配列名 | 配列を識別する名前 |
イメージ図
5個のint型が並んだ配列int a[5]
のイメージです。
左から右へインデックスが増えます。
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e0f7fa', 'lineColor': '#006064', 'textColor': '#000000'}}}%% graph LR A0["a[0]"]:::cell --> A1["a[1]"]:::cell --> A2["a[2]"]:::cell --> A3["a[3]"]:::cell --> A4["a[4]"]:::cell classDef cell fill:#e0f7fa,stroke:#006064,stroke-width:2px;
有効なインデックスは0~4です。
5は含みません。
C言語 配列がない場合の不便さ
配列が無い前提で、5人分の点数を扱って平均を出す例を考えます。
変数を5個用意し、入力や計算を同じように繰り返す必要があります。
サンプルコード(配列を使わない例)
#include <stdio.h>
int main(void) {
// 5人分の点数を別々の変数で管理する
int s1, s2, s3, s4, s5;
printf("5人分の点数を入力してください(例: 70 82 91 65 77): ");
scanf("%d %d %d %d %d", &s1, &s2, &s3, &s4, &s5);
// 変数名を都度書かなければならない
int sum = s1 + s2 + s3 + s4 + s5;
double avg = sum / 5.0;
printf("入力: %d %d %d %d %d\n", s1, s2, s3, s4, s5);
printf("合計: %d\n", sum);
printf("平均: %.2f\n", avg);
return 0;
}
5人分の点数を入力してください(例: 70 82 91 65 77): 70 82 91 65 77
入力: 70 82 91 65 77
合計: 385
平均: 77.00
このように、人数が6人、10人、20人と増えるたびにコードを書き換える必要があり、間違いも起こりやすくなります。
変数との違いと使い分け
単一の値を扱うときは通常の変数、同じ種類の値が複数あるときは配列が向いています。
配列は値の「まとまり」を明示でき、繰り返し処理と組み合わせると簡潔に書けるのが特長です。
観点 | 変数 | 配列 |
---|---|---|
保持できる値 | 1つ | 同じ型の複数 |
アクセス方法 | 名前のみ | 配列名 + 添字(例:a[0] ) |
適した用途 | 単独の値(旗フラグ、カウンタなど) | 同種データの集合(成績、測定値、日ごとの統計など) |
コードの見通し | 数が増えると冗長になりやすい | ループで簡潔に書ける |
C言語 配列のメリット
配列を使うと、以下のような利点があります。
特に初学者にとっては、「追加や変更に強いコード」を書けることが大きなメリットです。
- 同じ型のデータを1つの名前で一括管理できるため、データ構造が明確になります。
for
などの繰り返しで、入力、表示、集計がすっきり書けます。- 要素数の変更が、ループ条件や定数の調整だけで済むことが多く、修正漏れが減ります。
配列の宣言の考え方
C言語 配列の宣言は「型+要素数」
配列の宣言は基本形が決まっています。
型名 配列名[要素数]です。
宣言の書式と例
- 書式:
型名 配列名[要素数];
- 例:
int scores[5];
(int型の要素が5個の配列)
#include <stdio.h>
int main(void) {
int scores[5]; // 5人分の点数
double prices[3]; // 3つの価格
char flags[8]; // 8個のフラグ(0/1などの小さな値を入れるのにも使える)
// 要素への代入(配列は0から始まる)
scores[0] = 80;
scores[1] = 75;
printf("scores[0]=%d, scores[1]=%d\n", scores[0], scores[1]);
return 0;
}
scores[0]=80, scores[1]=75
要素数は初学者のうちは定数で指定するのが安全です。
必要に応じて#define
やenum
で定数化すると、後で変更しやすくなります。
インデックスは0から始まる
C言語の配列は0から始まり、要素数-1が最後のインデックスです。
これを前提にループ条件を組み立てます。
サンプルコード(0始まりの確認)
#include <stdio.h>
int main(void) {
int i;
int a[5]; // 5要素: 有効な添字は0,1,2,3,4
// それぞれに10, 20, 30, 40, 50を代入
for (i = 0; i < 5; i++) {
a[i] = (i + 1) * 10; // i=0→10, i=1→20, ...
}
// 値を表示
for (i = 0; i < 5; i++) {
printf("a[%d] = %d\n", i, a[i]);
}
return 0;
}
a[0] = 10
a[1] = 20
a[2] = 30
a[3] = 40
a[4] = 50
よくある配列の例
配列は「同じ意味を持つ複数データ」を並べるのに向いています。
例としては以下のようなものがあります。
例 | 型 | 要素数の目安 | 例示する値 |
---|---|---|---|
学生の点数 | int | クラス人数分 | 0~100 |
1週間の気温 | double | 7 | 23.5, 24.2, … |
月別売上 | long | 12 | 120000, 98000, … |
サンプルコード(1週間の平均気温)
#include <stdio.h>
int main(void) {
// 7日分の気温(度数法)。同じ型(double)の連続した要素を配列で管理
double temp[7] = {23.5, 24.2, 22.8, 25.1, 26.0, 24.7, 23.9};
int i;
double sum = 0.0;
for (i = 0; i < 7; i++) {
sum += temp[i];
}
printf("平均気温: %.2f\n", sum / 7.0);
return 0;
}
平均気温: 24.60
配列が役立つ場面と使いどころ
複数の入力をまとめて扱う
ユーザーから複数の値を受け取る処理は、配列とループで簡潔に書けます。
要素数の変更にも強い構造になります。
サンプルコード(5個の整数を入力→表示と合計)
#include <stdio.h>
#define N 5 // 入力する個数。ここを変えるだけで拡張しやすい
int main(void) {
int nums[N];
int i;
int sum = 0;
printf("%d個の整数をスペース区切りで入力してください: ", N);
// 入力: ループで一括して受け取る
for (i = 0; i < N; i++) {
scanf("%d", &nums[i]);
}
// 一覧表示と合計
printf("入力された値: ");
for (i = 0; i < N; i++) {
printf("%d ", nums[i]);
sum += nums[i];
}
printf("\n合計: %d\n", sum);
printf("平均: %.2f\n", sum / (double)N);
return 0;
}
5個の整数をスペース区切りで入力してください: 12 7 19 3 10
入力された値: 12 7 19 3 10
合計: 51
平均: 10.20
一覧表示や集計をシンプルにする
配列があれば、要素を順に処理することで合計、平均、最小値、最大値などを簡潔に求められます。
サンプルコード(点数の一覧、最小・最大・平均)
#include <stdio.h>
int main(void) {
int scores[6] = {75, 88, 92, 64, 83, 79};
int i;
int min = scores[0];
int max = scores[0];
int sum = 0;
printf("点数一覧: ");
for (i = 0; i < 6; i++) {
int s = scores[i];
printf("%d ", s);
if (s < min) min = s;
if (s > max) max = s;
sum += s;
}
printf("\n最小: %d, 最大: %d, 平均: %.2f\n", min, max, sum / 6.0);
return 0;
}
点数一覧: 75 88 92 64 83 79
最小: 64, 最大: 92, 平均: 80.17
繰り返し処理と相性が良い
配列はインデックスを使った規則的な処理に強く、初期化や加工が1本のループで書けます。
要素数の変更も、#define
などの定数を1箇所変えるだけで済みます。
サンプルコード(0~9の2乗を配列に入れて表示)
#include <stdio.h>
#define N 10
int main(void) {
int squares[N];
int i;
// iの2乗を格納
for (i = 0; i < N; i++) {
squares[i] = i * i;
}
// 表示
for (i = 0; i < N; i++) {
printf("squares[%d] = %d\n", i, squares[i]);
}
return 0;
}
squares[0] = 0
squares[1] = 1
squares[2] = 4
squares[3] = 9
squares[4] = 16
squares[5] = 25
squares[6] = 36
squares[7] = 49
squares[8] = 64
squares[9] = 81
初心者が知っておきたい注意点
要素数を超えない
配列の範囲外アクセスは未定義動作です。
C言語は自動で範囲チェックをしません。
クラッシュやデータ破損の原因になるため、添字は必ず0~要素数-1に収めます。
悪い例(範囲外アクセス。実行しないこと)
#include <stdio.h>
int main(void) {
int a[5] = {1, 2, 3, 4, 5};
// a[5] は存在しない(有効範囲は0~4)。未定義動作。
printf("%d\n", a[5]); // ← ダメ: 範囲外
return 0;
}
良い書き方(定数とループ条件で自衛する)
#include <stdio.h>
#define LEN 5
int main(void) {
int a[LEN] = {1, 2, 3, 4, 5};
int i;
for (i = 0; i < LEN; i++) { // i <= LEN はダメ、必ず i < LEN
printf("%d\n", a[i]);
}
return 0;
}
配列のサイズは固定
いったん宣言した配列の要素数は後から変えられません。
例えばint a[5];
をa[10]
に拡張することはできません。
将来の拡張を見越して、上限値を定数で表現しておくと安全です。
必要に応じて#define
やenum
で意味のある名前を付けましょう。
#include <stdio.h>
enum { STUDENT_COUNT = 30 }; // クラスの最大人数を表す定数
int main(void) {
int scores[STUDENT_COUNT]; // 後からサイズは変えられない
// ... 入力や集計の処理 ...
printf("配列の要素数は固定です。サイズは定数で管理しましょう。\n");
return 0;
}
可変長配列や動的確保といったテクニックもありますが、これは別の記事で扱います。
本記事では「固定サイズの配列」を前提にします。
名前付けとコメントで配列の意図を明確に
配列名には中身と単位が伝わる言葉を選び、コメントで「何件分か」を補足しましょう。
保守性が大きく変わります。
良い例 | 悪い例 | 理由 |
---|---|---|
scores, exam_scores | data, arr | 何のデータかが明確か |
temps_celsius | t | 単位が分かるか |
monthly_sales | m | 粒度(単位期間)が分かるか |
サンプルコード(意図が伝わる命名とコメント)
#include <stdio.h>
enum { DAYS = 7 }; // 1週間(7日)分
int main(void) {
double temps_celsius[DAYS]; // 1日ごとの気温(摂氏)
int i;
// 値の投入(例として i + 20.0 を設定)
for (i = 0; i < DAYS; i++) {
temps_celsius[i] = 20.0 + i;
}
// 一覧表示
printf("日次気温(℃): ");
for (i = 0; i < DAYS; i++) {
printf("%.1f ", temps_celsius[i]);
}
printf("\n");
return 0;
}
日次気温(℃): 20.0 21.0 22.0 23.0 24.0 25.0 26.0
配列サイズや意味を表す定数名(例: DAYS
, STUDENT_COUNT
)を併用すると、読む人にも意図が伝わります。
まとめ
配列は、同じ型の複数データを一括管理するための基本的な道具です。
配列名とインデックスで要素にアクセスし、0から始まる添字と固定サイズという性質を理解すれば、入力、一覧表示、集計を繰り返し処理で簡潔に書けます。
特に、定数で要素数を管理する、範囲外アクセスを避ける、意味のある命名といった基本を守ることで、安全で拡張しやすいプログラムになります。
配列の基礎をしっかり押さえ、次のステップ(初期化の工夫、要素アクセスのテクニック、ポインタとの関係など)へ進む準備を整えましょう。