一、什么是数组指针?
即是数组的指针。首先它是一个指针,指向数组,指针本身占4个字节。
二、数组指针的使用
int a[3][5]; int (*p)[5]; p=&a; 第二行定义了一个数组指针,p是指针名,指向一个含有5个int类型数据的数组。注意括号一定不要省略,否则就是指针数组。 第三行将数组a首地址赋值给指针。
三、为什么要使用数组指针?
使用数组指针是为了更方便地操作二维数组。来看栗子:
int a[3][5]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}; int (*p)[5]=&a; int i,j; for(i=0;i<3;i++) { for(j=0;j<5;j++) { printf("a[%d][%d]=%d ",i,j,a[i][j]); } } printf(" "); printf(" "); printf("a[1][2]=%d ",p[1][2]); printf("a[2][3]=%d ",p[2][3]);
运行结果显示,a[1][2]==p[1][2],a[2][3]==p[2][3],完全没有问题。当然,这是是指针的数组表示方法。
p[1][2]可以转化为 *(*(p+1)+2)这是指针传统的表示方法。
有人认为,定义一个普通的指针变量来操作二维数组也没问题啊,现在在上面的代码中加入如下:
int *q=&a;
此时该如何用指针q表示a[1][2]呢?有两种方法,一种是指针的传统表示方法:*(q+8);另一种是数组表示法:q[8]。
这时候,“8”是程序员人为计算出来的,不方便,因此操作二维数组用数组指针更适合。
四、详细理解*(*(p+1)+2)
二维数组,即数组的数组,如果一维数组的每个元素都是一个一维数组,那整个数组就成了二维数组。
对于p[1][2]可以解析为:*(*(p+1)+2) ,再解析,*(p+1)操作使指针指向了第二个小数组的首地址并执行了*操作。
问题来了:p+1是地址,*(p+1)呢?
我们知道,如果定义一个普通的指针
int c=5; int q=&c;
那么*q==c==5。对指针进行*操作就是取出指针所指向那片内存上的值。
在以上二维数组的代码中,加入以下代码进行测试:
printf("a[1]的地址是%p ",*(p+1)); printf("a[1]的地址是%p ",(p+1));
得到的结果是:p+1和*(p+1)都是地址,且数值相等。
p+1中p的步长是一个小数组的长度,即5×4个字节;而*(p+1)+1中,步长是一个元素的长度,即4个字节。
二维数组是数组的数组,a是大数组,a[0]、a[1]是小数组,p是大数组的指针,对小数组进行操作;*p是小数组的指针,对元素进行操作。
最后验证一下:
printf("a的地址=%p ",*p); printf("a的地址=%p ",p);
运行结果都是地址,且数值相同,p和*p两者都是指针。