苦しんで覚えるC言語

配列の使い方


初期値の代入


配列も、今までの変数と同様に、宣言と同時に初期化することが出来ます。
配列の初期化は、次のようにして行います。

型名 配列名[要素数]={0番の数値,1番の数値,2番の数値,・・・};
{}で囲んだ中に順番に,で区切って数値を並べます。
全てを指定する必要はないので、数値の個数は、配列の要素数以下にします。
配列の要素数よりも少ない場合、残りには全て0が代入されます。
次のプログラムは、配列を初期化して表示する例です。

#include <stdio.h>

int main(void)
{
	int array[10] = {42,79,13};
	
	printf("array[0] = %d\n",array[0]);
	printf("array[1] = %d\n",array[1]);
	printf("array[2] = %d\n",array[2]);
	printf("array[3] = %d\n",array[3]);
	printf("array[4] = %d\n",array[4]);
	
	return 0;
}
このプログラムの実行結果は、次の通りになります。

array[0] = 42
array[1] = 79
array[2] = 13
array[3] = 0
array[4] = 0
この方法で宣言した場合、要素数を省略できます。
その場合は、指定した数値の個数だけの要素数が確保されます。
次のプログラムは、要素数を省略して配列を宣言する例です。

#include <stdio.h>

int main(void)
{
	int array[] = {42,79,13};	/* 要素数が省略されている */
	
	printf("array[0] = %d\n",array[0]);
	printf("array[1] = %d\n",array[1]);
	printf("array[2] = %d\n",array[2]);
	
	return 0;
}
要素数を指定する手間が省ける上に、数え間違いもなくなるので、
初期値を代入出来る場合には省略する方が良いでしょう。

1度に配列に値を代入するのは、宣言の時にしか出来ません。
例えば、次のような代入は出来ません。

array = {42,79,13};
array[10] = {42,79,13};
これらは、エラーとなってしまうので、
宣言の後で値を代入したい場合は、面倒でも1つ1つ代入します。

array[0] = 42;
array[1] = 79;
array[2] = 13;

目次に戻る

全要素の表示


配列の全ての要素を表示するために、for文のループを使うことが出来ます。
この様な使い方が出来ることこそ、配列の最大の利点です。
次のプログラムは、配列内の要素の数を全て表示する例です。

#include <stdio.h>

int main(void)
{
	int array[] = {42,79,13,75,19};
	int i;
	
	for (i = 0;i < 5;i++) {
		printf("array[%d] = %d\n",i,array[i]);
	}
	
	return 0;
}
このプログラムの実行結果は次の通りになります。

array[0] = 42
array[1] = 79
array[2] = 13
array[3] = 75
array[4] = 19
このプログラムでのポイントは、配列の要素番号には変数も使えることです。
変数の値を変化させれば、様々な番号の要素に直接アクセスすることが出来ます。
配列ではない普通の変数では、5つの要素の表示にはprintf関数が5つ必要ですし、
100個表示するには100個必要ですが、配列ならfor文の数値を変えるだけです。

これなら、1万人のデータを表示させるプログラムだって簡単に書けます。
他にも、ループ内の文を変えることで、全要素に同じ値を代入したり、
全要素に代入された値の平均を求めることも簡単に出来ます。

目次に戻る

要素数を求める


前項では、for文のループを使用して配列の要素を全て表示しました。
繰り返し回数の5は直接指定しましたが、これでは要素数を数えなくてはなりません。
この方法では、要素数が増えるたびに、for文を書き直す必要があります。

それは面倒くさいので、要素数を自動的に求めて繰り返させることにします。
要素数を求める直接的な方法は用意されていませんが、計算することは出来ます。

配列全体のサイズを求め、それを要素1つのサイズで割れば要素の数がわかります。
C言語には、変数や配列のサイズを求めるsizeof(サイズオブ)演算子があります。
sizeof演算子は、次のようにして使います。

sizeof(変数や配列名)
sizeof演算子には()をつけなくても良いのですが、つけた方が読みやすいでしょう。
この演算子を使って配列arrayの要素数を求めるには次のようにします。

sizeof(array) / sizeof(array[0])
array[0]としているのは、0番の要素は必ずあるからです。
次のプログラムは、この方法で前項のプログラムを書き直した例です。

#include <stdio.h>

int main(void)
{
int array[] = {42,79,13,75,19};
	int i;
	
	for (i = 0;i < sizeof(array) / sizeof(array[0]);i++) {
		printf("array[%d] = %d\n",i,array[i]);
	}
	
	return 0;
}
実行結果は、前回と同じになります。
配列の要素数を変えると、自動的にその数だけ表示します。
要素数を変数に格納してムダを省く
実は、上記のプログラムにはムダがあります。
この書き方ですと、ループ1回毎に「sizeof(array) / sizeof(array[0])」の計算を行ってしまうのです。
int array_count = sizeof(array) / sizeof(array[0]);
for (i = 0;i < array_count;i++) {
として、要素数を変数に格納しておくことで、毎回計算するムダを省くことができます。

目次に戻る

配列のコピー


ある配列の全ての要素の値を他の配列に代入するにはfor文を使います。

#include <stdio.h>

int main(void)
{
  int array1[] = {42,79,13,19,41};
	int array2[] = {1,2,3,4,5};
	int i;
	
	for (i = 0;i < sizeof(array2) / sizeof(array2[0]);i++) {
		printf("array2[%d] = %d\n",i,array2[i]);
	}
	
	/* array1 の全要素を array2 にコピー */
	for (i = 0;i < sizeof(array2) / sizeof(array2[0]);i++) {
		array2[i] = array1[i];
	}
	
	for (i = 0;i < sizeof(array2) / sizeof(array2[0]);i++) {
		printf("array2[%d] = %d\n",i,array2[i]);
	}
	
	return 0;
}
このプログラムの実行結果は次の通りになります。

array2[0] = 1
array2[1] = 2
array2[2] = 3
array2[3] = 4
array2[4] = 5
array2[0] = 42
array2[1] = 79
array2[2] = 13
array2[3] = 19
array2[4] = 41
結果を見ると、array1の値がarray2にコピーされています。

しかし、for文を使わなくても、memcpy関数を使うことが出来ます。
なお、memcpy関数を使うには、memory.h ファイルを #include する必要があります。

memcpy(コピー先配列名、コピー元配列名、配列全体のサイズ)
配列全体のサイズは配列の型や要素数によって変わってくるので、
この関数では、sizeof演算子で得られたサイズを元にします。

配列の全ての要素をコピーするには、sizeof演算子で配列名を指定します。
次のプログラムは、memcpy関数で配列をコピーする例です。

#include <stdio.h>
#include <memory.h>

int main(void)
{
	int array1[] = {42,79,13,19,41};
	int array2[] = {1,2,3,4,5};
	int i;
	
	for (i = 0;i < sizeof(array2) / sizeof(array2[0]);i++) {
		printf("array2[%d] = %d\n",i,array2[i]);
	}
	
	memcpy(array2,array1,sizeof(array1)); /* array1 の全要素を array2 にコピー */
	
	for (i = 0;i < sizeof(array2) / sizeof(array2[0]);i++) {
		printf("array2[%d] = %d\n",i,array2[i]);
	}
	
	return 0;
}
実行結果は、先ほどと全く同じになります。
なお、コピー元の配列がコピー先より大きくても指定サイズだけコピーされるので、
要素数の多い配列からコピーすると問題が発生することがあります。

目次に戻る