参数传递即实参向形参传递信息,使形参获得对应的存储空间及初值,C++中函数传递主要有3种方式:
1、按值传递。
以按值传递方式进行参数传递的过程为:首先计算出实参的值,然后给它所对应的形参变量分配存储空间,该空间大小等于该形参类型的长度,然后把实参值存入到为形参分配的存储空间里去,该值即为形参的初值,在函数被调用时使用。而这种方式被调用的函数对实参的值改变不会有任何的影响,也就是说,即使形参的值在函数中被改变,也不会对实参值产生任何影响,实参值仍为被调用之前的值。究其原因还是实参和形参各占独立的存储单元,彼此之间互不影响。
按值传递引例:
#include <iostream>
using namespace std;
void swap(int a,int b);
int main(void)
{
int a=1,b=2;
cout<<"a="<<a<<",b="<<b<<endl;
swap(a,b);
cout<<"a="<<a<<",b="<<b<<endl;
return 0;
}
void swap(int a,int b)
{
int c=a;
a=b;
b=c;
}
运行结果为:
a=1,b=2
a=1,b=2
注意,虽然形参和实参都是a b,但它们是被分配到了不同的存储空间,这涉及到作用域问题。
总结:(1)只有在函数被调用时,才为形参分配内存空间并赋予初值,当函数调用结束后,形参的内存空间被释放,同时函数返回值(如果有的话);
(2)调用函数时形参实参类型必须一致,int型对应int型,同理double型对应double型,以此类推,否则程序会出错;
(3)C++中函数参数的求值顺序也即传递顺序从右向左,例如:
#include <iostream>
using namespace std;
int sum(int x,int y);
int main(void)
{
int a,b;
a=1;b=2;
cout<<sum(++a,a+b)<<endl;
a=1;b=2;
cout<<sum(a+b,++a)<<endl;
return 0;
}
int sum(int x,int y)
{
return x+y;
}
运行结果为:
5
6
2,、地址传递。
在定义函数的时候如果将形参值定义为指针变量,则调用该函数的时候实参应为地址,这种传递方式即为地址传递。与按值传递不同的是,地址传递是将实参的存储地址传递给对应形参,从而使形参指针和实参的指针都指向同一个地址,所以被调用函数中形参指针指向的地址中内容的改变同时会造成实参内容的改变。
地址传值引例:
#include <iostream>
using namespace std;
void swap(int *,int *);
int main(void)
{
int a=1,b=2;
cout<<"a="<<a<<",b="<<b<<endl;
swap(&a,&b);
cout<<"a="<<a<<",b="<<b<<endl;
return 0;
}
void swap(int *,int *)
{
int c=*a;
*a=*b;
*b=c;
}
运行结果:
a=1,b=2
a=2,b=1
注意:此时的实参和形参仍然占用不同的存储单元,只是它们的指针指向的是同一个地址。
3、引用传递
引用是C语言所没有而C++提供的一种新特性,引用可以看做是变量或者对象的别名,当建立引用的时候,程序用一个变量或者对象的名字初始化它,这样引用就可以当做该变量或者对象的别名所使用,因此对引用的改变就是对变量或者对象本身的改变。引用的语法格式如下所示:
变量类型& 引用名=变量名;
例如定义一个整型变量的引用:
int a;
int& refa=a; \\refa作为a的别名
refa=10;
a-=40;
cout<<a<<endl;
输出结果为-30。此时系统没有为refa分配存储空间,它和a代表了相同的内存空间,对refa进行改变就是对a进行改变。引用的建立和使用引例:
#include <iostream>
using namespace std;
int main(void)
{
int a=3,b=2;
int &a=refa,&b=refb;
refa=a+2;
b=refa+1;
cout<<refa<<" "<<a<<endl;
cout<<refb<<" "<<b<<endl;
refa=b;
cout<<refa<<" "<<a<<endl;
return 0;
}
运行结果为:
5 5
3 3
3 3
注意:(1)引用在定义的时候必须被初始化,必须指定是哪个变量或对象的别名,类型对应一致;
(2)引用仅仅是变量或者对象的别名,系统不会为它分配内存空间;
(3)引用一旦建立就不能被改变,即它已跟定了该变量或者对象,不能作为其它变量或对象的别名。
按值传递易理解但改变形参不能对实参产生影响,地址传递虽可以,但是在函数中多次用指针进行间接访问会使程序难以阅读,且易产生错误,而引用完美解决了上述两个问题。引用传递是在函数定义时在形参前面加上“&”。
引用传递引例:
#include <iostream>
using namespace std;
void swap(int &,int &);
int main(void)
{
int a=1,b=2;
cout<<"a="<<a<<",b="<<b<<endl;
swap(a,b);
cout<<"a="<<a<<",b="<<b<<endl;
return 0;
}
void swap(int &,int &)
{
int c=a;
a=b;
b=c;
}
以上即为C++函数调用时的三种传递方式。