注意:
1、参数的传递是单向的,只能由实参传给形参;
2、函数的形参只有在被调用时才会给它分配空间,调用结束分配的内存便会被释放;
3、值传递中包括指针传递,指针也是一个变量,这个变量存储的是一个地址,值传递时,传递的都是实参的一个拷贝。
在调用一个函数时,会给函数的形参分配空间,并用实参对形参初始化。在函数体中对形参的修改并不能影响到实参,修改的只是实参的副本——形参。
例1:值传递
#include <iostream> using namespace std; void Swap(int a, int b){ int tmp = a; a = b; b = tmp; cout << "Swap::a=" << a << endl; cout << "Swap::b=" << b << endl; } int main(){ int a = 10, b = 20; Swap(a, b); cout << "main::a=" << a << endl; cout << "main::b=" << b << endl; }
可以看到值传递时,对形参的修改并不能作用到实参上,操作的只是实参的副本——形参。
例2:值传递——指针传递
#include <iostream> using namespace std; void Swap(int *a, int *b){ int *tmp = a; a = b; b = tmp; cout << "Swap::a=" << *a << endl; cout << "Swap::b=" << *b << endl; } int main(){ int a = 10, b = 20; Swap(&a, &b); cout << "main::a=" << a << endl; cout << "main::b=" << b << endl; }
可以看到,虽然Swap函数中交换了a和b的地址,但是实际交换的是交换了Swap函数中指针变量a和指针变量b所存储的地址,对main函数中的a和b没有任何影响。要修改main函数中的a和b,就需要对指针a和指针b所存储的地址进行修改。
在传参数时进行引用传递,就相当于给实参起了个别名,这个别名就是形参,对形参的操作会作用到实参上。
#include <iostream> using namespace std; void Swap(int &a, int &b){ int tmp = a; a = b; b = tmp; cout << "Swap::a=" << a << endl; cout << "Swap::b=" << b << endl; } int main(){ int a = 10, b = 20; Swap(a, b); cout << "main::a=" << a << endl; cout << "main::b=" << b << endl; }
可以看到,Swap函数和main函数中的a和b都发生了交换。
按值传参时,因为要对形参开辟空间,并用实参初始化,初始化时会调用拷贝构造函数。
#include <iostream> using namespace std; class A{ int val; public: A(int x = 0):val(x){ cout << "A(int x = 0)" << endl; } ~A(){ cout << "~A()" << endl; } A(const A& a):val(a.val){ cout << "A(const A&)" << endl; } void show(){ cout << val << endl; } }; void show(A a){ a.show(); } int main(){ A a = 10; show(a); }
引用传递并不需要给形参开辟额外的空间,只需要给传进来的实参起个别名,所以引用传递的效率会比按值传递效率高。
#include <iostream> using namespace std; class A{ int val; public: A(int x = 0):val(x){ cout << "A(int x = 0)" << endl; } ~A(){ cout << "~A()" << endl; } A(const A& a):val(a.val){ cout << "A(const A&)" << endl; } void show(){ cout << val << endl; } }; void show(A &a){ a.show(); } int main(){ A a = 10; show(a); }