指针遍历数组
使用指针遍历数组是 C 语言中常见的模式,比下标访问在某些情况下更高效(减少乘法运算)。指针遍历的精髓在于利用指针运算的简洁性,同时确保不越界。
基本遍历
int arr[5] = {10, 20, 30, 40, 50};
/* 下标方式 */
for (int i = 0; i < 5; i++)
printf("%d ", arr[i]);
/* 指针方式 */
for (int *p = arr; p < arr + 5; p++)
printf("%d ", *p);
/* 等价的 while */
int *p = arr;
int *end = arr + 5;
while (p < end) {
printf("%d ", *p);
p++;
}
反向遍历
int arr[5] = {10, 20, 30, 40, 50};
/* 反向指针遍历 */
for (int *p = arr + 4; p >= arr; p--)
printf("%d ", *p);
/* 输出:50 40 30 20 10 */
注意:当数组为空时,p >= arr 在 p 为无符号类型时可能出问题。使用有符号类型或额外检查。
双指针技巧
查找两个数的和等于目标:
int *find_pair(int arr[], int n, int target)
{
int *left = arr;
int *right = arr + n - 1;
while (left < right) {
int sum = *left + *right;
if (sum == target)
return left;
else if (sum < target)
left++;
else
right--;
}
return NULL;
}
反转数组:
void reverse(int arr[], int n)
{
int *left = arr;
int *right = arr + n - 1;
while (left < right) {
int temp = *left;
*left = *right;
*right = temp;
left++;
right--;
}
}
指针与下标的性能
现代编译器优化后,指针遍历和下标遍历通常没有性能差异。选择可读性更好的方式:
/* 下标通常更易读 */
for (int i = 0; i < n; i++)
arr[i] = i;
/* 指针在某些场景更简洁 */
while (*p != '\0')
p++;
常见错误
越界遍历:
int arr[5];
int *p = arr;
for (int i = 0; i <= 5; i++) /* 错误:<= 导致越界 */
printf("%d ", *p++);
空数组:
int arr[0];
int *p = arr;
int *end = arr + 0;
while (p < end) { /* 不会执行,安全 */
/* ... */
}
最佳实践
- 优先使用下标遍历(可读性更好)
- 指针遍历时用
<而非!=作为结束条件 - 保存结束指针避免重复计算
- 复杂遍历考虑双指针技巧
- 始终确保指针在数组范围内