C言語/配列

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動

配列の基本[編集]

配列(はいれつ)とは、特定の型のオブジェクトの集合を連続して割り付けたものである。[1] 配列を使うことで、 同じ型の複数のデータを、 共通の名前で、添字(そえじ)と呼ばれる番号を用いて、 アクセスすることができる。

例えば、10個の変数の合計を求めるプログラムは、 配列を用いて次のように簡潔に書き換えることができる。

#include <stdio.h>

int main(void)
{
	int i0 = 2, i1=3, i2=5, i3=7, i4=11, i5=13, i6=17, i7=19, i8=23, i9=29;
	int sum;
	sum = i0+i1+i2+i3+i4+i5+i6+i7+i8+i9;
	printf("%d", sum);
}

#include <stdio.h>

int main(void)
{
	int i[10] = {2,3,5,7,11,13,17,19,23,29};
	int sum = 0;
	int n;
	for(n=0; n<10; ++n)
		sum+=i[n];
	printf("%d", sum);
}

配列には、添字が1つの1次元の配列と、 添字が2つ以上の多次元の配列がある。

1次元の配列[編集]

1次元の配列の宣言[編集]

1次元の配列の宣言の記述は次のようになっている。

配列のデータ型 配列名[配列の要素数];

配列のデータ型をデータ型に持って、 配列名を名前に持って、 配列の要素数だけ要素の数を持った配列を宣言する。 配列のデータ型と配列名は、変数の宣言と同様である。 C言語/データ型と変数#データ型と変数の基本を参照せよ。 配列の要素数は、配列の中の要素の数を表す。 要素数は0より大きな整数でなければならない。 [2]

図1
//例 配列を宣言する。
int main(void)
{
	int hairetsu[3]; // int型3つ([0]~[2])の配列を宣言する。※図1
}

上の例では、int型でhairetsuという名前で3つの要素を持つ配列を宣言している。 3つの要素は配列名のあとに[]に囲まれた添字と呼ばれる番号を付けて区別する。 添字は[0]から順番に数え、[配列の要素数-1]までの整数である。 つまりhairetsu[0]、hairetsu[1]、hairetsu[2]というようになる。

また、配列は、宣言と同時に、値のリストで初期化することもできる。 初期化していないローカルな配列の値は不定であり、その値をそのまま参照してはならない。 (値を代入した後になら参照してもよい。) 初期化の記述は次のようになっている。 [3]

配列のデータ型 配列名[配列の要素数]={値のリスト};

値のリストは、コンマで区切った定数のリストである。 値のリストの定数で、対応する配列の要素の値を初期化する。
※値のリストが配列の要素数より多い場合、コンパイルエラーとなる。
※値のリストが配列の要素数より少ない場合、足りない要素は0で初期化される。
※値のリストで初期化するのは、宣言時のみ可能。 宣言後に初期化しようとすると、コンパイルエラーとなる。

図2
//例 配列を宣言し初期化する。
int main(void)
{
	int hairetsu[3]={1,2,3}; // int型3つ([0]~[2])の配列を宣言し、1,2,3で初期化する。※図2
}

上の例では、hairetsu[0]が1、hairetsu[1]が2、hairetsu[2]が3でそれぞれ初期化されている。

配列を値のリストで初期化する場合、要素数を省略できる。

図2
//例 要素数を省略して、配列を宣言し初期化する。
int main(void)
{
	int hairetsu[]={1,2,3}; // int型3つ([0]~[2])の配列を宣言し、1,2,3で初期化する。※図2
}

上の例では、値のリストの要素数で、配列の要素数が決まる。

1次元の配列の代入[編集]

1次元配列の代入の記述は次のようになっている。

配列名[添字]=;

配列名が指す配列の[添字]番目の要素に、式の値を代入する。 添字とは、アクセスする配列の要素を特定するものである。 添字は[0]から順番に数え、[配列の要素数-1]までの整数である。 [4]

図1
図2
//例 配列に代入する。
int main(void)
{
	int hairetsu[3]; // int型3つ([0]~[2])の配列を宣言する。※図1
	hairetsu[0]=1; hairetsu[1]=2; hairetsu[2]=3; // 配列に数値を代入する。※図2
}

上の例では、hairetsu[0]に1、hairetsu[1]に2、hairetsu[2]に3をそれぞれ代入している。

1次元の配列の参照[編集]

1次元配列の参照の記述は次のようになっている。

配列名[添字]

配列名が指す配列の[添字]番目の要素を参照する。 添字とは、アクセスする配列の要素を特定するものである。 添字は[0]から順番に数え、[配列の要素数-1]までの整数である。 [4]

図2
図3
//例 配列を参照する。
int main(void)
{
	int hairetsu[]={1,2,3}; // int型3つ([0]~[2])の配列を宣言し、1,2,3で初期化する。※図2
	hairetsu[0]=hairetsu[1]+hairetsu[2]; // 配列の[1]と[2]の数値を参照し、配列の[0]にその和を代入する。※図3
}

上の例では、hairetsu[1]とhairetsu[2]の要素が参照され、 その和をhairetsu[0]の要素に代入している。

注意!
C言語では、配列の添字に関して、
範囲外チェックをしません。
範囲外にならないように、気をつけてください。

多次元の配列[編集]

多次元の配列の宣言[編集]

多次元配列の宣言は、 配列名の後に、 次元の数だけ[配列の要素数]を追加する。 例えば3行×4列の2次元配列の宣言は、 次のように記述できる。

//例 多次元の配列を宣言する。
int main(void)
{
	int hairetsu[3][4];
}

上の例では、次の表のように3行×4列の配列が確保される。

[0] [1] [2] [3]
[0] hairetsu[0][0] hairetsu[0][1] hairetsu[0][2] hairetsu[0][3]
[1] hairetsu[1][0] hairetsu[1][1] hairetsu[1][2] hairetsu[1][3]
[2] hairetsu[2][0] hairetsu[2][1] hairetsu[2][2] hairetsu[2][3]

実際には、次の表のような順番で配列がメモリ上に確保される。

メモリ
hairetsu[0][0]
hairetsu[0][1]
hairetsu[0][2]
hairetsu[0][3]
hairetsu[1][0]
hairetsu[1][1]
hairetsu[1][2]
hairetsu[1][3]
hairetsu[2][0]
hairetsu[2][1]
hairetsu[2][2]
hairetsu[2][3]

多次元配列も1次元配列と同様に、 配列の宣言と同時に値のリストで初期化することができる。 値のリストは、 各次元の添字が[0]のものから始まり、 一番右の次元の添字が1つずつ増えていき、 その添字の数が要素数まで増えたら、 1つ左の次元へ繰り上がる。

//例 多次元の配列を宣言し初期化する。

int main(void)
{
	int hairetsu[3][4]={
		0,1,2,3,
		4,5,6,7,
		8,9,10,11
		};
}

上の例では、次の表のように、初期化される。

[0] [1] [2] [3]
[0] hairetsu[0][0]
0
hairetsu[0][1]
1
hairetsu[0][2]
2
hairetsu[0][3]
3
[1] hairetsu[1][0]
4
hairetsu[1][1]
5
hairetsu[1][2]
6
hairetsu[1][3]
7
[2] hairetsu[2][0]
8
hairetsu[2][1]
9
hairetsu[2][2]
10
hairetsu[2][3]
11

多次元配列を値のリストで初期化する場合、 1番左の次元の要素数は省略できる。

//例 要素数を省略して、多次元の配列を宣言し初期化する。

int main(void)
{
	int hairetsu[][4]={
		0,1,2,3,
		4,5,6,7,
		8,9,10,11
		};
}

多次元の配列の代入[編集]

多次元配列の代入は、 配列名の後に、 次元の数だけ[添字]を追加する。 [4]

//例 多次元の配列に代入する。

int main(void)
{
	int hairetsu[3][4];
	int x, y;
	for (y=0; y<3; ++y)
		for (x=0; x<4; ++x)
			hairetsu[y][x] = x+y*4;
}

上の例では、次の表のように、代入される。

[0] [1] [2] [3]
[0] hairetsu[0][0]
0
hairetsu[0][1]
1
hairetsu[0][2]
2
hairetsu[0][3]
3
[1] hairetsu[1][0]
4
hairetsu[1][1]
5
hairetsu[1][2]
6
hairetsu[1][3]
7
[2] hairetsu[2][0]
8
hairetsu[2][1]
9
hairetsu[2][2]
10
hairetsu[2][3]
11

多次元の配列の参照[編集]

多次元配列の参照も同様に、 配列名の後に、 次元の数だけ[添字]を追加する。 [4]

//例 多次元の配列を参照する。
#include <stdio.h>

int main(void)
{
	int hairetsu[3][4] = {
		0,1,2,3,
		4,5,6,7,
		8,9,10,11
		};
	int x, y;
	for (y=0; y<3; ++y){
		for (x=0; x<4; ++x){
			printf("%2d ", hairetsu[y][x]);
		}
		printf("\n");
	}
}

配列全体のコピー[編集]

配列全体をコピーする場合、各要素を1つずつコピーしなければならない。

//例 配列を1つずつコピーする。

int main(void)
{
	int hairetsu1[3] = {0,1,2};
	int hairetsu2[3];
	int n;
	for(n=0; n<3; ++n)
		hairetsu2[n] = hairetsu1[n]; // hairetsu1をhairetsu2にコピーする。
}

また、memcpy関数を用いることで、配列全体をコピーできる。 memcpy関数を使用するためには、memory.hというヘッダファイルを組み込む必要がある。

//例 配列をまとめてコピーする。
#include <memory.h>

int main(void)
{
	int hairetsu1[3] = {0,1,2};
	int hairetsu2[3];
	memcpy(hairetsu2, hairetsu1, sizeof(hairetsu2)); // hairetsu1をhairetsu2にコピーする。
}

脚注[編集]

  1. ^ 『JISX3010:2003』p.24「6.2.5 型」
  2. ^ 『JISX3010:2003』p.86「6.7.5.2 配列宣言子」
  3. ^ 『JISX3010:2003』p.94「6.7.8 初期化」
  4. ^ 4.0 4.1 4.2 4.3 『JISX3010:2003』p.51「6.5.2.1 配列の添字付け」

参考文献[編集]

  • 日本工業標準調査会『JISX3010 プログラム言語C』2003年12月20日改正