6-1 配列

配列とは変数の集まりです。
変数を集団で宣言する方法です。

配列とは(宣言と使い方)

変数では、1つ1つに名前を付けて使用しました。
数が少ないときはこれで良いのですが、多くなったらどうでしょう。
高層マンションのXX号室の価格を記憶するのに、1つ1つの変数に名前を付けられますか。
例えば、

int room101, room102, ・・・, room999


大変でしょう。
これを以下のように宣言できます。

型名 配列名[要素数]

int room[1000];


この意味は、
roomという配列の名前で、1000室分の記憶領域(要素数)を用意するという意味です。
型名はint、short、doubleなど何でも使用できます。

変数と配列を比較してみましょう。

以下を例として考えます。
101号室 3500万円
201号室 3700万円
301号室 3800万円
これを変数で表した場合、部屋数分の変数名の宣言が必要になります。

int room101, room201, room301,・・・;
room101=3500; ←101号室は 3500 万円
room201=3700; ←101号室は 3700 万円
room301=3800; ←101号室は 3800 万円

配列で表した場合、1つの配列名を宣言すればよいのです。

int room[1000]; ←1000室分
room[101]=3500; ←101号室は 3500 万円
room[201]=3700; ←201号室は 3700 万円
room[301]=3800; ←301号室は 3800 万円


宣言 int room[1000]; は、
roomという名前の配列で、1000個の記憶領域を用意するという意味です。
そして、部屋番号を[]内で使用していますが、これはプログラマーが部屋番号で使うと決めたからです。使い手が自由に決めればよいのです。
宣言では、roomという名前で入れ物を1000用意するという意味しかありません。
このカッコ内の番号をインデックスといいます。
このインデックスはroomという記憶領域の何番目かを表しており、ゼロから始まります。
room[1000]と宣言したら、インデックス0~999までの1000個の入れ物を用意したということです。
1000は使用できるインデックスの最大値ではありません。
インデックスは0から始まるので、room[0]~room[999]までの1000個が使用できるということです。インデックスは999までしか使えません。

もう1つ使用例をあげてみましょう。
次の例は、小学校の1クラス30名の国語の点数を記憶する場合です。
この例ではインデックスを出席番号1~30として扱っています。

#include <stdio.h>

int main()
{
    int ten[31];

    /* インデックスは出席番号 1~30 */
    ten[1] = 75;
    ten[2] = 80;
    ten[3] = 90;
}

インデックスのゼロは使用していませんね。
ten[0]~ten[30]までの31個の領域が使用できます。
しかし、プログラマーは0は使用する気が無いようです。
配列は理解できたでしょうか。

配列の初期化

配列を宣言しただけですと、記憶領域が確保されただけです。
では、その配列に最初にどんな値が入っているかというと、その記憶場所を以前使用していただれかがセットしていた値があるということなのです。
要するに宣言しても、そこにはどんな値が入っているかは神のみぞ知るということなのです。
そこで、以下のように1つずつセットしても良いのですが、

int ten[30];
ten[0]=0;
ten[1]=70;
ten[2]=80;
ten[3]=78;
ten[4]=91;

配列の場合には簡単な方法があります。
上記の内容は以下のように書けます。

データ型 配列名[要素数] = {値, 値, ...};

int ten[30] = {0, 70, 80, 78, 91, ・・・};

次の例を見てください。

#include <stdio.h>

int main()
{
    int ten[30] = { 70, 80, 78, 91};

    for (int i=0; i<10; i++)
        printf("ten[%d]=%d\n", i, ten[i]);
}
実行結果
ten[0]=70
ten[1]=80
ten[2]=78
ten[3]=91
ten[4]=0
ten[5]=0
ten[6]=0
ten[7]=0
ten[8]=0
ten[9]=0

配列 ten は30個の領域なのに、初期化は最初の4つ、インデックスでは0~3のみ初期化しています。
このように領域の数より初期化が少ない場合には、後ろの領域(4以降)にはゼロが初期値として入れられます。

配列の要素数(上の例の[30])を指定せずに、初期化することもできます。
次の例を見てください。

データ型 配列名[] = {値, 値, ...};

int ten[] = {70, 80, 78, 91};

この例の場合は、初期化で指定している数値が4個ですので、tenは[0]~[3]しか領域が確保されません。

文字型配列

文字型にも配列があります。

変数では、1つ1つに名前を付けて使用しました。
数が少ないときはこれで良いのですが、多くなったらどうでしょう。
アルファベットを記憶するのに、1つ1つの変数に名前を付けられますか。
例えば、

char a, b, ・・・, z;


大変でしょう。
これを以下のように宣言できます。

型名 配列名[要素数]

char alp[26];


この意味は、
alpという配列の名前で、26文字の記憶領域(要素数)を用意するという意味です。

変数と配列を比較してみましょう。

以下を例として考えます。
変数aの内容は 文字'a'
変数bの内容は 文字'b'
変数cの内容は 文字'c'
これを変数で表した場合、文字数分の変数名の宣言が必要になります。

char a,b,c,・・・;
a='a'; ←変数aの文字は 'a'
b='b'; ←変数aの文字は 'b'
c='c'; ←変数aの文字は 'c'

配列で表した場合、1つの配列名を宣言すればよいのです。

char alp[26];
alp[0]='a'; ←変数alpの0番目の文字は 'a'
alp[1]='b'; ←変数alpの1番目の文字は 'b'
alp[2]='c'; ←変数alpの2番目の文字は 'c'


宣言 char alp[26]; は、
alpという名前の配列で、26個の記憶領域を用意するという意味です。
0番目には文字’a'を、1番目には文字’b'を、2番目には文字’c'を入れています。
intのときと使い方は同じです。

文字型配列の初期化

文字型の初期化もint型と同様です。

データ型 配列名[要素数] = {値, 値, ...};

char alp[26] = {'a','b','c', ・・・};

次の例を見てください。

#include <stdio.h>

int main()
{
    char alp[26] = {'a', 'b', 'c', 'd', 'e',
                    'f', 'g', 'h', 'i', 'j',
                    'k', 'l', 'm', 'n', 'o',
                    'p', 'q', 'r', 's', 't',
                    'u', 'v', 'w', 'x', 'y',
                    'z'};

    for (int i=0; i<=25; i++)
        printf("alp[%d]=%c \n", i, alp[i]);
}
実行結果
alp[0]=a
alp[1]=b
alp[2]=c
alp[3]=d
alp[4]=e
alp[5]=f
alp[6]=g
alp[7]=h
alp[8]=i
alp[9]=j
alp[10]=k
alp[11]=l
alp[12]=m
alp[13]=n
alp[14]=o
alp[15]=p
alp[16]=q
alp[17]=r
alp[18]=s
alp[19]=t
alp[20]=u
alp[21]=v
alp[22]=w
alp[23]=x
alp[24]=y
alp[25]=z

int型の配列と考え方は同じです。

これも配列の要素数(上の例の[26])を指定せずに、初期化することもできます。
次の例を見てください。

データ型 配列名[] = {値, 値, ...};

int alp[] = {'a','b','c','d'};

この例の場合は、初期化で指定している数値が4個ですので、alpは[0]~[3]しか領域が確保されません。

多次元配列

2次元配列は以下のように宣言できます。

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

int array[10][3];

3次元配列は以下のように宣言できます。

データ型 配列名[要素数1][要素数2][要素数3];

int array[10][3][5];

4次元以上も宣言できますが、あまり使用する機会はないと思います。

どのように使うのでしょう。
小学校の1クラス10名の国語、算数、社会の点数を記憶する場合を考えてみましょう。

インデックスの使い方を以下のように決めます。
要素数1: 出席番号に使用する。1番の人はインデックス0、2番の人はインデックス1と決める。
要素数2: 0は国語、1は算数、2は社会と決める。

次のように使います。

int ten[10][3];
ten[0][0] = 60; ←出席番号1番の人の国語の点数
ten[0][1] = 70; ←出席番号1番の人の算数の点数
ten[0][2] = 80; ←出席番号1番の人の社会の点数

ten[1][0] = 65; ←出席番号2番の人の国語の点数
ten[1][1] = 75; ←出席番号2番の人の算数の点数
ten[1][2] = 85; ←出席番号2番の人の社会の点数

ten[2][0] = 62; ←出席番号3番の人の国語の点数
ten[2][1] = 72; ←出席番号3番の人の算数の点数
ten[2][2] = 82; ←出席番号3番の人の社会の点数

1つの配列に、複数のデータが入れられますね。

多次元配列の初期化

上のデータをセットする例を初期化でセットしてみます。

int ten[10][3] = {{60, 70, 80}, {65, 75, 85}, {62, 72, 82}};

これは以下のようにも書けます。

int ten[][3] = {{60, 70, 80}, {65, 75, 85}, {62, 72, 82}}

要素数1は省略できます。
省略するとコンパイラーが、初期化の数をみて領域を確保してくれます。
このため上の例では、[3][3]で宣言したのと同じになってしまします。

この例を見て下さい。

#include <stdio.h>

int main()
{
    int ten1[10][3] = {{60, 70, 80}, {65, 75, 85}, {62, 72, 82}};
    int ten2[][3]  = {{60, 70, 80}, {65, 75, 85}, {62, 72, 82}};

    for (int i=0; i<10; i++) {
        for (int j=0; j<3; j++)
            printf("ten1[%d][%d] = %d ", i, j, ten1[i][j]);
        printf("\n");
    }

    printf("\n");

    for (int i=0; i<3; i++) {
        for (int j=0; j<3; j++)
            printf("ten2[%d][%d] = %d ", i, j, ten2[i][j]);
        printf("\n");
    }
}
実行結果
ten1[0][0] = 60 ten1[0][1] = 70 ten1[0][2] = 80
ten1[1][0] = 65 ten1[1][1] = 75 ten1[1][2] = 85
ten1[2][0] = 62 ten1[2][1] = 72 ten1[2][2] = 82
ten1[3][0] = 0 ten1[3][1] = 0 ten1[3][2] = 0
ten1[4][0] = 0 ten1[4][1] = 0 ten1[4][2] = 0
ten1[5][0] = 0 ten1[5][1] = 0 ten1[5][2] = 0
ten1[6][0] = 0 ten1[6][1] = 0 ten1[6][2] = 0
ten1[7][0] = 0 ten1[7][1] = 0 ten1[7][2] = 0
ten1[8][0] = 0 ten1[8][1] = 0 ten1[8][2] = 0
ten1[9][0] = 0 ten1[9][1] = 0 ten1[9][2] = 0

ten2[0][0] = 60 ten2[0][1] = 70 ten2[0][2] = 80
ten2[1][0] = 65 ten2[1][1] = 75 ten2[1][2] = 85
ten2[2][0] = 62 ten2[2][1] = 72 ten2[2][2] = 82

ten1の初期化していないところは、ゼロがセットされます。
ten2は3件分しか領域が確保されていませんので気を付けてください。

コメント

タイトルとURLをコピーしました