指针 (Pointers)

开篇故事

想象你拿到一张酒店房卡。房卡上印的不是房间本身,而是一个房间号。你需要拿着这个号码走到对应的门前,刷卡,才能进入房间。

指针就是 C 语言里的「房卡」。它不存储数据本身,而是存储数据所在的地址。&a 是在问「a 住在哪个地址」,*p 是拿着地址 p 走到门前,开门看看里面是什么。

int a = 10;
int *p = &a;   // p 拿着 a 的地址,像房卡指向房门
*p = 20;       // 顺着地址找到 a,修改门里的值

什么是指针

指针是 C 语言中最核心也最让人迷惑的概念。但从根本上说,它很简单:指针就是一个存储内存地址的变量

普通变量存的是值——int x = 42 表示 x 这个盒子里装着 42。指针变量存的是地址——int *p = &x 表示 p 这个盒子里装着 x 的位置。这就是全部。

为什么需要指针?因为 C 语言默认是值传递的。当你把一个变量传给函数时,函数拿到的是副本,不是原件。指针给了你一种方式:「这是我的数据的地址,你直接去那里操作。」这让函数可以修改调用方的变量,也让程序可以动态管理内存。

当然,指针是一把双刃剑。用对了,它让程序高效、灵活;用错了,它会带来段错误、野指针、内存泄漏。每个 C 程序员都经历过这些痛苦。好消息是:规则不多,理解之后你就能驾驭它。

最简单的例子

#include <stdio.h>
#include <stdint.h>

int main(void) {
    int32_t  num = 42;
    int32_t *ptr = &num;   // ptr 存储 num 的地址

    printf("num 的值  = %d\n", num);
    printf("num 的地址 = %p\n", (void *)&num);
    printf("*ptr 的值 = %d  (解引用得到 num 的值)\n", *ptr);

    *ptr = 100;            // 通过指针修改 num
    printf("修改后 num  = %d\n", num);

    return 0;
}

这个例子展示了指针的三个核心操作:声明(int32_t *ptr)、取地址(&num)、解引用(*ptr)。

你会学到什么

指针是一个大家族,各个子章节深入探讨不同的侧面:

  • 指针基础&*、NULL、初始化、野指针,从零掌握指针的核心语法
  • 指针运算 — 指针加减、数组等价性,理解指针如何在内存中移动
  • void* 类型擦除 — 万能指针与类型擦除,类型安全与泛型编程
  • 指针与数组 — 多维数组、数组下标本质,打通指针和数组的关系
  • 指针与函数 — 指针参数、返回指针,用指针实现引用语义
  • const 正确性 — const 指针、指针到 const,在类型系统中表达约束

建议按顺序学习,因为每个子章节建立在前一个的基础之上。

继续学习