指针、空间地址
编写一个功能函数,让一个变量增加10
-
编写函数 add10_value,形参是 int x
-
在函数内部对 x 加 10 并输出
-
在 main 中调用后再输出原变量,观察差异
参考代码
#include <iostream> using namespace std; void add10_value(int x) {x += 10;cout << "inside add10_value, x = " << x << endl; } int main() {int n = 5;add10_value(n);cout << "after add10_value, n = " << n << endl; // 依旧是 5return 0; }
关键现象:add10_value 得到的是 n 的副本,副本改了,原变量还是 5。
二、地址传递:指向同一块内存
-
改写为 add10_ptr,形参是 int* p
-
在函数里 *p += 10;
-
主函数传入 &n,观察变化
参考代码
#include <iostream> using namespace std; void add10_ptr(int* p) {*p += 10; // 解引用,对真实内存写入cout << "inside add10_ptr, *p = " << *p << endl; } int main() {int n = 5;int* m = &n;add10_ptr(m);cout << "after add10_ptr, n = " << n << endl; // 变成 15return 0; }
为什么能改掉?因为 p 保存的就是 n 的地址,同一块空间。
三、* 与 & 的含义
*(解引用):根据地址找到对应的空间 & (取地址):把空间的地址取出来
小结 int a = 5; // a 是 5 int* p = &a; // p 存的是 a 的地址 *p = 8; // 在地址处写 8,a 立刻变 8
四、多重指针:内存里再存一张门牌号 概念 指针本质也是变量,也住在一块内存。如果我们想操作“指针自身指向哪里”,就需要再保存一次它的地址——这就是指针的指针。
任务
-
写函数 reset_zero(int** pp),让它把 **pp 置 0
-
主函数里先让 p 指向 n,再把 &p 传进去
-
输出验证
参考代码
#include <iostream> using namespace std; void reset_zero(int** pp) {**pp = 0; // 找到最深层的 int 并清零 } int main() {int n = 42;int* p = &n;reset_zero(&p); // &p 是指向指针的指针cout << "after reset_zero, n = " << n << endl; // 输出 0return 0; }
过程剖析 pp 里保存的是 p 的地址 *pp 取得 p 本身(即保存着 n 地址的那块内存) **pp 跳两次,最终落到 n 所在的真实位置
练习延伸
-
写 swap_ptrs(int* p1, int* p2),交换两个指针的指向
-
验证指针交换是否成功
-
写 swap_ptrs(int** p3, int** p4),交换两个指针的指向
-
验证指针交换是否成功
-
思考当 p1、p2、p3、p4 时修改的到底是谁