Z
ZHANK

指针与数组

数组名即指针、通过指针遍历数组、指针 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(指针大小),不是数组大小
}