一、问题
指针到底该如何操作数组?
二、解答
实践和程序结果可以让我们产⽣疑问,但同时也是解决问题的重要依据,所以⾸先看 ⼀个演示程序。代码如下。
#include <stdio.h>
int main()
{int i, a[6] = {19, 89, 2, 1, 12, 25};int *p = a;for (i = 0; i <= 5; i++){printf("(a+%d)=%d\n", i, *(a + i));}printf("\n");for (i = 0; i <= 5; i++){printf("*(p+%d)=%d\n", i, *(p + i));}return 0;
}
运⾏结果如图所示。
(a+0)=19
(a+1)=89
(a+2)=2
(a+3)=1
(a+4)=12
(a+5)=25*(p+0)=19
*(p+1)=89
*(p+2)=2
*(p+3)=1
*(p+4)=12
*(p+5)=25
从图中可以看出,数组元素 a[0] 和指针 *(p+0) ,a[1] 和 *(p+1) ……它们每组取出的值都分别相同,也就说明在引⽤指针后,对数组的操作可以使⽤指针,⽽且可以更⽅便地进⾏元素的访问。
当使⽤指针指向数组的⾸地址后,指针可以像数组的别名⼀样,进⾏下标操作,但是这些似乎意义都不⼤,指针操作数组的优点主要体现在对数组元素进⾏顺序操作的时候。
在上⾯的程序中有这样⼀段代码。
for (i = 0; i <= 5; i++)
{printf("*(p+%d)=%d\n", i, *(p + i));
}
上⾯这段代码完全可以写成如下的格式。
for (i = 0; i <= 5; i++)
{printf("*p++=%d\n", *p++);
}
两段代码中,第⼆段就是每执⾏⼀次循环,指针先执⾏⼀次取值运算,然后⾃加⼀次, 将指针位置后移⼀个单位,⼀直循环操作,直到循环体结束。要注意的是,循环结束后, 指针的位置是在数组所占内存单元的后⾯⼀个内存单元,⽽不是指向数组的最后⼀个内存单元。
上⾯代码中还有这样⼀段代码。
for (i = 0; i <= 5; i++)
{printf("(a+%d)=%d\n", i, *(a + i));
}
那么,这段代码可不可以改成如下形式呢?
for (i = 0; i <= 5; i++)
{printf("*a++=%d\n", *a++);
}
很遗憾,编译出错。这样看来,数组名和指针还是有区别的。那么为什么会出错呢? 原因在于指针是指针变量,可以通过运算改变它们的值,但是数组名是常量,常量的值是不允许改变的。
三、总结
操作计算中的⼏个区分问题:
*p++,由于 ++ 是后置运算,这⾥先得到的是 p 指向变量的值,即先执⾏*p,然后执⾏ ++ 运算。*(++p),这⾥先运算 ++p,也就是 p 先⾃增⼀次,然后进⾏取值运算。(*p)++,先将 p 指针指向的地址值中的数据取出,然后将取出的数据值⾃增⼀次运算。