Date:2012-10-24
看下面的代码:
#include <stdio.h> int main(int argc, const char *argv[]) { int a[2][3] = { {1, 2, 3}, {4, 5, 6} }; printf("%p\n", a); printf("%p\n", *a); return 0; }
会发现a和*a竟然是一样的.
其实这6个数字是连续存储的:
+---+---+---+---+---+---+ | 1 | 2 | 3 | 4 | 5 | 6 | +---+---+---+---+---+---+
那就是说,存储的跟一维数组完全一样.
如果我们这么定义 a[2][3]:
int a[2][3] = { 1, 2, 3, 4, 5, 6 };
会发现编译和执行都正常.验证了这6个数据是连续存储的.
而a存储着a[0][0]的地址.
看下面的代码:
int main(){ int a[1][2][3] = { 1, 2, 3, 4, 5, 6 }; printf("%p\n", a); printf("%p\n", *a); printf("%p\n", **a); printf("%d\n", ***a); return 0; }
会发现a,*a,**a都是一样的.最后一个输出数据1.
所以这就摸清了规律了.
所以对上面的定义方式来说,a根本不是一个二级指针.
既然是连续存储,加入2句code:(存储方式就是一维数组的方式)
int *b = (int *)a; printf("%d\n", *b);
会看到输出了1.也就是,只要这种存储方式,数组名永远是首元素的地址.上式中把a强制赋值给了b,b记录着a[0][0]的地址
那对于下面的code呢?,并不是上面我们讨论的存储方式:
#include<stdio.h> int main(){ int m[3] = {1, 2, 3}; int n[3] = {4, 5, 6}; int *a[2] = {m, n}; return 0; }
并且这里的a与*a也不相等.
这个问题很不好理解.欢迎交流!
---over----