C++的函数参数传递方式,可以是传值方式,也可以是传引用方式。传值的本质是:形参是实参的一份复制。传引用的本质是:形参和实参是同一个东西。
1.值传递
传值方式下,形参是实参的拷贝:重新建立了变量,变量取值和实参一样。
这种情况下,修改函数内的形式参数,并不会影响到函数外的实际参数。
#include <iostream>
using namespace std;
void swap_by_value(int x, int y) {
int tmp = x;
x = y;
y = tmp;
cout << "&x: " << &x << ", &y: " << &y << endl;
cout << "x: " << x << ", y: " << y << endl;
}
int main()
{
cout << "swap_by_value:" << endl;
int a = 3;
int b = 7;
cout << "before: a: " << a << ", b: " << b << endl;
cout << "&a: " << &a << ", &b: " << &b << endl;
swap_by_value(a, b);
cout << "after : a: " << a << ", b: " << b << endl;
return 0;
}
运行结果如下图所示,由于形参是实参的拷贝,形参和实参的地址是不同的。因此改变形参的值,并不会影响外部实参的值。
当只在函数内部改变参数,且不希望这个改变影响外部参数时,采用值传递。
2.指针传递
向函数传递参数的指针,即把参数的地址copy给形式参数。(传指针实际还是传值)
在函数内,该地址用于访问要用到的实际参数,这意味着修改形式参数会影响实际参数。
#include <iostream>
using namespace std;
void swap_by_pointer(int* x, int* y) {
int tmp = *x;
*x = *y;
*y = tmp;
cout << "&x: " << &x << ", &y: " << &y << endl;
cout << "x: " << x << ", y: " << y << endl;
}
int main()
{
cout << "swap_by_pointer:" << endl;
int a = 3;
int b = 7;
cout << "before: a: " << a << ", b: " << b << endl;
cout << "&a: " << &a << ", &b: " << &b << endl;
swap_by_pointer(&a, &b);
cout << "after : a: " << a << ", b: " << b << endl;
return 0;
}
运行结果如下图所示,形参为指向实参地址的指针,因此对形参的指向操作,就相当于对实参本身进行操作。但形参自己的地址与实参不同。
3.引用传递
传值是C和C++都能用的方式。传引用则是C++比C所不同的地方。传引用,传递的是实参本身,而不是实参的一个拷贝,形参的修改就是实参的修改。
相比于传值,传引用的好处是省去了复制,节约了空间和时间。假如不希望修改变量的值,那么请选择传值而不是传引用。
#include <iostream>
using namespace std;
void swap_by_ref(int& x, int& y) {
int tmp = x;
x = y;
y = tmp;
cout << "&x: " << &x << ", &y: " << &y << endl;
cout << "x: " << x << ", y: " << y << endl;
}
int main()
{
cout << "swap_by_ref:" << endl;
int a = 3;
int b = 7;
cout << "before: a: " << a << ", b: " << b << endl;
cout << "&a: " << &a << ", &b: " << &b << endl;
swap_by_ref(a, b);
cout << "after : a: " << a << ", b: " << b << endl;
return 0;
}
运行结果如下图所示,形参相当于是实参的“别名”,显然,形参a和实参a完全一样:值相同,地址也相同。说明形参不是实参的拷贝,而是就是实参本身。