配列とポインタ #2

C の多次元配列は一応、「配列の配列」になっている。けど、dereference/reference の挙動が、多分、かなり直感に反することになると思う。「配列へのポインタ」でも同じく。要するにポインタの dereference ってのは単純な間接アドレス参照ではないのだ。
詳しくは後で書くかもしれないけど、とりあえず、こんなコードでも。

#include <stdio.h>
#define PTR_OUT(x) printf("%p\n", (x))
int main()
{
    int a[5][10];
    PTR_OUT(a);
    PTR_OUT(&a);
    PTR_OUT(*a);
    PTR_OUT(a[0]);
    PTR_OUT(&a[0]);
    PTR_OUT(&a[0][0]);
}

追記

きむら(K)さんのコメントに従い、sizeof (とあとついでに a + 0 を)追加。

#include <stdio.h>
#define INFO(x) printf("%8s: value = %p, size = %4d\n", #x, (x), sizeof(x))
int main()
{
    int a[5][10];
    INFO(a);
    INFO(a + 0);
    INFO(&a);
    INFO(*a);
    INFO(a[0]);
    INFO(&a[0]);
    INFO(&a[0][0]);
    return 0;
}

C++ で型情報も出すという手もある。

#include <typeinfo>
#include <cstdio>

#define INFO(x) printf("%8s: value = %p, size = %4d, type = %s\n", #x, (x), sizeof(x), typeid(x).name())

int main()
{
    int a[5][10];
    INFO(a);
    INFO(a + 0);
    INFO(&a);
    INFO(*a);
    INFO(a[0]);
    INFO(&a[0]);
    INFO(&a[0][0]);
    return 0;
}

GCC だと typeid(x).name() は mangle された名前になってしまうので、demangle すると分かりやすい。

#include <typeinfo>
#include <cstdio>
#include <cxxabi.h>

#define INFO(x) printf("%8s: value = %p, size = %4d, type = %s\n", #x, (x), sizeof(x), abi::__cxa_demangle(typeid(x).name(), 0, 0, NULL))

int main()
{
    int a[5][10];
    INFO(a);
    INFO(a + 0);
    INFO(&a);
    INFO(*a);
    INFO(a[0]);
    INFO(&a[0]);
    INFO(&a[0][0]);
    return 0;
}

追記 #2

id:mumumu-tan さんのアドバイスに従い

int a[10][10];

から

int a[5][10];

に変更。