配列の配列とポインタの配列


前回の投稿で知識が足りず,

個人的に*ptmp[]は多次元配列だと思っているのだが,宣言すら失敗してしまう.

という間違い発言をしてしまった.
丁寧に @angel_p_57 さんから間違い発言を訂正してくれました.

結論から言えば,私の頭で理解できる許容量を超えた出来事だと言うこと.
早速ソースコードをさらす.
最初の数行:D0〜D3は普通の配列
D:ポインタの配列
pp・hoge:配列の配列
boo:いわゆるダブルポインタ変数
pppp:配列へのポインタ

#include <stdio.h>

int main(void){
    int D0[10] = {0};
    int D1[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    int D2[10] = {2, 2, 99, 2, 2, 2, 2, 2, 2, 2};
    int D3[10] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3};
    int *D[10] = {D0, D1, D2, D3};
    int pp[4][10] = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
                {10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
                {20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
                {30, 31, 32, 33, 34, 35, 36, 37, 38, 39}
                };
    int hoge[][10] = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
                {10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
                {20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
                {30, 31, 32, 33, 34, 35, 36, 37, 38, 39}
                };
    int **boo;
    int (*pppp)[10];

    printf("1.D[2][2]:[%d]\n", D[2][2] );
    printf("2.D[2][2]:[%d]\n", (*(D+2))[2] );
    printf("3.D[2][2]:[%d]\n", *((*(D+2))+2) );
    printf("4.D[2][2]:[%d]\n", *((D[2])+2) );
    printf("5.pp[2][2]:[%d]\n", pp[2][2] );
    printf("6.pp[2][2]:[%d]\n", (*(pp+2))[2] );
    printf("7.pp[2][2]:[%d]\n", *((*(pp+2))+2) );
    printf("8.pp[2][2]:[%d]\n", *((pp[2])+2) );

    boo = &D[0];
    printf("9.boo[2][2]:[%d]\n", boo[2][2] );
    printf("10.boo[2][2]:[%d]\n", *((*(boo+2))+2) );

    pppp = hoge;
    printf("11.pppp[2][2]:[%d]\n", pppp[2][2] );
    printf("12.pppp[2][2]:[%d]\n", *((*(pppp+2))+2) );

    return 0;
}

以下,出力結果

一応意図した内容が出力されている.しかし無理矢理出力させているだけなので全然理解できていないorz
世間一般として1.5.9.11.の4種類を2次元配列として出力しているといえるだろう.
しかし,C言語に多次元配列(2次元配列以上の配列)は存在しない.そのため2.3.4.6.7.8.10.12.のような記述方法でも問題なく出力できる.
そして11.12.は配列へのポインタを利用して出力している.理解してコーディングしたつもりだが,やっぱり理解していないorz
う〜ん.C言語は奥が深い.

※余談
 当然ここまで調べたらキャストなどのことも目にする.しかし,ここでは触れないことにしよう(色々今回は消化不良もあり,次に進めないorz).

以上ですorz

参考URL

C言語の宣言、なぜそう書くのか?
Pointerの超基礎学習#2
多次元配列の実現
文法上多次元配列はない
互換性のないポインタ型からの代入
10-4.ポインタのポインタ