
C言語で複数の同じ型のデータを扱うとき、配列はとても便利な仕組みだ。たとえば、3人の年齢をそれぞれ別の変数に格納するよりも、int ages[3]; のように配列でまとめたほうがすっきりする。配列を使えば、変数名に連番をつける必要がなく、ループでまとめて処理できる。
配列とは
配列は「同じ種類のデータをひとつにまとめた箱の列」と考えるとイメージしやすい。各要素は0番から順に並び、好きな位置を数字(添字)で指定してアクセスできる。C言語ではこの添字を使って、ages[0] のように特定の要素にアクセスする。
配列を使うと、コードの見通しがよくなるだけでなく、ミスを減らせる。データ数が多いときや繰り返し処理が必要な場面では、ループとの相性がいい。for文と組み合わせれば、10人分の得点や毎月の売上なども簡単に扱えるようになる。
配列は同じ型の値しか入れられない決まりがある。整数、文字、浮動小数点数など、ひとつの配列には必ず統一された型の値だけを並べる。異なる型を混ぜることはできないので注意が必要だ。
実際のプログラムでは、ユーザーからの入力や計算結果を一時的に記録しておく用途でも配列はよく使われる。ゲームのスコアを保存したり、センサーの値を記録したりと、使い道は多い。C言語の初学者にとって、配列は避けて通れない基本中の基本といえる。
配列の宣言と初期化の具体例
配列を使うには、まず宣言が必要だ。宣言では、どの型のデータをいくつ並べるのかを指定する。整数型(int)の配列で5個のデータを格納したい場合は
int numbers[5];
のように書く。これで、numbers[0] numbers[1] numbers[2] numbers[3] numbers[4] の5つの要素が使えるようになる。C言語では添字が0から始まる点に注意が必要だ。
配列を宣言と同時に初期化する方法もある。
int vals[3] = {10, 20, 30};とすれば、最初の3つの要素に順に値が代入される。このように初期値を並べるだけで、個別に代入しなくてもよい。もし初期値の数が配列の要素数より少なければ、残りは0で埋められる。逆に、初期値が多すぎるとコンパイルエラーになる。
文字配列char型では、文字列を扱うための工夫が必要だ。たとえば、
char name[6] = "Japan";
のように書くと、5文字のあとに終端を示すヌル文字(’\0’)が自動的に追加される。これは、C言語で文字列を正しく扱うために欠かせない知識だ。配列サイズが文字数ぴったりだと、ヌル文字の分が足りず、意図しない動作をすることがあるため、文字列を格納する配列には、必ずヌル文字のための1文字分の余裕を持たせるのが基本だ。
char型でも個別の文字を初期化することはできる。
char grade[5] = {'A', 'B', 'C', 'D', 'F'};
のようにすれば、1文字ずつ指定できる。ただしこの配列は文字列ではなく、単なる文字の集まりとして扱われる。文字列として使いたいなら、最後に’\0’を付ける必要がある。
このように、配列はデータ型ごとに基本ルールが決まっており、初期化の書き方もそれに応じて変わる。整数や浮動小数点数の配列では、ヌル文字のような終端記号は不要だが、文字列を扱う配列ではヌル文字の扱いを正しく理解しておく。こうしたルールを押さえておけば、配列を使ったバグを避けやすくなる。
配列に値を代入する2つの方法
配列に値を入れる方法には、大きく分けて2つある。ひとつは宣言と同時に初期値を代入する方法、もうひとつはforループなどを使って後から値を代入する方法だ。
最もシンプルなのが初期化時にまとめて代入する方法だ。たとえば以下のように書く。
int scores[5] = {80, 90, 75, 60, 85};このように波括弧 {} の中に値を並べるだけで、それぞれの要素に順に代入される。scores[0] には80、scores[1] には90、という具合だ。この方法は、最初から全ての値が決まっているときに便利で、コードも簡潔になる。
一方、実行時にユーザーから値を受け取って配列に格納したい場合は、forループを使う方法が有効だ。たとえば、5人分の点数を入力してもらう場合は、次のようなコードになる。
int scores[5];
for (int i = 0; i < 5; i++) {
printf("scores[%d]を入力してください: ", i);
scanf("%d", &scores[i]);
}#include <stdio.h>
int main(void) {
int scores[5];
for (int i = 0; i < 5; i++) {
printf("scores[%d]を入力してください: ", i);
scanf("%d", &scores[i]);
}
// 入力された値を確認のために出力
printf("入力されたscoresの値:\n");
for (int i = 0; i < 5; i++) {
printf("scores[%d] = %d\n", i, scores[i]);
}
return 0;
}このコードでは、ループを使って0番目から4番目まで順に配列の各要素に値を代入している。配列の添字をインデックスとして使うことで、複数のデータを簡単に処理できるのがポイントだ。
このように、配列への代入は静的にも動的にも可能であり柔軟に使い分けられる。ユーザー入力を処理するプログラムでは、ループと組み合わせることで真価を発揮する。
C言語における配列のサイズとバッファの安全性
C言語では、配列のサイズを超えてアクセスするとメモリ破壊が起きる可能性がある。これは「バッファオーバーラン」と呼ばれる典型的なバグで、プログラムが異常終了したり、セキュリティ上の脆弱性につながる危険がある。
たとえば
int a[5];
と定義した配列に対して、
a[5] = 100;
のように書くと未定義動作になる。これは5番目の要素(6個目)にアクセスしていることになり、a[0]〜a[4]までの範囲外だ。C言語ではこうしたアクセスをコンパイラが自動で検出してくれないため、プログラマが自分でサイズ管理をする必要がある。
安全に使うためには、sizeof演算子が役立つ。たとえば配列の要素数は、次のようにして求められる。
int a[5];
int length = sizeof(a) / sizeof(a[0]); // length = 5この式は、配列全体のバイト数を要素1つ分のサイズで割っている。特に関数内で静的に定義された配列に対しては有効で、安全なループ制御などに使える。
また、配列全体をゼロで初期化したい場合は、= {0}を使うのが一般的だ。
int buffer[100] = {0};このように書くと、最初の要素だけでなく残りのすべての要素も自動的にゼロになる。配列を使う前に中身を明示的に初期化しておくことで、ゴミデータによるバグを未然に防ぐことができる。
C言語では便利な反面、配列の取り扱いを誤ると簡単に深刻な不具合が生じる。そのため、サイズの明確化と初期化の徹底が、安全なコーディングの基本といえる。
実践:スコア入力と平均計算を行う配列プログラム
配列の理解を深めるには、実践的なプログラムに触れるのが効果的だ。ここではスポーツの得点を入力して、平均スコアを計算する簡単なサンプルを紹介する。
まず、得点を保存するための配列を用意し、ユーザーからの入力を順に代入する。
#include <stdio.h>
int main(void) {
int scores[5] = {0}; // 配列を初期化
int i;
int sum = 0;
double average;
printf("5人分のスコアを入力してください。\n");
for (i = 0; i < 5; i++) {
printf("%d人目のスコア: ", i + 1);
scanf("%d", &scores[i]);
sum += scores[i]; // 合計を計算
}
average = (double)sum / 5; // 整数→浮動小数点へ型変換
printf("平均スコアは %.2f です。\n", average);
return 0;
}このプログラムでは、scores 配列を {0} で初期化し、forループを使って scanf()で値を入力している。入力されたスコアは sum に加算され、最終的に average に平均値として格納される。
ここで重要なのが、整数の合計を浮動小数点で割るときの型変換である。sum が int 型のままだと、整数同士の除算になり小数点以下が切り捨てられてしまう。そのため、(double)sum のように 明示的にキャストして、浮動小数点として割り算を行っている。
このように、配列とループ、型変換を組み合わせることで、現実的な処理を安全かつ正確に行うことができる。平均値や統計処理では浮動小数点の扱いが欠かせないため、型の使い分けにも注意しておこう。
よくある配列のミスとその防止策
C言語の配列では、初心者が陥りやすいミスがいくつか存在する。代表的なものと、その対策を以下に紹介する。
まず多いのが初期化忘れだ。未初期化の配列には不定値が入っており、計算結果に影響を及ぼす。{0}での初期化や、ループで明示的に値を入れることで防げる。
次に、添字の範囲外アクセスが挙げられる。C言語では境界チェックが自動で行われないため、定義したサイズ以上のインデックスを使うとメモリ破壊が起こり得る。ループでは 「i < 配列サイズ」の条件を厳守することが大切だ。
また、文字列と文字の配列の混同もよくある。たとえば
char name[10] = "Tanaka";
のような代入では、終端の \0(ヌル文字)も含めて文字数を数える必要がある。必要なサイズを見積もる際には strlen() + 1 を意識しよう。
これらのミスは、コードの見直しとテストの徹底によって未然に防ぐことができる。配列は便利だが、使い方を誤るとバグの温床にもなるため、基本を丁寧に守ることが肝心だ。



