一週間で身につくC言語の基本

おさえておきたいプログラミングの基本

【5日目】 配列変数

5-1.配列変数

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

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

変数を用いて大量のデータを扱う場合、配列変数(はいれつへんすう)を用いることができます。ここでは配列変数の使い方を学ぶことにしましょう。なお、配列変数は単に配列(はいれつ)と呼ばれることもあります。

(2) 配列変数が有効なケース

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

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

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

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

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

int main(int argc, char** argv) {
	//	サイズ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("%lf ",d[i]);
		sum += d[i];
	}
	printf("\n");
	avg = sum / 3.0;			//	平均値の計算
	printf("合計値:%lf\n",sum);
	printf("平均値:%lf\n",avg);
    return 0;
}

実行結果は、list5-1と一緒です。若干プログラムは長くなってしまいましたが、変数はd1つだけです。変数は1つですが、[]の中の数字で区別しています。このような変数が配列変数です。

このような方法だと、もしも変数が5個、10個、100個・・・ と増えたときを考えてみてください。こちらのほうが、プログラムを変更する手間が少なそうです。


(3) 配列変数の宣言

では、一体、このプログラムはどのような仕組みになっているのでしょうか?

配列変数を利用するには、まず配列の宣言が必要です。通常の変数が、変数の型と名前を決めるように、配列変数の宣言は変数の型と名前、そして配列の大きさを決めます。書式は次の通りです。

配列変数の宣言の書式
変数の型 変数名[配列の大きさ];

list5-1では、5行目で行ってます。

配列変数の宣言
double d[3];

この場合、dが変数名になります。[]の中に記述されているのが、配列の大きさで、この場合、サイズは3になります。この処理により、d[0]、d[1]、d[2]という3つのdouble型の変数が使用可能になります。(図5-1)

図5-1.配列の宣言
配列の宣言

(4) 添字

9行目から11行目の間で、d[0]、d[1]、d[2]に値を代入しています。[]の中に書いてある数字を添字(そえじ)と言います。例えば、「d[1] = 3.7;」という処理は、この配列の2番目の変数に、3.7という値を代入することを意味します。(図5-2)

図5-2.配列への値の代入
配列への値の代入

この数値は必ず0から始まりますので、配列の大きさが3の場合は、2までになります。

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

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

図5-3.添字を変数にした処理
添字を変数にした処理

(4) 配列の初期化

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

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

int main(int argc, char** argv) {
    int n[] = { 5,4,3,2,1 };
	int i;
	for(i = 0; i < 5; i++){
		printf("n[%d]=%d ",i,n[i]);
	}
	printf("\n");
    return 0;
}
実行結果
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;

通常はlist5-2.のように配列の宣言と代入は複数行にわたりますが、このように宣言と初期値の設定を同時に行うと1行で行うことができます。

5-2.文字列と配列

(1) char型の配列と文字列

配列変数は、基本的にどのような型の変数でも利用可能です。しかし、中でも特殊なのがchar型の配列です。C言語では文字列をchar型の配列変数として扱う仕組みがあり、そのために様々な関数が用意されています。(発展編第4日目参照)

ここでは、文字列配列の基本的な考え方と、その関数の一部を紹介します。以下のサンプルを実行してみてください。

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

int main(int argc, char** argv) {
	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);
    return 0;
}
実行結果
文字列を入力してください。:Taro ← 文字列を入力しEnterキーを押す s1 = abc s2 = HelloWorld s3 = Taro

(2) 文字列配列のscanf()

まず、文字列が入力可能になるのは、9行目のscanf関数の処理です。scanf関数で整数を入力する方法はすでに説明しましたが、文字列の入力も可能なのです。

scanf関数による文字列の入力
scanf("%s",s3); // 文字列の入力

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

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

また、%sはprintf関数で文字列を表示する際にも用います。(10~12行目)

(3) 文字列とNULL文字

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

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

なお、char型の配列の途中に∖0があった場合、どんなに長いchar型配列であってもそこで文字列は終了します。scanf関数で文字列を入力する場合、それは何文字になるかわかりません。そのため、入力結果を代入する配列の長さは十分に長くとる必要があります。

この例では長さ10の配列s3を用意しています。もしも4文字の文字列が代入されると、4番目に∖0が代入され、そこで文章は終わります。(図5-4:③)

図5-4.文字列の配列
文字列の配列

5-3.多次元配列

(1) ニ次元配列

最後に、配列変数の応用である、多次元配列(たじげんはいれつ)について説明しましょう。多次元配列とは、複数の添字をつけることができる配列変数です。そのなかで、最も基本となる二次元配列の例をここでは紹介します。二次元配列はEXCELの表のような二次元形式の表でデータを管理するのに都合の良い配列です。

以下のプログラムを実行してみてください。

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

int main(int argc, char** argv) {
	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");
	}
    return 0;
}
実行結果
0 1 2 3 1 2 3 4 2 3 4 5

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

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

このプログラムでは、i、jの二重ループでa[i][j]にi+jが代入されます。(7~11行目)そのため、a[0][0]=1、a[0][1]=1、…、a[1][2]=3、…a[2][3]=5となります。

最後にこれを表示しています。(13~18行目)

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

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

練習問題 : 問題5.


一週間で学べるコースの一覧
Udemy
...
2024/10/01

Udemyでも学びましょう!

一週間でわかるC言語・C++言語がオンライン講座になりました!動画音声によってさらにわかりやすくなりました!! 1講座で2つの言語を学ぶことができる上に、練習問題の回答もダウンロードできます。

Read →
Impress一週間シリーズ
1週間でC言語の基礎が学べる本
2024/10/01

書籍化された一週間シリーズ

本講座が「1週間でC言語の基礎が学べる本」として書籍化されました!サイトの内容プラスアルファでより学習しやすくなっています!Impressより発売中です!!

Read →
Impress一週間シリーズ
...
2024/10/01

書籍化された一週間シリーズ

一週間シリーズは書籍化されています。こちらもどうぞ!

Read →
プログラマーなら欲しいグッズ
プログラミンググッズ

プログラミンググッズ

快適なプログラミング環境を構築したい人々にぜひとも揃えてほしいグッズです。

Read →
制作・管理
シフトシステム株式会社

シフトシステム株式会社

このサイトはシフトシステム株式会社によって制作・管理がなされています。

Read →