函数内修改参数无效是因为C++默认值传递,形参是实参副本;需用引用传递(T&)才能修改原变量,漏写&编译不报错但逻辑失效。

为什么改了参数函数里却没变?——检查你是不是传了值而不是引用
常见现象是:函数内部修改了形参,但调用方的变量值完全没变。这不是逻辑错,大概率是声明时漏了 &。C++ 默认按值传递,void foo(int x) 中的 x 是原变量的副本,改它等于白改。
- 值传递:复制整个对象,安全但可能慢(尤其大结构体、
std::vector) - 引用传递:本质是别名,不复制,改
int& x就等于直接改原变量 - const 引用(
const std::string& s)既能避免拷贝,又防误改,适合只读大对象
函数声明里漏写 & 会怎样?——编译器不会报错,但语义全错
这是最隐蔽的坑:语法完全合法,编译通过,运行也不崩溃,只是逻辑失效。比如想交换两个数:
void swap_wrong(int a, int b) { int t = a; a = b; b = t; } // 没用
正确写法必须带 &:
void swap_correct(int& a, int& b) { int t = a; a = b; b = t; }
- 如果函数需要修改实参,形参类型必须显式写成
T&(或T&&) - 不能对字面量或临时对象绑定非 const 引用:
int& r = 42;错;const int& r = 42;对 - 返回局部变量的引用是未定义行为,编译器通常不警告,但一运行就崩
const T& 和 T 传参性能差多少?——看对象大小和拷贝代价
对 int、double 这类小类型,值传递反而更快(寄存器传,无解引用开销);但对 std::string、自定义类,拷贝构造可能触发内存分配+深拷贝。
立即学习“C++免费学习笔记(深入)”;
- 实测:传一个 1MB 的
std::vector<char></char>,值传递耗时 ≈ 引用传递的 100 倍+ - 原则:只读场景一律优先用
const T&;小 POD 类型(≤ 寄存器宽度)可值传 - 注意:
const T&不阻止移动语义,C++11 后临时对象仍可能被移动,不是万能“零拷贝”
引用参数能默认值吗?——能,但限制极多,慎用
可以写 void f(int& x = some_global),但默认值必须是左值(有名字、能取地址),不能是字面量或临时对象。
- 常见错误:
void g(std::string& s = "hello")——"hello"是字符串字面量,类型是const char[6],转std::string产生临时对象,无法绑定非 const 引用 - 若真要默认,得用
const std::string& s = some_const_string,且some_const_string必须是全局或静态变量 - 更稳妥做法:重载函数,或用指针(
T*)加nullptr判断
& 符号的“肌肉记忆”——少打一个字符,bug 就藏进运行时里,还很难被调试器一眼揪出。











