C++セミナー(初級)配列

HOME->講習会->プログラミングセミナー->C++セミナー(初級)


多くのデータをよみとって,変数に格納したいといった場合にいくつも変数を宣言するのはソースコードが長くなったり,データ数が変わった時に対応させることができません.大量のデータを扱うときに配列と呼ばれるものを使用します.

目次

配列
固定長配列
可変長配列
for文による配列処理
演習

配列

同じ型の変数を一列にすき間を開けずに並べたものを配列といいます.よく例えられる例として,1つの大きな箱に仕切りをいれて,順番に番号を付けたものといわれます.

配列を構成する1つ1つのデータのことを要素といいます.上図で言えば,要素数が4ですが,要素の番号は0から振られるので,0,1,2,3と要素数=要素の最後の番号ではないので注意が必要です(ほとんどのプログラミング言語が同じ仕様です).

また,1方向にだけ要素を並べたものを1次元配列といい,2方向に要素を並べたものを2次元配列,3方向に並べたものを3次元配列…n方向に要素を並べたものをn次元配列といいます.2次元以上の配列は多次元配列ともいわれます.

固定長配列

固定長配列(静的配列ともいう)は,一度,要素数を決定したら変更することができない配列のことを言います.C++では,以下のようにして配列の宣言を行います.

変数型 配列名[要素数];
変数型 配列名[要素数][2次元目要素数];
変数型 配列名[要素数][2次元目要素数]...[n次元目要素数];

通常の変数宣言に加え,名前の後ろに「[ ]」で要素数を指定するだけで配列の宣言は可能となります.例えば,int型の配列だと以下のように宣言します.

int array[10];             // 要素数10の1次元配列
int array2d[10][5];        // 要素数10x5の2次元配列
int array3d[10][2][20];    // 要素数10x2x20の3次元配列

要素数については,コンパイル時に決定していなければならないため,要素数をstd::cinで読み取って,当てはめるというようなことはできないので,注意が必要です.各要素のデータの読み書きについては,以下のように行います.

配列名[要素番号] = データ;
変数 = 配列名[要素番号];

多次元配列の場合でも,「[ ]」の数が増えて,要素番号を指定するだけで可能です.また,配列は変数と同様に宣言と同時に初期化することも可能です.例えば,int型配列から要素を0から9まで格納して初期化する例を示します.

int array[] = {0,1,2,3,4,5,6,7,8,9};

上記のように,配列の初期化は「{ }」でカンマ区切りで記述することで行うことができます.また,配列の初期化は「{ }」でカンマ区切りで記述することで行うことができます.このときに初期化の時に要素が自動的に決まるので,要素数の記入を省略することも可能です.多次元配列については,1次元目以外は省略できないので注意が必要です.

int array[][5]{
    {1,2,3,4,5},
    {2,3,4,55,1}
};

可変長配列

可変長配列(動的配列ともいう)は,要素数を場合によって変更することができる配列のことをいいます.C++では,可変長配列を利用するためにポインタ変数を用います.

int *array = new int[5];

newは,ポインタ変数に実態を持たせるための機能です(詳しくはC++セミナー(中級)でやります).ポインタ変数 arrayに対して,要素数が5のint型配列を生成するというような意味になります.この可変長配列は,固定長配列の要素数がコンパイル時に決定していなければならないというのに対して,コンパイル後に要素数を決定することができます.しかし,多次元配列になると初期化だけでも手間がかかります.例えば,int型の二次元配列を用意するのは以下のようになります.

int **array = new int*[5];
for(int i=0; i<5; i++){
    array[i] = new int[5];
}

ここで,注意しなければならないのが,newを用いて生成したものについて,メモリを解放するということをしなければなりません.メモリの解放は以下のようにして行います.

int *array = new int[5]; // メモリの確保
delete []array;          // メモリの解放

int **array2d = new int*[5];
for(int i=0; i<5; i++){
    array2d[i] = new int[5];
}
for(int i=0; i<5; i++){
    delete []array2d[i]
}
delete []array2d;

メモリの解放を忘れると,常にメモリ領域が確保された状態になるため,新しくメモリを確保できなくなるといったメモリリークと呼ばれるバグが発生します.deleteは,確保したアドレスを解放するためのものになります.newで生成したものは必ずdeleteで解放しましょう.配列の開放の場合には,「[]」を配列名の前に付ける必要があるので注意が必要です.付け忘れると,配列の先頭の要素のみしか解放されません.

データの読み書きについては,固定長配列と同じです.

for文による配列処理

配列は,for文による繰り返し処理と組み合わせて使われることが多いです.例えば,配列のすべての要素を表示するには以下のようにすればよいです.

#include <iostream>
int main()
{
    int array[5] = {1,2,3,4,5};
    for(int i=0; i<5; i++){
        std::cout << array[i] << std::endl;
    }
}

しかし,これでは,要素数が変動したときに条件式の「i<5」を変化させなければなりません.そのような場合には,C言語のときにはなかった「拡張for文」を使用します(他の言語ではforeachと呼ばれるものだったりします).

for(変数型 変数名: コンテナ名){
    処理;
}

コンテナは,配列やリスト,連想配列など複数のデータを保持したもののことを指します(C++セミナー(上級)で扱います).拡張for文を用いて,配列のすべての要素を表示するには以下のようにすればよいです.

#include <iostream>
int main()
{
    int array[] = {1,2,3,4,5};
    for(auto dat: array){
        std::cout << dat << std::endl;
    }
}

演習

・要素数3の配列を2つ用意して,ベクトルの内積と外積を求めるプログラムを作成してみましょう.なお,要素は入力から受け取るようにしてください.
・要素数3×3の2次元配列を用意して,行列の和,差,積を求めるプログラムを作成してみましょう.なお,要素は入力から受け取るようにしてください.