传指针却没改到原变量,是因为指针参数本质是值传递,形参ptr是实参指针的副本;✅正确做法是解引用修改指向内容(如*ptr = 10),❌错误做法是重新赋值ptr本身(如ptr = &x),这仅改变副本,不影响外部指针。

为什么传指针进去却没改到原变量?
直接传指针参数本身是值传递,ptr 在函数内是个副本,但只要你不重新赋值 ptr(比如写成 ptr = &x;),而是解引用修改它指向的内容,就能影响外部变量。常见错误是只改了指针本身,没改它指向的内存。
- ✅ 正确:用
*ptr = 10;修改指针指向的值 - ❌ 错误:写
ptr = new int(20);—— 这只会让函数内的ptr指向新地址,对外部无影响 - ⚠️ 危险:传入空指针(
nullptr)后直接解引用,触发未定义行为
C++ 函数参数该用 int* 还是 int&?
两者都能改外层变量,但语义和约束不同。指针更灵活(可为 nullptr、可重指向),引用更安全(必须绑定有效对象、不能重绑定)。
- 用
int*:适合可能不修改的情况(如“可选输出参数”),或需要在函数内改变指针指向(比如遍历数组时移动指针) - 用
int&:语义更清晰,调用方无法传入空值,编译器能更好优化,且避免意外把指针设为nullptr - 性能上没区别 —— 都是间接访问,底层通常生成相似汇编
修改多个变量时,指针参数怎么组织?
一个函数改多个外部变量,常见做法是多个指针参数,但容易出错(顺序错、漏传、类型混淆)。更稳妥的方式是封装成结构体或用引用参数。
- 不推荐:
void parse(int* a, double* b, bool* valid)—— 调用时易传错顺序,且nullptr判断分散 - 推荐结构体方式:
struct ParseResult { int a; double b; bool valid; };然后传ParseResult& out,语义明确、不易出错 - 若必须用指针,至少加注释说明每个参数是否可为空,并在函数开头统一校验:
if (!a || !b || !valid) return;
const 修饰指针时,到底哪个不能改?
看 const 紧挨谁:int* const ptr 表示指针本身不可变(不能指向别处),但内容可改;const int* ptr 或 int const* ptr 表示内容不可改,指针可变;const int* const ptr 两者都不可变。
立即学习“C++免费学习笔记(深入)”;
- 想通过指针修改外部变量 → 用
int* ptr或const int* ptr不行(后者禁止写) - 函数声明里写
void f(const int* p),调用方仍可传非 const 变量,只是函数内部不能改它 - 如果函数本意是“只读”,却用了
int* p,既误导调用方,也失去编译器保护
const —— 它不是装饰,是契约。一旦漏掉,后续有人误改,调试起来很隐蔽。


















