C++传参时值传递和引用传递的区别
在定义函数时,函数括号中的变量称为 形式参数,简称 形参;而在调用一个函数时括号中的变量称为 实际参数,简称 实参。
在调用函数时,把实参传递给形参有多种方式,下面主要介绍的是值传递方式和引用传递方式。
注意:
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);
}