1.值传递
程序示例:
#include<iostream>
using namespace std;
void swap(int a, int b);
int main()
{
int x = 10;
int y= 20;
cout<<x<<" "<<y<<endl;
swap(x, y);
cout<<x<<" "<<y<<endl;
return 0;
}
void swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
为什么x,y没有交换?
程序的执行流程:
首先,进入main函数,为x,y变量分配存储空间,进入swap子程序后,为a,b形参分配存储空间,并将实参传给形参,为局部变量temp分配存储空间并赋值,从而实现a,b值的交换,至此swap的生命周期已经结束,swap子程序对应的空间被释放,但是此刻形参的改变没有传给实参,所以x,y的值并不变。
特点:单向传递,实参可以传递给形参,但是形参不能传递给实参。所以被调用函数的执行不影响函数的实参,即在被调用函数中不能对函数的实参进行修改,因此,通常以值传递方式实现函数的输入。
2.地址传递
#include<iostream>
using namespace std;
void swap(int *p1, int *p2);
int main()
{
int x = 10;
int y= 20;
cout<<x<<" "<<y<<endl;
swap(&x, &y);
cout<<x<<" "<<y<<endl;
return 0;
}
void swap(int *p1, int *p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
程序的执行流程:
首先,进入main函数,为x,y变量分配存储空间,进入swap子程序,为p1,p2形参分配存储空间。并将x,y的地址传给p1,p2。此时可以认为,p1,p2“指向”了x,y变量。并将p1所指单元的内容赋值给它,进而为局部变量temp分配存储空间,实现指针对应内容的交换(即x,y交换)。此时,swap子程序 执行完成,则swap 子程序对应的存储空 间会被释放。
传地址方式的要点是: main函数和swap函数共用x, y变量的存储空间,只不过在过在main函数中,用x,y访问此空间;而在swap函数中,则用*p1,*2这种间接访问方式访问此空间。由于空间是共用的,所以形参*p1, *p2发生了改变,也就影响到了实参x,y.
指针传递方式的特点:在被调用函数中可以对实参地址所对应的存储单元进行访问,即可以读取,
或修改该内存单元的值。因此,可以通过指针传递方式实现函数的输出,即将被调用函数修改的
值传递(返回)给调用者。
3.引用传递
如果我们在声明或定义函数的时候将函数的形参指定为引用,则在调用该函数时会将实参直接传递给形参,而不是将实参的拷贝传递给形参。如此一来,如果在函数体中修改了该参数,则实参的值也会被修改。这跟函数的普通传值调用还是有区别的。
#include<iostream>
using namespace std;
void swap(int &a, int &b);
int main()
{
int num1 = 10;
int num2 = 20;
cout<<num1<<" "<<num2<<endl;
swap(num1, num2);//引用:int &a=num1, int &b=num2
cout<<num1<<" "<<num2<<endl;
return 0;
}
void swap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
在本例中我们将swap函数的形参声明为引用,在调用swap函数的时候程序是将变量num1和num2直接传递给形参的,其中a是num1的别名,b是num2的别名,在swap函数体中交换变量a和变量b的值,也就相当于直接交换变量num1和变量num2的值了,因此程序最后num1=20,num2=10。