参数按数值传递和按地址传递(Arguments passed by value and by reference)
到目前为止,我们看到的所有函数中,传递到函数中的参数全部是按数值传递的(by value)。也就是说,当我们调用一个带有参数的函数时,我们传递到函数中的是变量的数值而不是变量本身。但在某些情况下你可能需要在一个函数内控制一个函数以外的变量。要实现这种操作,我们必须使用按地址传递的参数(arguments passed by reference),就象下面例子中的函数duplicate:
// passing parameters by reference
#include <iostream.h>
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;
}
第一个应该注意的事项是在函数duplicate的声明(declaration)中,每一个变量的类型后面跟了一个地址符ampersand sign (&),它的作用是指明变量是按地址传递的(by reference),而不是像通常一样按数值传递的(by value)。
当按地址传递(pass by reference)一个变量的时候,我们是在传递这个变量本身,我们在函数中对变量所做的任何修改将会影响到函数外面被传递的变量。

用另一种方式来说,我们已经把变量a, b,c和调用函数时使用的参数(x, y和 z)联系起来了,因此如果我们在函数内对a 进行操作,函数外面的x 值也会改变。同样,任何对b 的改变也会影响y,对c 的改变也会影响z>。
这就是为什么上面的程序中,主程序main中的三个变量x, y和z在调用函数duplicate 后打印结果显示他们的值增加了一倍。
如果在声明下面的函数:
void duplicate (int& a, int& b, int& c)
时,我们是按这样声明的:
void duplicate (int a, int b, int c)
也就是不写地址符 ampersand (&),我们也就没有将参数的地址传递给函数,而是传递了它们的值,因此,屏幕上显示的输出结果x, y ,z 的值将不会改变,仍是1,3,7。
这种用地址符 ampersand (&)来声明按地址"by reference"传递参数的方式只是在C++中适用。在C 语言中,我们必须用指针(pointers)来做相同的操作。按地址传递(Passing by reference)是一个使函数返回多个值的有效方法。
函数重载(Overloaded functions)
两个不同的函数可以用同样的名字,只要它们的参量(arguments)的原型(prototype)不同,也就是说你可以把同一个名字给多个函数,如果它们用不同数量的参数,或不同类型的参数。例如:
// overloaded function
#include <iostream.h>
int divide (int a, int b) {
return (a/b);
}
float divide (float a, float b) {
return (a/b);
}
int main () {
int x=5,y=2;
float n=5.0,m=2.0;
cout << divide (x,y);
cout << "\n";
cout << divide (n,m);
cout << "\n";
return 0;
}
在这个例子里,我们用同一个名字定义了两个不同函数,当它们其中一个接受两个整型(int)参数,另一个则接受两个浮点型(float)参数。编译器 (compiler)通过检查传入的参数的类型来确定是哪一个函数被调用。如果调用传入的是两个整数参数,那么是原型定义中有两个整型(int)参量的函数被调用,如果传入的是两个浮点数,那么是原型定义中有两个浮点型(float)参量的函数被调用。
为了简单起见,这里我们用的两个函数的代码相同,但这并不是必须的。你可以让两个函数用同一个名字同时完成完全不同的操作。
Inline 函数(inline functions)
inline 指令可以被放在函数声明之前,要求该函数必须在被调用的地方以代码形式被编译。这相当于一个宏定义(macro)。它的好处只对短小的函数有效,这种情况下因为避免了调用函数的一些常规操作的时间(overhead),如参数堆栈操作的时间,所以编译结果的运行代码会更快一些。
它的声明形式是:
inline type name ( arguments ... ) { instructions ... }
它的调用和其他的函数调用一样。调用函数的时候并不需要写关键字inline ,只有在函数声明前需要写。
递归(Recursivity)
递归(recursivity)指函数将被自己调用的特点。它对排序(sorting)和阶乘(factorial)运算很有用。例如要获得一个数字n的阶乘,它的数学公式是:
n! = n * (n-1) * (n-2) * (n-3) ... * 1
更具体一些,5! (factorial of 5) 是:
5! = 5 * 4 * 3 * 2 * 1 = 120
而用一个递归函数来实现这个运算将如以下代码:
// factorial calculator#include <iostream.h>
long factorial (long a){
if (a > 1) return (a * factorial (a-1));
else return (1);
}
int main () {
long l;
cout << "Type a number: ";
cin >> l;
cout << "!" << l << " = " << factorial (l);
return 0;
}