函数参数传递
| 特性 | 值传递 | 引用传递 | 常引用传递 | 指针传递 |
|---|---|---|---|---|
| 语法 | void f(int x) | void f(int &x) | void f(const int &x) | void f(int *x) |
| 能否创建副本 | ✅ 是 | ❌ 否 | ❌ 否 | ❌ 否 |
| 能否修改原变量 | ❌ 否 | ✅ 是 | ❌ 否 | ✅ 是 |
| 调用方式 | f(a) | f(a) | f(a) | f(&a) |
| 空值支持 | ❌ 不支持 | ❌ 不支持 | ❌ 不支持 | ✅ 支持 nullptr |
| 性能(大型对象) | 较差(需拷贝) | 较好(避免拷贝) | 较好(避免拷贝) | 较好(避免拷贝) |
| 典型用途 | 小型数据、只读输入 | 需要修改实参、避免拷贝 | 只读大型对象、输入参数 | 需要操作地址、可选参数 |
选择建议:
值传递
按值传递参数,先创建实参的副本,然后将副本传递给函数,函数内对副本的修改不会影响调用者的变量。
cpp
double cube(double x); // 函数原型
...
// 按值传递
double volume = cube(side); // 函数调用- 创建副本:调用时拷贝实参
- 副本操作:函数内操作的是副本
- 副本销毁:函数返回时副本被销毁
引用传递
按引用传递参数,允许函数直接操作调用者的变量,而不是操作变量的副本。
cpp
void swap(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int x = 5, y = 10;
swap(x, y); // x 变为 10,y 变为 5
}- 直接操作原变量:不创建副本,函数内的修改直接影响原变量。
- 避免拷贝开销:对于大型对象(如
vector、string),引用传递可避免拷贝。 - 可返回多个值:对于引用参数,函数可以 "输出" 多个值。
常引用传递
常引用是 C++ 中最推荐的参数传递方式之一,特别适用于大型对象和只读场景。
cpp
void print(const std::string &s) {
std::cout << s << std::endl;
// s = "new"; // 编译错误!不能修改
}- 避免拷贝:不复制实参,提高性能。
- 保证只读:防止函数以外修改传入的对象。
指针传递
按指针传递参数,允许函数通过指针间接操作变量,提高了灵活性但需要谨慎使用。
cpp
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 5, y = 10;
swap(&x, &y); // 传入地址,x 变为 10,y 变为 5
}- 间接操作 - 通过解引用
*ptr访问原变量 - 可为空 - 指针可以是
nullptr,需检查 - 可重新指向 - 指针可以在函数内指向其他对象