### 设置指针/引用参数

在介绍指针/引用参数之前，我们先来介绍函数的传递方式。在 C++中，函数参数主要采用两种传递方式，值传递和引用传递。所谓值传递是指在调用函数时将实际参数复制一份传递到函数中，这样，在函数中如果对参数进行修改，将不会影响到实际参数。而引用传递是指在调用函数时将实际参数的地址传递到函数中，那么，在函数中对参数所进行的修改，将影响到实际参数。

下面我们编写一个按值传递的函数 OutputNumber，函数的作用是输出一个数值。

按值传递

void OutputNumber(int nNumber)

{

cout << nNumber << endl; //输出数值

nNumber = 20; //修改参数

}

在 main 函数中调用 OutputNumber 函数。

int main(int argc, char* argv[])

{

int nNum = 10; //定义一个变量

OutputNumber(nNum); //调用 OutputNumber 函数

cout << nNum << endl; //输出变量值

return 0;

}

运行程序，效果如图 1 所示。

图 1 值传递

从图 1 中可以发现，在 OutputNumber 函数中输出的数值是 10，尽管在该函数中将参数 nNumber 设置为 20，但是在 main 函数中执行“cout << nNum << endl;”语句时，输出的结果仍为 10。因为 OutputNumber 函数采用按值传递，对形式参数 nNumber 的修改不会影响到实际参数 nNum。

如果我们修改 OutputNumber 函数，将参数的类型修改为引用类型，则 OutputNumber 函数将按引用方式传递。

按引用传递

void OutputNumber(int &nNumber) //设置引用类型参数

{

cout << nNumber << endl; //输出结果

nNumber = 20; //修改参数值，将影响到实际参数

}

int main(int argc, char* argv[])

{

int nNum = 10; //定义一个变量

OutputNumber(nNum); //调用 OutputNumber 函数

cout << nNum << endl; //输出变量值

return 0;

}

运行程序，效果如图 2 所示。

图 2 引用传递

从图中可以发现，在 OutputNumber 函数中将形式参数 nNumber 设置为 20，实际参数 nNum 的值也为 20。因为引用传递，传递的是参数的地址，对 nNumber 的修改自然会影响到 nNum。

许多用户可能会问，如何判断函数是值传递还是引用传递呢？这需要根据参数的数据类型来判断，如果参数的数据类型是指针类型、引用类型或数组类型，则函数是引用传递，其他情况下是值传递。因此，不仅只有引用数据类型才是按引用传递，指针和数组类型参数同样是按引用传递。下面修改函数 OutputNumber，采用指针作为函数参数。

指针作为函数参数

void OutputNumber(int *pNumber) //使用指针作为函数参数

{

cout << *pNumber << endl; //输出参数值

*pNumber = 20; //设置参数值

}

int main(int argc, char* argv[])

{

int nNum = 10; //定义一个整型变量

OutputNumber(&nNum); //调用 OutputNumber 函数

cout << nNum << endl; //输出 nNum

return 0;

}

运行程序，效果与图 2 是相同的。

在编写函数时，如果函数需要采用引用方式传递，使用指针和引用作为参数类型都是可以的。对于引用类型，引用必须被初始化为一个对象，并且不能使它再指向其他对象，因为对引用赋值实际上是对目标对象赋值。这是引用类型的缺点，但也是引用类型的优点，因为在函数调用时需要验证引用参数的合法性。例如，如果函数 OutputNumber 采用引用参数类型，则语句“OutputNumber(0);”是非法的。如果函数 OutputNumber 采用指针类型参数，则语句“OutputNumber(0);”是合法的。因为 0 被认为是一个空指针，对空指针操作必然会导致地址访问错误。因此对于指针对象作为函数参数，函数体中需要验证指针参数是否为空。这是使用指针类型作为函数参数的缺点。但是，使用指针对象作为函数参数，用户可以随意修改指针参数指向的对象，这是引用类型参数所不能的。

注意：使用指针和引用类型作为函数参数各有优缺点，视具体环境而定。