C语言初学者关于数组指针的深度讨论

时间:2021-01-28 09:01:58

一、什么是数组指针?

即是数组的指针。首先它是一个指针,指向数组,指针本身占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\n",i,j,a[i][j]);
}
}
printf("\n");
printf("\n");
printf("a[1][2]=%d\n",p[1][2]);
printf("a[2][3]=%d\n",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\n",*(p+1));
printf("a[1]的地址是%p\n",(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\n",*p);
printf("a的地址=%p\n",p);

运行结果都是地址,且数值相同,p和*p两者都是指针。