************************************************************
原文:http://www.cplusplus.com/doc/tutorial
************************************************************
函数
(II)
|
参数的传值和传引用
<script type="text/javascript" src="http://ads.adbrite.com/mb/text_group.php?sid=170596&col=3&br=1"></script>
直到现在,在我们已经看到的所有函数中,传给函数的参数都是“传值”的。这意味着当调用一个带有参数的函数时,我们传给函数只是这些参数的值得一份拷贝而不是变量本身。例如,设想一下我们使用下面的代码来调用我们的第一个函数
addition
:
int x=5, y=3, z;
z = addition ( x , y );
|
我们在这里做的就是调用函数
addition
,并把
x
、
y
的值传给它,如分别是
5
和
3
,但并不是变量
x
和
y
它们本身。
因此,当函数
addition
被调用时,它的局部变量
a
和
b
的值将分别为
5
和
3
,但是在函数
addition
中对
a
或
b
的任何修改对于函数外的变量
x
和
y
的值都没有任何影响,因为变量
x
和
y
并不是把它们自身传递给了函数,而只是在函数被调用时把它们的值的一份拷贝传给了函数。
但是在某些情况下你可能需要在一个函数的内部来操作一个外部的变量。为了这个目的我们可以使用参数的“引用”传递,例如在下面这个例子中的函数
duplicate
中那样:
// passing parameters by reference
#include <iostream>
using namespace std;
void duplicate (int& a, int& b, int& c)
{
a*=2;
b*=2;
c*=2;
}
int main ()
{
int x=1, y=3, z=7;
duplicate (x, y, z);
cout <<
"x="
<< x <<
", y="
<< y <<
", z="
<< z;
return 0;
}
|
x=2, y=6, z=14
|
第一件应该得到你注意的事就是在函数
duplicate
的声明中每个形参的类型后面都跟有一个
&
。
&
说明它们对应的实参是被传的
”
引用
”
而不是
”
值
”
当一个变量是传“引用”时,我们不是传递了它值的一份拷贝,我们而是用某种方式把变量本身传给了函数,我们对于这个函数中的这些(形参列表中的,在类型符后带有
&
的变量——译者注)局部变量的任何修改都将对它们所对应的在调用这个函数时传进来的实参产生影响。
用另一种方法解释就是,我们另形参
a, b, c
分别对应在函数调用时传进来的实参(
x, y, z
),那么我们在函数
duplicate
中对
a
做的任何是都将影响它外面的
x
的值。我们对
b
做的任何改变将影响
y
,同样的
c
和
z
也是如此。
那就是为什么我们的展示在调用函数
duplicate
后保存在变量
x, y, z
中的值得输出,展示出
main
函数的全部三个变量的值都乘以了
2
。
如果当我们定义如下的函数时:
void duplicate (int& a, int& b, int& c)
|
我们用这种方法定义了它:
void duplicate (int a, int b, int c)
|
例如,如果没有
&
符,我们就没有以“引用”的方式来传递变量,而是用其值的一份拷贝来代替它本身,因此,我们新的程序在屏幕上的输出因该是
x, y, z
没有被修改的值。
“引用”传递也是允许一个函数有多于一个返回值的一种高效的方法。例如,下面的函数返回传入的第一个形参的前一个和下一个值。
// more than one returning value
#include <iostream>
using namespace std;
void prevnext (int x, int& prev, int& next)
{
prev = x-1;
next = x+1;
}
int main ()
{
int x=100, y, z;
prevnext (x, y, z);
cout <<
"Previous="
<< y <<
", Next="
<< z;
return 0;
}
|
Previous=99, Next=101
|
形参的缺省值
.
在声明一个函数时我们可以为每一个形参说明一个缺省值。这个值将在这个函数被调用但其形参对应的实参空缺时被使用。为了达到这个目的,我只需简单的使用符值运算符和一个在函数声明时作为实参的一个值。如果当函数调用时那个形参的值没有被传递,缺省值将被使用,但是如果有一个值被明确的传了过来那么这个缺省值将被忽略,将直接使用传过来的值。例如:
// default values in functions
#include <iostream>
using namespace std;
int divide (int a, int b=2)
{
int r;
r=a/b;
return (r);
}
int main ()
{
cout << divide (12);
cout << endl;
cout << divide (20,4);
return 0;
}
|
6
5
|
就像我们在函数体中看到的那样,调用了两次
divide
函数。第一个是:
divide (12)
|
我们只指明了一个实参,但是函数
divide
却允许最多
2
个实参。因此函数
divide
认为第二个参数是
2
因为这个值是我们想要在这个形参没有被传递时说期望的(注意这个函数的声明,它以
int b=2
结束而不仅仅是
int b
)。因此这个函数在这次调用中的结果是
6
(
12/12
)。
第二个调用:
divide (20,4)
|
有两个参数,因此
b
的缺省值
(int b=2 )
被忽略了,
b
带有实参传过来的值——
4
,这使得返回的结果等于
5
(
20/4
)。
(带有缺省值的形参要出现在函数形参列表的最右侧。如在形参列表中一个形参带有缺省值,则其后面(右侧)的形参都要代用缺省值——译者注)。