看一下这个C代码输出什么?
#include <stdio.h>int main(){int array[5][4] ={{1,2,3,4},{11,12,13,14},{21,22,23,24},{31,32,33,34},{41,42,43,44}};int** p = array;printf("%d\n",*p);printf("%d\n",array[0][0]);return 0;}
先简单思考下,然后我们再一起分析分析
- array 是一个二级数组
- p 是一个指针

二级指针和一级指针的图示
array 从数值上来说是一个地址,这个地址是二维数组的首地址。
- p = array
可以认为把 array 数组的首地址赋值给指针变量 p。
二级指针的示例代码
int b = 120;int *p1 = &b;int** p = &p1;printf("%d\n",**p);
这个示例就是我上面耳机指针的图示对应。
那如果是二级指针呢?
我们编译上面的代码
zhizhen.c: In function ‘main’:zhizhen.c:5:15: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]int** p = array;^zhizhen.c:6:12: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]printf("%d\n",*p);
第一个警告是类型不匹配,第二个警告是我们输出的p 类型是 int 但是我们却使用 %d 来输出。
再说回前面的题目,二级指针和二维数组
#include <stdio.h>int main(){int array[5][4] ={{1,2,3,4},{11,12,13,14},{21,22,23,24},{31,32,33,34},{41,42,43,44}};int** p = array;printf("%d\n",*p);printf("%d\n",array[0][0]);return 0;}
这个程序输出多少呢?
我们知道array 我们就把它当成一个地址
那么 p 就是把p这个地址的值给取出来,array是数组的首地址,那么p 应该就可以取到二维数组首元素的值。
所以输出应该是
1
1
我们执行下程序试试
如我所料
既然你这么厉害,我把代码修改一下
#include <stdio.h>int main(){int array[5][4] ={{1,2,3,4},{11,12,13,14},{21,22,23,24},{31,32,33,34},{41,42,43,44}};int** p = array;printf("%d\n",*(p+1));printf("%d\n",array[0][0]);return 0;}
这个代码输出什么?
直接分析一下,p 的类型是 int ,p +1 ,它跳过的地址大小应该是
`sizeof(int)<br />学指针的同学把这个记清楚,一定会有所收获。<br />所以<br />(p+1)<br />其实就是<br />(&array + sizeof(int))
sizeof(int) = 8<br />那就应该是输出<br />3
1`
为了验证上面,我们的代码修改如下
#include <stdio.h>int main(){int array[5][4] ={{1,2,3,4},{11,12,13,14},{21,22,23,24},{31,32,33,34},{41,42,43,44}};int** p = array;printf("sizeof(int**):%d\n",sizeof(int**));printf("%d\n",*(p+1));printf("%d\n",array[0][0]);return 0;}

那怎么用一个指针来指向一个二维数组呢?
其实不管是多少维度的数组,它都是直尺,一直变长的直尺,我们把二维数组说成长宽之类的,都是为了方便我们理解。
我们可以这样声明一个二维数组
#include <stdio.h>int main(){int array[5][4] ={1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44};int** p = array;printf("sizeof(int**):%d\n",sizeof(int**));printf("%d\n",*(p+1));printf("%d\n",array[0][0]);return 0;}
所以,我们如果想用一个二维数组,可以用一个一维指针指向一个二维数组
#include <stdio.h>int main(){int array[5][4] ={1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44};int* p = array;printf("%d\n",*(p+1));printf("%d\n",array[0][0]);return 0;}

当然,也可以用二维指针来指向二维数组
#include <stdio.h>int main(){int array[5][4] ={1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44};int(*p)[4]= &array[0];printf("%d\n",*(*(p+0)+0));printf("%d\n",*(*(p+0)+1));printf("%d\n",*(*(p+1)+0));printf("%d\n",*(*(p+1)+1));printf("%d\n",array[0][0]);return 0;}

还可以这样的
#include <stdio.h>int main(){int array[5][4] ={1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44};int(*p)[4]= &array[0];printf("%d\n",(*p)[0]);printf("%d\n",(*p)[1]);printf("%d\n",(*p)[2]);printf("%d\n",(*p)[3]);p++;printf("%d\n",(*p)[0]);printf("%d\n",(*p)[1]);printf("%d\n",(*p)[2]);printf("%d\n",(*p)[3]);printf("%d\n",array[0][0]);return 0;}

还可以改成这样
#include <stdio.h>int main(){int array[5][4] ={1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44};int(*p)[4]= &array[0];printf("%d\n",(*p)[0]);printf("%d\n",(*p)[1]);printf("%d\n",(*p)[2]);printf("%d\n",(*p)[3]);printf("%d\n",(*p)[4]);printf("%d\n",(*p)[5]);printf("%d\n",(*p)[6]);printf("%d\n",(*p)[7]);printf("%d\n",array[0][0]);return 0;}

