在平衡树左旋,右旋函数中,我们使用了引用传递的方式,在这里补充一下函数的三种传递方式:
1、按值传递(pass by value)
2、地址传递(pass by pointer)
3、引用传递(pass by reference)
1、按值传递的过程为:首先计算出实参表达式的值,接着给对应的形参变量分配一个存储空间,该空间的大小等于该形参类型的,然后把以求出的实参表达式的值一一存入到形参变量分配的存储空间中,成为形参变量的初值,供被调用函数执行时使用。这种传递是把实参表达式的值传送给对应的形参变量,故称这种传递方式为“按值传递”。
使用这种方式,调用函数本身不对实参进行操作,也就是说,即使形参的值在函数中发生了变化,实参的值也完全不会受到影响,仍为调用前的值。
/*
pass By value
*/
#include <iostream>
using namespace std;
void swap(int,int);
int main()
{
int a = 3, b = 4;
cout << "a = " << a << ", b = "
<< b << endl;
swap(a,b);
cout << "a = " << a << ", b = "
<< b << endl;
return 0;
}
void swap(int x, int y)
{
int t = x;
x = y;
y = t;
}
输出结果:
a=3,b=4
a=3,b=4
2、地址传递与按值传递的不同在于,它把实参的存储地址传送给对应的形参,从而使得形参指针和实参指针指向同一个地址。因此,被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参。
#include <iostream>
using namespace std;
void swap(int*, int*);
int main()
{
int a = 3, b = 4;
cout << "a=" << a << ", b=" << b << endl;
swap(&a, &b);
cout << "a=" << a << ", b=" << b << endl;
system("pause");
return 0;
}
void swap(int *x, int *y){
int t = *x;
*x = *y;
*y = t;
}
输出结果
a=3,b=4
a=4,b=3
按值传递方式容易理解,但形参值的改变不能对实参产生影响。
地址传递方式虽然可以使得形参的改变对相应的实参有效,但如果在函数中反复利用指针进行间接访问,会频繁的用到间接访问运算符 “*”,会使程序容易产生错误且难以阅读。
3、如果以引用为参数,则既可以使得对形参的任何操作都能改变相应的数据,又使得函数调用显得方便、自然。引用传递方式是在函数定义时在形参前面加上引用运算符“&”。
#include <iostream>
using namespace std;
void swap(int&, int&);
int main(){
int a = 3, b = 4;
cout << "a=" << a << ", b=" << b << endl;
swap(a, b);
cout << "a=" << a << ", b=" << b << endl;
system("pause");
return 0;
}
void swap(int &x, int &y){
int t = x;
x = y;
y = t;
}
输出结果:
a=3,b=4
a=4,b=3
函数参数传递机制的理论
函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题。基本的参数传递机制有两种:值传递和引用传递。以下讨论称调用其他函数的函数为主调函数,被调用的函数为被调函数。
值传递(passl-by-value)过程中,被调函数的形式参数作为被调函数的局部变量处理,即在堆栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。
引用传递(pass-by-reference)过程中,被调函数的形式参数虽然也作为局部变量在堆栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过堆栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。
有时候为了程序的需要,我们不得选用指针和引用传递的一种,我建议选引用传递。