配列とポインタ #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; }