指针与数组
数组名即指针、通过指针遍历数组、指针 vs 下标性能
指针与数组
"数组名就是指向第一个元素的指针"——这句话不算全准确,但足够帮助你理解指针和数组的关系。
学完本章你将: 数组名退化为指针、通过指针遍历数组、下标 vs 指针性能。
数组名 → 指针
c
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30, 40, 50};
int *p = arr; // arr 自动退化为 &arr[0]
printf("%d\n", *p); // 10
// 以下三种写法等价
printf("%d\n", arr[2]); // 下标
printf("%d\n", *(arr + 2));// 指针运算
printf("%d\n", *(p + 2)); // 指针运算
return 0;
}
通过指针遍历数组
c
int arr[] = {1, 2, 3, 4, 5};
int *p = arr;
// 方式 1:下标
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
// 方式 2:指针++(经典 C 风格)
for (int i = 0; i < 5; i++) {
printf("%d ", *p++); // 先取 *p,再 p++
}
// 方式 3:边界指针
int *end = arr + 5;
for (int *p = arr; p < end; p++) {
printf("%d ", *p);
}
arr 与 &arr 的区别
c
int arr[5] = {0};
printf("%p\n", arr); // 第一个元素的地址
printf("%p\n", &arr[0]); // 同上
printf("%p\n", &arr); // 整个数组的地址(数值相同)
// arr + 1 → 指向 arr[1](跳 1 个元素)
// &arr + 1 → 指向 arr 之后(跳 1 个数组 = 跳 5 个元素)
数组传参的退化
c
// 这三种写法完全等价——都退化为指针
void func1(int arr[]) { }
void func2(int arr[10]) { } // 10 被忽略!
void func3(int *arr) { }
// 函数内 sizeof(arr) 拿到的是指针大小,不是数组大小!
void bad(int arr[]) {
printf("%zu\n", sizeof(arr)); // 8(指针大小),不是数组大小
}