1. 使用指针访问数组
指针类型的加减运算可以使指针内保存的首地址移动。
指针类型加n后。首地址向后移动n * 步长
字节。
指针类型减n后。首地址向前移动n * 步长
字节。
步长为指针所指向的类型所占空间大小。
例如:
int *p = (int *)100;
p + 1,结果为首地址向后移动sizeof(int)字节,即104。 p - 1,结果为首地址向前移动sizeof(int)字节,即96。
因此,指针加减运算对于访问在内存中连续排布的数据对象非常方便。
而数组这种数据对象,每个元素在内存中一定是连续排布的。下面,我们来探究怎样使用指针访问数组。
2. 使用第一个元素获取数组首地址
在初识数组那一节中,我们已经学会了使用下标来访问数组元素。
#include <stdio.h>
int main()
{
int arr[5] = {111, 222, 333, 444, 555};
printf("%d\n", arr[0]); // 第1个元素
printf("%d\n", arr[1]); // 第2个元素
printf("%d\n", arr[2]); // 第3个元素
printf("%d\n", arr[3]); // 第4个元素
printf("%d\n", arr[4]); // 第5个元素
return 0;
}
既然数组元素在内存中的存储可以保证是连续的,那么第一个元素的首地址,就是整个数组的首地址。
我们可以使用取地址运算符&,获取第一个元素的首地址和空间大小,即获取一个int *
类型的指针。
int *p = &arr[0]; // 从第1个元素获取数组首地址
p; // 指向第1个元素
p + 1; // 指向第2个元素
p + 2; // 指向第3个元素
p + 3; // 指向第4个元素
p + 4; // 指向第5个元素
通过取值运算符*,可以使用指针中的首地址和空间大小访问或修改目标数据对象。
#include <stdio.h>
int main()
{
int arr[5] = {111, 222, 333, 444, 555};
int *p = &arr[0];
printf("%d\n", *p); // 第1个元素
printf("%d\n", *(p + 1)); // 第2个元素
printf("%d\n", *(p + 2)); // 第3个元素
printf("%d\n", *(p + 3)); // 第4个元素
printf("%d\n", *(p + 4)); // 第5个元素
return 0;
}
注意,表达式p + 1
必须先被括号包裹,再使用取值运算符*。
这是因为取值运算符*的优先级高于算术运算符。
我们需要先让首地址移动,再进行取值操作。
若不使用括号,*p
会先被取值,之后值再被加1。
不使用括号:*p
的值为111,*p + 1
的结果为112。
使用括号:
(p + 1)
使得首地址移动到第二个元素,*(p + 1)
得到结果为222。