C++引用形参和非引用形参专题

每次调用函数时都会重新创建该函数所有形参的值,此时所传递的实参将会初始化对应的形参。形参的初始化和变量的初始化一样,如果形参具有非引用类型,则复制实参的值,如果形参为引用类型,则它只是实参的别名。

1、非引用形参

普通的非引用类型的参数通过复制对应的实参实现初始化。当用实参副本初始化形参时,函数并没有访问调用所传递的实参本身,因此不会修改实参本身。

典型的例子:

int gcd(int v1,int v2)
{
  while(v2)
    {
      int temp=v2;
      v2=v1%v2;
      v1=temp;  
    }  
    return v1;
}        

while循环体虽然修改了v1与v2的值,但是这些变化仅限于局部参数,而对调用gcd函数使用的实参没有任何影响。

总结:非引用形参表示对应实参的局部副本。对这类形参的改变仅仅改变的是局部副本的值。

(a)指针形参

函数的形参可以使指针,此时将复制实参指针。该类形参的任何改变也仅仅作用于局部副本,如果函数将新指针值赋值给形参,主调函数使用的实参指针的值将没有任何改变。

如何函数形参时非const类型的指针,则函数可以通过指针实现赋值,修改指针所指向对象的值。

例如:

void reset(int *p)
{
  *ip=0;
    ip=0;    
}

调用该函数后,ip中所存的地址不变,地址中存放的值变成了0。

如果需保护指针指向的值,则形参需定义为指向const对象的指针。

例如:

void use_ptr(const int *p)

指针形参时指向const类型或非const类型,将影响函数调用使用的实参。我们既可以用int *也可以用const int *类型的实参类型调用use_ptr函数,但是仅能将int *类型的实参传递给reset函数。

总结:指针的初始化规则,可以将指向const对象的指针初始化为指向非const对象,但是不能让指向非cosnt对象的指针指向const对象。

2、引用形参

这是我在写而二叉搜索树的删除算法的时候引出的问题,引用形参很方便的改变指针的值,非引用形参则不能改变传入实参的值。下面对引用形参做一个总结。

例如需要交换两个实参的值,我们需要将形参定义为引用类型:

void swap(int &v1,int &v2)
{
  int tmp=v2;
  v2=v1;
  v1=tmp;    
}

引用形参直接关联到其所绑定的对象,而并非实参的副本。定义引用时,必须用与该引用绑定的对象初始化该引用。

下面在在我的程序中用到的引用形参的使用方法:

(a)传递指向指针的引用

这里给出一个小例子:

void ptrswap(int *&v1,int *&v2)
{
  int *tmp=v2;
  v2=v1;
  v1=tmp;  
}

这样就可以实现交换指针的值。

如果定义为int *v1,int *v2则交换的只是局部副本的指针的值,实参指针的值不受影响。