topazの遊び場

いろいろやってみる

そろそろC++やるぞパート10 配列4 ~ 多次元配列 ~

そろそろC++やります

そろそろC++をやります。そろそろC++をやりたいからです。
何回やるかはわかりません。基礎を理解するまではやろうと思います。

という感じでやっています。

※ 初心者がメモレベルで記録するので、技術記事としてはお力になれないかもしれません。

内容

  • Microsoft配列をベースに、多次元配列について行います。

多次元配列

配列の配列が多次元配列です。各括弧で並べられた定数式を並べることで指定できます。

int mdArray[3][6];

なお、今回はmultidimensional array(多次元配列)mdArrayという変数とおきます。

今まで取り扱ってきた一次元の配列(array[3])の各要素が配列になったものが、多次元配列です。

初期化は波括弧({ })を使用します。多次元なので、波括弧の中に波括弧を書きます。

int mdArray[2][3]{
        {1, 3, 5},
        {12, 14, 16}};

アクセスは、配列の変数に各括弧([ ])にインデックスを添えてアクセスします。一次元配列同様に、配列外アクセスでは、配列外参照のエラー(IndexOutOfRangeExceptionなど)は出ずに、実行できてしまうため注意が必要です。

for (int i = 0; i < 2; i++)
{
    for (int j = 0; j < 3; j++)
    {
        cout << mdArray[i][j] << endl;
    }
}

多次元配列もメモリ上では、一次元配列のように、一列に並んだデータとなっています。


多次元配列の並び方が、行並びか、列並びかの話をずっと前にどこかで聞いたような気がしたので、C言語で試してみました。(競プロの話でしたっけ?完全に忘れてしまったので、心当たりのある方は教えてください。)

// ##### C言語 #####
#include <stdio.h>

int main(){
    int mdArray[2][3]=  
    {{1,2},{2,2,5}};

    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            printf("%p\n", &mdArray[i][j]);
        }   
    }
}
/// Output:
// 0x16f0fadb0
// 0x16f0fadb4
// 0x16f0fadb8
// 0x16f0fadbc
// 0x16f0fadc0
// 0x16f0fadc4

結果は変わらず、jで細かくメモリの位置をずらしていました。


また、3次元配列の定義も同じようにできます。2次元配列を理解していれば、そのまま応用できると思います。

int mdArray[2][2][3]{
    {{1, 3, 5}, {2, 5, 8}},
    {{3, 7, 11}, {4, 9, 14}}};

遊んでいたら、たまたま発見したのですが、二次元配列を一つの波括弧({ })でまとめて初期化することができました。これも、メモリが一続きになっているおかげでしょうか。

// Before
int mdArray[2][3]{
        {1, 3, 5},
        {12, 14, 16}};

// After
int mdArray[2][3]{1, 3, 5, 12, 14, 16};

関数渡しは少し特殊で、以下のように二つ目の要素には、定数を与える必要があります。

void ReceiveMdArray(int mdArray[][3])
{
}

これは、メモリの配列の仕方が要因となっています。この場合は、int[3]の配列が引数になっていると考え、二要素目以降は定数で指定する必要がありました。

参考リスト

感想

多次元配自体は他の言語と似ているように感じました。ただ、関数に渡す時に要素の指定の仕方が特殊なので、注意が必要と感じました。

次回は配列の初期化と、要素へのアクセスについて行います。