C言語における多次元配列と配列へのポインタについて

C言語における多次元配列についてはJIS規格で以下のように定義されている。

連続した添字演算子は、多次元配列の要素を指し示す。Eが次元 i ✖️ j ✖️ … ✖️ k をもつ n 次元配列(n ≧ 2)である場合、E(左辺値以外として用いた場合。)は次元 j ✖️ … ✖️ k をもつ (n – 1)次元配列へのポインタに型変換する。

プログラム言語C JIS X 3010 : 2003

簡単に言うとn次元配列は(n – 1)次元配列へのポインタへ成り下がるという事である。これを確認するための3次元配列を例にしたプログラムを記載しておく。

#include <stdio.h>
#include <stddef.h>

void f3(int *p, size_t sz)
{
    for(size_t i = 0; i < sz; i++)
    {
        printf("%d ", p[i]);
    }
    printf("\n");

    //出力結果 
    //1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
}

void f2(int (*p)[4], size_t sz) //*pは1次元配列
{
    //*pは0次元配列(先頭要素)へのポインタへ成り下がる。
    //データ型は int *
    f3(*p, sz);
}

void f1(int (*p)[3][4], size_t sz) //*pは2次元配列
{
    //*pは1次元配列へのポインタへ成り下がる。
    //データ型は int (*)[4] 
    f2(*p, sz);
}

int main()
{
    //arrは3次元配列
    int arr[2][3][4] = {{{1,2,3,4},{5,6,7,8},{9,10,11,12}},
               {{13,14,15,16},{17,18,19,20},{21,22,23,24}}};

    size_t arr_size = sizeof(arr)/sizeof(int);

    //arrは2次元配列へのポインタへ成り下がる。
    //データ型は int (*)[3][4]
    f1(arr, arr_size);

    return 0;
}

なお関数 f1 と f2 の配列パラメータは以下のように書いても良い。

void f2(int p[][4], size_t sz) //*pは1次元配列
{
    //*pは0次元配列(先頭要素)へのポインタへ成り下がる。
    //データ型は int *
    f3(*p, sz);
}

void f1(int p[][3][4], size_t sz) //*pは2次元配列
{
    //*pは1次元配列へのポインタへ成り下がる。
    //データ型は int (*)[4] 
    f2(*p, sz);
}

コメント