指针 (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 = # // 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,在类型系统中表达约束
建议按顺序学习,因为每个子章节建立在前一个的基础之上。