配列変数

大量のデータを扱う場合の処理

4日目までの内容で、ほぼC言語の基本的な概念が出てきました。しかし、これだけでは十分なプログラムができるわけではありません。実用的なプログラムを作るときに大事なことはたくさんありますが、特にここでは大量のデータを扱う場合について説明しましょう。C言語では、変数を用いて大量のデータを扱う場合、配列変数(はいれつへんすう)を用います。ここでは、配列変数の使い方を学ぶことにしましょう。

サンプルプログラム

配列変数について詳しく説明する前に、まずは以下のプログラムを入力・実行してみてください。

list5-1:main.c
#include <stdio.h>

void main(){
	double one,two,three;			//	変数の宣言
	double sum,avg;	//	合計値、平均値を入れる変数
	one = 1.2,two = 3.7,three = 4.1;	//	変数の代入
	printf("%f %f %f¥n",one,two,three);
	sum = one + two + three;	//	合計値の計算
	avg = sum / 3.0;			//	平均値の計算
	printf("合計値:%f¥n",sum);
	printf("平均値:%f¥n",avg);
}
実行結果
1.200000 3.700000 4.100000
合計値:9.000000
平均値:3.000000

このケースは、数値が3つだからよいですが、もしももっと増えたらどうなるでしょう?four,five,と、次々に定義する変数の数を増やしていかなくてはなりません。 しかし、このプログラムを、以下のように変更すると、大変楽になります。

list5-2:main.c
#include <stdio.h>

void main(){
	//	サイズ3の配列変数の宣言
	double d[3];
	double sum,avg;	//	合計値、平均値を入れる変数
	int i;
	//	値を代入
	d[0] = 1.2;
	d[1] = 3.7;
	d[2] = 4.1;
	sum = 0.0;
	for(i = 0; i < 3; i++){
		printf("%f ",d[i]);
		sum += d[i];
	}
	printf("¥n");
	avg = sum / 3.0;			//	平均値の計算
	printf("合計値:%f¥n",sum);
	printf("平均値:%f¥n",avg);
}

実行結果は、list5-1と一緒です。若干プログラムは長くなってしまいましたが、もしも変数が5個、10個、100個・・・ と増えたときを考えてみてください。こちらのほうが、プログラムを変更する手間が少なそうです。

配列変数

では、一体、このプログラムはどのような仕組みになっているのでしょうか?5行目に出てくる、int d[3];という記述が、配列変数(はいれつへんすう)の宣言です。配列変数とは、同一の名前で多数のデータを格納できる変数のことで、単に配列(はいれつ)とも呼ばれます。

配列変数にも、変数名が存在します。この場合、dが変数名になります。[]の中に記述されているのが、配列の大きさで、この場合、サイズは3になります。

添字

この処理により、d[0]、d[1]、d[2]という3つのdouble型の変数が使用可能になります(図5-1)。4行目から6行目の間で、これらの変数に値を代入しています。なお、ここで[]の中に書いてある数字を、添字(そえじ)と言います。例えば、「d[1] = 3.7;」という処理は、この配列の2番目の変数に、3.7という値を代入することを意味します(図5-2)。この数値は必ず0から始まりますので、配列の大きさが3の場合は、2までになります。

図5-1.配列の宣言図5-2.配列変数への値の代入
C言語の配列の宣言C言語の配列変数への代入

添字が、配列の範囲を超えていてもエラーにはなりませんが、実行時に異常終了したりすることがありますので、気をつけましょう。

配列変数を使うメリットは、実はこの添字が使えることにあります。13行目から17行目のforループの中で、添字に整数型変数iを用いています。 これにより、プログラムを変更して、配列の大きさを変化させても、for文に条件式の値を変化させるだけで対応できます。

配列の初期化

ところで、配列変数の宣言と初期化ですが、もう少し、楽にならないものなのでしょうか?実は、以下のようにすると、配列変数の宣言と初期化を一度に行うことができます。

list5-3:main.c
#include <stdio.h>

void main()
{
	int n[] = { 5,4,3,2,1 };
	int i;
	for(i = 0; i < 5; i++){
		printf("n[%d]=%d ",i,n[i]);
	}
	printf("¥n");
}
実行結果
n[0]=5 n[1]=4 n[2]=3 n[3]=2 n[4]=1

実行結果を見るとわかるように、5行目で行っている処理は、配列の大きさを5にし、同時に変数の値の代入を行っています。

配列の宣言と初期化
int n[] = { 5,4,3,2,1 };
    ↓ この処理は、以下の処理に相当
int n[5];
n[0] = 5;
n[1] = 4;
n[2] = 3;
n[3] = 2;
n[4] = 1;

文字列と配列

サンプルプログラム

配列変数は、基本的にどのような型の変数でも利用可能です。しかし、中でも特殊なのがchar型の配列です。C言語には、文字列をchar型の配列変数として扱う仕組みがあり、そのために様々な関数が用意されています(発展編第4日目参照)。ここでは、文字列配列の基本的な考え方と、その関数の一部を紹介します。以下のサンプルを実行してみてください。

list5-4:main.c
#include <stdio.h>

void main(){
	char s1[4] = { 'a','b','c','¥0' };	//	文字列"abc"
	char s2[] = "HelloWorld.";			//	文字列"HelloWorld."
	char s3[10];						//	最大10文字まで入る文字列
	//	文字列の入力
	printf("文字列を入力してください。:");
	scanf("%s",s3);	//	文字列の入力
	printf("s1 = %s¥n",s1);
	printf("s2 = %s¥n",s2);
	printf("s3 = %s¥n",s3);
}
実行結果
文字列を入力してください。:Taro
s1 = abc
s2 = HelloWorld
s3 = Taro

プログラムを実行すると、「文字列を入力してください。:」と表示されますので、ここで何か文字列を入力しましょう。すると、この結果上のように表示されます。

文字列配列のscanf()

まず、文字列が入力可能になるのは、9行目の

scanf("%s",s3); // 文字列の入力

になります。すでに述べたとおり、scanf()で整数値を入力するときには、"で囲まれた部分に、%dと書きました。しかし、文字列の場合は、%sとなります。なお、このとき、整数のときに必要だった、&は、必要ありません。理由に関しては、ここでは説明するのが難しいので省略(発展編第4日目参照)しますが、文字列を入れる配列変数名だけを記述してください。

→ scanf()関数について、より詳しい解説は、こちらを参考にしてください。

文字列とNULL文字

char型の変数の成分には、それぞれ文字列のコードが入っています。そして、文字列の最後には、必ず¥0が入っています。 エスケープシーケンスの部分でも説明しましたが、この文字を、NULL(ヌル)文字と言います。値としては0に等しいのですが、文字として使用する場合、とくにこう呼びます。

そのため、配列変数に文字列を作る場合は、最低限、文字数+1の成分が必要になります。また、配列の途中に¥0があれば、そこで文字列は終了になります。(図5-3)

図5-3.文字列の配列
文字列の配列① 文字列+1の長さの配列を用意し、文字を配置。最後に¥0が入る。
② 文字列+1の長さの配列が用意され、最後に¥0が入る。
③ 配列のサイズが文字列よりも大きくても、¥0が途中に入っていれば、
文字列はそこで終わる。

多次元配列

サンプルプログラム

最後に、配列変数の応用である、多次元配列(たじげんはいれつ)について説明しましょう。多次元配列とは、複数の添字をつけることができる配列変数です。そのなかで、最も基本となる二次元配列の例をここでは紹介します。以下のプログラムを実行してみてください。

list5-5:main.c
#include <stdio.h>

void main(){
	int a[3][4];
	int m,n;
	//	二次元配列に値を代入
	for(m = 0; m < 3; m++){
		for(n = 0; n < 4; n++){
			a[m][n] = m+n;
		}
	}
	//	成分の表示
	for(m = 0; m < 3; m++){
		for(n = 0; n < 4; n++){
			printf("%d ",a[m][n]);
		}
		printf("¥n");
	}	
}
実行結果
0 1 2 3
1 2 3 4
2 3 4 5

二次元配列

二次元配列aには、2つの添え字をつけることができます。これにより、二次元の配列を作ることが可能です。(図5-4)

図5-4.二次元配列のイメージ
二次元配列のイメージ

二次元配列の理由範囲は非常に高く、さまざまな表や、座標などのデータを表すものとして使用されます。わかりやすい例でいくと、表計算のような処理は、二次元配列を用いれば、非常に簡単に実現できます。

理論的には、このようにして添字を増やすことにより、二次元、三次元・・・といった多次元の配列変数を作ることは可能です。しかし、実際用いられる多次元配列は、ほとんどがこの二次元配列です。

練習問題 : 問題5.