
C言語の基本|1次元配列の基本操作
宣言して、値を入れて、必要な要素を取り出す。1次元配列の基本操作を覚えて、複数のデータをすっきり管理しよう。
1次元配列の基本操作
C言語では、同じ型のデータを複数まとめて扱いたい場面がよくあります。
たとえば、次のようなデータです。
- 5人分の点数
- 7日分の売上
- 10個の商品価格
- 複数地点の測定値
配列を使わずに保存する場合は、データの数だけ変数を用意しなければなりません。
int value1;
int value2;
int value3;
int value4;
int value5;この書き方でも値は保存できますが、変数が増えるほど管理しにくくなります。同じ処理を繰り返したい場合も、それぞれの変数名を個別に指定しなければなりません。
そこで役立つのが1次元配列です。
int values[5];この1行で、int型の値を5個保存するための領域をまとめて用意できます。それぞれの要素には添字という番号が付いているため、必要な場所を指定して値を代入したり参照したりできます。
1次元配列の基本操作は、大きく分けると次の3つです。
- 配列を宣言する
- 要素に値を代入する
- 要素を参照する
この3つの操作と、添字が0から始まるルールを理解すれば、配列の基本的なコードを読み書きできるようになります。
1次元配列とは
1次元配列は、同じ型のデータを一列に並べて保存する仕組みです。
番号の付いた箱が横一列に並び、それぞれの箱に値を保存するイメージを持つと分かりやすいでしょう。
配列を構成する一つひとつの保存場所を要素と呼びます。また、要素の位置を表す番号を添字と呼びます。
C言語では、添字は0から始まります。
たとえば、int型の要素を5個持つ配列は、次のように宣言します。
int values[5];この配列には、次の5つの要素があります。
values[0]
values[1]
values[2]
values[3]
values[4]1番目の要素はvalues[0]です。values[1]は2番目の要素を表します。
図1:1次元配列を構成する5つの要素

この図から分かること
配列valuesには、int型の要素が5個あります。
要素の位置と添字の対応は次のとおりです。
| 要素の位置 | 添字 | 要素の指定 |
|---|---|---|
| 1番目 | 0 | values[0] |
| 2番目 | 1 | values[1] |
| 3番目 | 2 | values[2] |
| 4番目 | 3 | values[3] |
| 5番目 | 4 | values[4] |
要素数は5ですが、最後の添字は4です。要素数と最後の添字を混同しないようにしましょう。
1次元配列を宣言する
1次元配列を使うには、最初に配列を宣言します。
基本的な文法は次のとおりです。
型名 配列名[要素数];各部分には、次の意味があります。
| 項目 | 内容 |
|---|---|
| 型名 | 各要素に保存するデータの型 |
| 配列名 | 配列に付ける名前 |
| 要素数 | 配列が持つ要素の個数 |
整数を5個保存する配列scoresなら、次のように宣言します。
int scores[5];この宣言によって、int型の値を5個保存できる配列scoresが用意されます。
ほかの型でも、同じ形で宣言できます。
| 宣言 | 内容 |
|---|---|
| int scores[5]; | int型の要素を5個持つ |
| double prices[8]; | double型の要素を8個持つ |
| char letters[10]; | char型の要素を10個持つ |
1つの配列に保存する要素は、すべて同じ型です。int型の配列へはint型の値、double型の配列へはdouble型の値を保存します。
宣言しただけでは要素の値は決まらない
関数内で次のように配列を宣言しただけでは、各要素の値は初期化されていません。
int scores[5];この時点の状態は、次のように考えられます。
| 要素 | 状態 |
|---|---|
| scores[0] | 不定値 |
| scores[1] | 不定値 |
| scores[2] | 不定値 |
| scores[3] | 不定値 |
| scores[4] | 不定値 |
不定値とは、使用できる値が設定されていない状態です。不定値の要素を参照してはいけません。
安全に使うためには、値を参照する前に次のどちらかを行います。
- 各要素へ値を代入する
- 宣言と同時に配列を初期化する
宣言したことと、値を設定したことは別の操作です。
要素数と添字の違い
配列を扱うときは、要素数と添字を区別する必要があります。
int scores[5];この配列の要素数は5ですが、使用できる添字は0から4です。
| 項目 | 値 |
|---|---|
| 要素数 | 5 |
| 最初の添字 | 0 |
| 最後の添字 | 4 |
一般的には、要素数がnなら使用できる添字は0からn - 1です。
| 要素数 | 使用できる添字 |
|---|---|
| 1 | 0 |
| 3 | 0~2 |
| 5 | 0~4 |
| 10 | 0~9 |
要素数5の配列でscores[5]を指定すると、6番目の要素を使おうとすることになります。これは配列の範囲外です。
1次元配列の要素に値を代入する
宣言した配列には、添字を使って要素ごとに値を代入します。
基本的な形は次のとおりです。
配列名[添字] = 値;たとえば、配列scoresの先頭から3つの要素へ値を代入する場合は、次のように書きます。
scores[0] = 85;
scores[1] = 92;
scores[2] = 78;それぞれの文には、次の意味があります。
| 代入 | 内容 |
|---|---|
| scores[0] = 85; | 1番目の要素に85を代入する |
| scores[1] = 92; | 2番目の要素に92を代入する |
| scores[2] = 78; | 3番目の要素に78を代入する |
配列全体ではなく、添字で指定した1つの要素へ値を入れています。
一部の要素だけに代入した場合
次のコードでは、5個ある要素のうち、先頭から3個だけに値を代入しています。
int scores[5];
scores[0] = 85;
scores[1] = 92;
scores[2] = 78;代入後の状態は次のとおりです。
| 要素 | 値または状態 |
|---|---|
| scores[0] | 85 |
| scores[1] | 92 |
| scores[2] | 78 |
| scores[3] | 不定値 |
| scores[4] | 不定値 |
値を代入した要素だけが使用できる状態になります。scores[3]とscores[4]には値を設定していないため、まだ参照してはいけません。
配列を宣言したからといって、すべての要素へ同じ値が自動的に入るわけではありません。
図2:代入済みの要素と不定値の要素

この図から分かること
配列の一部へ値を代入しても、ほかの要素まで自動的に初期化されるわけではありません。
図では、levels[0]からlevels[2]までに値が入っています。一方、levels[3]とlevels[4]には値を代入していないため、不定値のままです。
配列を安全に使うには、どの要素に値を設定したかを把握しておく必要があります。
1次元配列の要素を参照する
配列に保存した値を取り出して使うことを、要素の参照といいます。
要素を参照するときも、配列名と添字を使います。
配列名[添字]たとえば、scores[0]に保存されている値を表示するなら、次のように書きます。
printf("%d\n", scores[0]);複数の要素を順番に表示する場合は、次のように記述できます。
printf("%d\n", scores[0]);
printf("%d\n", scores[1]);
printf("%d\n", scores[2]);scores[0]、scores[1]、scores[2]は、それぞれ1つのint型の値として扱われます。
配列要素は普通の変数のように使える
添字で指定した配列要素は、普通の変数と同じように計算や代入に使えます。
たとえば、2つの要素を加算できます。
int total;
total = scores[0] + scores[1];scores[0]が85、scores[1]が92なら、totalには177が代入されます。
要素の値を変更することもできます。
scores[0] = scores[0] + 5;この処理では、scores[0]の値に5を加え、その結果を同じ要素へ代入します。
複合代入演算子を使えば、次のようにも書けます。
scores[0] += 5;配列全体は複数の値のまとまりですが、添字を付けた1つの要素は、普通の変数のように扱えます。
1次元配列の基本操作をプログラムで確認する
ここでは、5地点分の騒音レベルを保存する配列を使います。
配列には5個の要素がありますが、今回は先頭から3個だけに値を代入し、その3個だけを参照します。
3地点分の騒音レベルを配列へ代入して表示するプログラム
ファイル名:10_2_1.c
#include <stdio.h>
int main(void)
{
/* 5地点分の騒音レベルを保存する配列を宣言する */
int levels[5];
/* 先頭から3つの要素に値を代入する */
levels[0] = 42; /* 1地点目 */
levels[1] = 48; /* 2地点目 */
levels[2] = 39; /* 3地点目 */
/* 値を代入した3つの要素を参照して表示する */
printf("%d\n", levels[0]);
printf("%d\n", levels[1]);
printf("%d\n", levels[2]);
return 0;
}実行結果の例
42
48
39配列の宣言を確認する
最初に、次の宣言によって配列levelsを用意しています。
int levels[5];この配列には、int型の要素が5個あります。
levels[0]
levels[1]
levels[2]
levels[3]
levels[4]宣言した直後は、各要素に使用できる値が設定されていません。そのため、値を代入する前にprintfで表示してはいけません。
要素への代入を確認する
次の部分では、先頭から3つの要素へ値を代入しています。
levels[0] = 42;
levels[1] = 48;
levels[2] = 39;対応関係は次のとおりです。
| 地点 | 要素 | 騒音レベル |
|---|---|---|
| 1地点目 | levels[0] | 42 |
| 2地点目 | levels[1] | 48 |
| 3地点目 | levels[2] | 39 |
1地点目をlevels[0]で表している点が重要です。C言語の添字は0から始まります。
要素の参照を確認する
値を表示する部分では、代入済みの要素だけを参照しています。
printf("%d\n", levels[0]);
printf("%d\n", levels[1]);
printf("%d\n", levels[2]);levels[0]には42、levels[1]には48、levels[2]には39が入っているため、これらの値が順番に表示されます。
levels[3]とlevels[4]には値を代入していないので、このプログラムでは参照していません。
宣言・代入・参照の関係
プログラム内の操作を整理すると、次のようになります。
| 操作 | コード | 役割 |
|---|---|---|
| 宣言 | int levels[5]; | int型の要素を5個用意する |
| 代入 | levels[0] = 42; | 1番目の要素へ42を入れる |
| 参照 | printf("%d\n", levels[0]); | 1番目の要素を表示する |
宣言は保存場所を用意する操作です。代入は指定した要素に値を入れる操作です。参照は保存されている値を取り出して使う操作です。
この3つは、それぞれ別の役割を持っています。
初期化との違い
配列には、宣言と同時に値を設定する初期化という書き方もあります。
int levels2[] = {42, 48, 39, 45, 41};この場合は、配列を用意すると同時に、すべての要素へ値が入ります。
| 要素 | 初期値 |
|---|---|
| levels2[0] | 42 |
| levels2[1] | 48 |
| levels2[2] | 39 |
| levels2[3] | 45 |
| levels2[4] | 41 |
初期値が5個あるため、角括弧の中の要素数を省略しても、要素数は5になります。
宣言、代入、初期化の違いは次のとおりです。
| 操作 | 例 | 内容 |
|---|---|---|
| 宣言 | int a[5]; | 配列の保存場所を用意する |
| 代入 | a[0] = 10; | 宣言後に1要素へ値を入れる |
| 初期化 | int a[] = {10, 20, 30}; | 宣言と同時に値を入れる |
今回の中心は宣言、代入、参照ですが、初期化を使えば未設定の要素を減らしやすくなります。
一部だけ初期化した場合
要素数を指定し、初期値を一部だけ書くこともできます。
int data[5] = {10, 20};この場合、残りの要素は0で初期化されます。
| 要素 | 値 |
|---|---|
| data[0] | 10 |
| data[1] | 20 |
| data[2] | 0 |
| data[3] | 0 |
| data[4] | 0 |
配列全体を0で初期化する場合は、次のように書けます。
int data[5] = {0};宣言だけを行う場合と、初期値を指定して宣言する場合では、要素の状態が異なる点を覚えておきましょう。
添字の範囲外へアクセスしてはいけない
配列では、使用できる添字の範囲を必ず守ります。
次の配列では、使用できる添字は0から4です。
int levels[5];次の指定は範囲外です。
levels[5] = 50;
levels[-1] = 30;levels[5]は6番目の要素を指定していますが、配列には5個しか要素がありません。levels[-1]は配列の先頭より前を指定しています。
C言語では、範囲外アクセスをしても、必ずその場で分かりやすいエラーが表示されるとは限りません。ほかのデータを壊したり、実行結果がおかしくなったりする可能性があります。
添字が正しい範囲にある条件は、次のように表せます。
0 <= 添字 && 添字 < 要素数for文と組み合わせて参照する
配列の要素は、for文で添字を変化させながら順番に参照できます。
5個の要素をすべて初期化した配列なら、次のように表示できます。
int levels[] = {42, 48, 39, 45, 41};
for (int i = 0; i < 5; i++) {
printf("%d\n", levels[i]);
}iは0、1、2、3、4と変化します。そのため、次の要素が順番に参照されます。
levels[0]
levels[1]
levels[2]
levels[3]
levels[4]for文の条件がi < 5になっている点が重要です。i <= 5にすると、範囲外のlevels[5]まで参照してしまいます。
図3:宣言・代入・参照の基本的な流れ

この図から分かること
1次元配列の基本操作は、宣言、代入、参照の順番で考えると分かりやすくなります。
- 宣言で要素を保存する場所を用意する
- 代入で指定した要素へ値を入れる
- 参照で保存されている値を取り出して使う
宣言しただけの要素は、不定値のままです。値を代入または初期化してから参照する必要があります。
また、代入と参照のどちらでも添字を使います。添字が配列の範囲内にあることを確認しましょう。
普通の変数と1次元配列を比べる
普通の変数は1つの値を保存します。1次元配列は、同じ型の値を複数保存します。
| 項目 | 普通の変数 | 1次元配列 |
|---|---|---|
| 保存できる値 | 1個 | 複数個 |
| 宣言例 | int level; | int levels[5]; |
| 値の指定 | level | levels[0] |
| 向いている処理 | 単独の値 | 同じ種類の複数データ |
| 繰り返し処理 | 個別の変数名では扱いにくい | 添字を変えて順番に扱える |
配列の各要素は普通の変数と同じように使えますが、どの要素を使うかを添字で指定する点が異なります。
よくある間違いを確認する
1次元配列の基本操作では、次のような間違いが起こりやすくなります。
| 間違い | 正しい考え方 |
|---|---|
| 添字を1から始める | 最初の添字は0 |
| 要素数5なら添字5まで使えると思う | 最後の添字は4 |
| 宣言しただけで値が0になると思う | 関数内で宣言しただけなら不定値 |
| 一部へ代入すれば全要素が使えると思う | 未代入の要素は参照しない |
| levels[5]へ代入する | 要素数5ならlevels[0]~levels[4]を使う |
| 配列名だけで1要素を指定する | 配列名と添字で指定する |
| for文をi <= 要素数で回す | i < 要素数で回す |
特に、要素数と最後の添字の違いは重要です。
要素数が5なら、添字は次の5個です。
0、1、2、3、41次元配列を読むときの確認ポイント
1次元配列を含むプログラムでは、次の順番で確認すると処理を追いやすくなります。
- 配列の型を確認する
- 配列名を確認する
- 要素数を確認する
- 使用できる添字の範囲を確認する
- どの要素に値を代入しているか確認する
- 参照する要素に値が入っているか確認する
- 添字が0から始まっているか確認する
- 範囲外の要素を使用していないか確認する
1次元配列では、配列全体を一度に考えるよりも、添字で指定した1つの要素に注目すると理解しやすくなります。宣言で箱を用意し、代入で値を入れ、参照で取り出すという流れを意識して使いましょう。
