引用经常被用作函数参数,使得函数中的变量名成为调用程序中的变量的别名。这种传递参数的方法称为按引用传递。按引用传递允许被调用的函数能够访问调用函数中的变量。C++新增的这项特性是对 C语言的超越,C语言只能按值传递。按值传递导致被调用函数使用调用程序的值的拷贝。当然,C语言也允许避开按值传递的限制,采用按指针传递的方式。
现在我们通过一个常见的的计算机问题一一交换两个变量的值,对使用引用和使用指针做一下比较。交换函数必须能够修改调用程序中的变量的值。这意味着按值传递变量将不管用,因为函数将交换原始变量副本的内容,而不是变量本身的内容。但传递引用时,函数将可以使用原始数据。另一种方法是,传递指针来访问原始数据。
演示源码:
// Len_value.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
using namespace std;
void swapr(int & a, int & b); // 按引用传递
void swapp(int * p, int* q); // 按指针传递
void swapv(int a, int b); // 按值传递
int main()
{
int a1 = 300;
int a2 = 350;
cout << "按引用传递:";
cout << "a1=" << a1 << ", a2=" << a2 ;
swapr(a1, a2);
cout << ",交换数据后:a1=" << a1 << ", a2=" << a2 << endl << endl;
a1 = 300;
a2 = 350;
cout << "按指针传递:";
cout << "a1=" << a1 << ", a2=" << a2;
swapp(&a1, &a2);
cout << ",交换数据后:a1=" << a1 << ", a2=" << a2 << endl << endl;
a1 = 300;
a2 = 350;
cout << "按值传递: ";
cout << "a1=" << a1 << ", a2=" << a2;
swapv(a1, a2);
cout << ",交换数据后:a1=" << a1 << ", a2=" << a2<<endl << endl;
}
void swapr(int & a, int & b) // 按引用传递
{
int temp = a;
a = b;
b = temp;
}
void swapp(int * p, int* q) // 按指针传递
{
int temp = *p;
*p = *q;
*q = temp;
}
void swapv(int a, int b) // 按值传递
{
int temp = a;
a = b;
b = temp;
}
执行结果:
程序说明:
swapr(a1, a2);
swapp(&a1, &a2);
swapv(a1, a2);
按引用传递swapr(a1,a2) 和按值传递 swapv(a1,a2)看起来相同。
只能通过原型或函数定义才能知道 swapr()是按引用传递的。然而,地址运算符&使得按地址传递swapp(&a1,&a2)一目了然。类型声明 int*p 表明p 是个int 指针因此与p 对应的参数应为地址如&a1。
比较函数 swapr()按引用传递和 swapv()按值传递的代码,唯一的外在区别是声明函数参数的方式不同:
void swapr(int & a, int & b); // 按引用传递
void swapv(int a, int b); // 按值传递
当然还有内在区别: 在 swapr()中,变量a 和 b 是 a1和a2 的别名,所以交换a和b 的值相当于交换a1和a2的值;但在 swapv()中,变量a和b是复制了a1和a2的值的新变量。因此交换 a和 b的值并不会影响a2 和a2的值。最后,比较函传递引用和 传递指针第一个区别是声明函数参数的方式不同:
void swapr(int & a, int & b); // 按引用传递
void swapp(int * p, int* q); // 按指针传递
另一个区别是指针版本需要在函数使用p和 的整个过程中使用解除引用运算符*。
之前说过,应在定义引用变量时对其进行初始化。函数调用使用实参初始化形参,因此质数的引用参数被初始化为函数调用传递的实参。也就是说,下面的函数调用将形参a和b分别初始化为 a1和a2。
swapr(a1,a2);