08 指针传参与二级指针
1. 函数接收的是指针的副本
void change(int *p)
{
p = NULL; // 只改变函数内部的 p
}
int x = 10;
int *ptr = &x;
change(ptr); // ptr 仍指向 x
C 函数参数按值传递。传入 ptr 时,复制的是它保存的地址;在函数内给形参 p 重新赋值,不会改变调用者的 ptr。
2. 二级指针可以修改调用者的一级指针
void redirect(int **pp, int *target)
{
*pp = target;
}
int x = 10, y = 20;
int *p = &x;
redirect(&p, &y); // p 改为指向 y
p保存x或y的地址,类型为int *。&p是指针变量p自身的地址,类型为int **。pp接收&p,所以*pp就是调用者的p。
3. *pp 改指向,**pp 改目标值
int x = 10, y = 20;
int *p = &x;
int **pp = &p;
*pp = &y; // 等价于 p = &y:修改 p 的指向
**pp = 30; // 等价于 *p = 30:修改 y 的值
// 最终:x == 10,y == 30
初始:pp ──> p ──> x (10) y (20)
改向:pp ──> p ──────────────> y (20)
赋值:pp ──> p ──────────────> y (30)
x 仍为 10
| 表达式 | 对应对象 | 操作示例 |
|---|---|---|
p | 一级指针本身 | p = &y 改指向 |
*p | p 当前指向的 int | *p = 30 改值 |
*pp | 一级指针 p | *pp = &y 改指向 |
**pp | p 当前指向的 int | **pp = 30 改值 |
核心记忆: pp → p → 变量。*pp 找到 p,**pp 再找到 p 当前指向的变量。pp 自身不必改变,**pp 访问的目标也可以随 p 的指向而改变。
注意:若
*pp = NULL,则不能继续执行**pp,否则会解引用空指针,产生未定义行为。