老生常谈C++中实参形参的传递问题

2020-01-06 17:02:02于海丽


void swap (int &v1,int &v2)

{

      int tmp=v1;

      v2=v1;

      v1=tmp;

}

当调用swap(i,j)时,i和j的值才真正实现了交换。

更灵活的指向const的引用

应该将不需要修改的引用形参定义为const引用。普通的非const引用形参在使用时不大灵活。非const引用形参既不能用const对象初始化,也不能用字面值或者产生右值的表达式实参初始化。(如果函数的形参是非const引用形参,表示在函数体内可能会修改该形参值,即会修改实参的值,因此不可以用const对象来做实参传递给这样的函数,所以不灵活。)

传递指向指针的引用

如果想编写一个与前面交换两个整数的swap类似的函数,实现两个指针的交换。已知需用*定义指针,用&定义引用,问题在于,如何将这两个操作符结合起来一获得指向指针的引用。


//交换两个指向整形的指针的值

void ptrswap(int *&v1,int *&v2)

{
       int=*tmp=v2;
       v2=v1;
       v1=tmp;
 }

形参int *&v1的定义,应该从右至左的理解:v1是一个引用,与指向int型对象的指针相关联。也就是说,v1只是传递ptrswap函数的任意指针的别名。

3.vector和其他容器类型的形参

由于复制vector会使得效率降低,多以如果形参是vector的话,我们常常将该形参声明为引用,避免复制。另一种方法在C++中更为常用,就是通过传递指向容器中需要处理的元素的迭代器来传递容器。

4.数组形参

由于数组是不可以复制的,所以不可以定义使用数组类型形参的函数。如果函数需要使用数组作为形参,那么就要通过操纵指向数组中元素的指针来处理数组。

以下定义都是正确的:


void printValues(int*){}
void printValues(int[]){}
void printValues(int[10]){}

注意了,虽然不能直接传递数组,但是函数的形参可以写成数组的形式。上面三种定义是等价的,形参类洗个都是int*。

通常,将数组形参直接定义为指针要比使用数组语法定义更好。这样就明确地表示,函数操纵的是指向数组元素的指针,而不是数组本身。由于忽略了数组长度,形参定义中如果包含了数组长度则特别容易引起误解。

对于非引用型形参来说,编译器检查数组形参关联的实参时,它只会检查实参是不是指针、指针的形参和数组元素的类型是否匹配,而不会检查数组的长度,所以即使实参数组的长度与形参不匹配时,编译也可以通过,但是在调用时会出错。

但是对于引用型形参来说,编译器还会检查是西安数组的大小与形参的大小是否匹配,所以如果实参数组的长度与形参不匹配,编译时就会报错。