看一下这个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;
}