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 改指向
*pp 当前指向的 int*p = 30 改值
*pp一级指针 p*pp = &y 改指向
**ppp 当前指向的 int**pp = 30 改值

核心记忆: pp → p → 变量。*pp 找到 p,**pp 再找到 p 当前指向的变量。pp 自身不必改变,**pp 访问的目标也可以随 p 的指向而改变。

注意:若 *pp = NULL,则不能继续执行 **pp,否则会解引用空指针,产生未定义行为。