函数参数传递 c++学习

每次函数传递,都会重新创建该函数的所有形参,此时将所传递的实参初始化对应的形参。

形参可以分为非引用形参和引用形参两类。

非引用形参:

普通的非引用形参是通过复制对应的实参实现初始化。当用实参的副本初始化形参时,函数并没有访问调用所传递的实参本身,因此不会修改实参的值。(非引用形参表示对应实参的局部副本。对这类形参的修改仅仅改变了局部副本的值。一旦函数执行结束,这些局部变量的值也就不存在了)。

非引用形参之指针形参:可以将指向const对象的指针初始化为指向const对象或非const对象;但只能将指向非const对象的指针初始化为指向非const对象。

若函数使用非引用的非const形参,则既可以给该函数传递const的实参,也可以传递非const实参。若函数使用非引用的const形参,则在函数中不可改变实参的局部副本,由于实参仍然是以副本的形式传递,因此传递给该函数既可以是const的实参也可以是非const的实参。

编译器会视const形参为普通的形参,兼容c,在c中具有const形参和具有非const形参的函数并无区别。

复制实参的局限性,不适应复制实参的情况包括:

1>当需要在函数中修改实参的值时;

2>当需要以大型对象作为实参传递时,复制实参付出的时间和存储空间的代价很大;

3>当没有办法实现对象的复制时。

引用形参

与所有引用一样,引用形参直接关联到其所绑定到的对象,而并非这些对象的副本。引用对象必须用与该引用绑定的对象初始化该引用。

使用引用形参不仅可以修改实参的值,还可以返回额外的信息——当函数有不止一个内容需要返回时。

利用const引用避免复制

如果使用引用形参的唯一目的是避免复制实参,则应将形参定义为const类型(不能通过该引用修改实参)。

更灵活的指向const的引用

如果函数具有普通的非const引用形参,则显然不能用const实参进行调用。且调用这样的函数,传递一个右值和具有需要转换的类型的对象是不允许的。const引用形参只能用完全同类型的非const对象关联。

应该将不需要修改相应实参的形参定义为const引用。如果将这样的形参定义为非const引用,则毫无必要地限制了该函数的使用。

传递指向指针的引用

void swap(int *&v1, int *&v2){ ...... } 

形参int *&v1从右至左理解:首先v1是一个引用,与指向int型对象的指针关联。

通常,函数不应该有vector和其他标准库容器类型的形参。调用含有普通的非引用vector形参的函数将会复制vector的每一个元素。从避免复制vector的角度出发,应将形参声明为引用类型。事实上,C++程序员倾向于通过传递指向容器中需要处理的元素的迭代器来传递容器。

数组形参

数组的两个特殊性质:一是不能复制数组;二是使用数组名字时,数组名会自动转换为指向数组第一个元素的指针。

数组形参定义的方式有三种:例如 void fun(int a[10]) ; void fun(int *a) ; void fun(int a[]);

通常将数组形参定义为指针要比使用数组语法更好。这样就明确表明函数操纵的是指向数组元素的指针,而不是数组本身。当编译器检查数组形参关联的实参时,它只会检查该实参是不是指针,指针的类型和数组元素的类型是否匹配,而不会检查数组的长度。

数组实参

在传递数组时,数组实参是指向数组第一个元素的指针,形参复制的是这个指针的副本,而不是数组元素本身。函数操纵的是指针的副本,而不会修改实参指针的值。然而,可以通过该指针改变它所指向的数组元素的值。

通过引用传递数组

如果形参是数组的引用,编译器不会将数组实参转化为指针,而是传递数组的引用本身。这种情况下数组的大小成为形参和实参类型的一部分。编译器会检查数组大小和形参的大小是否匹配。

多维数组的传递

C++没有多维数组,所谓多维数组实际是数组的数组。多维数组的元素本身就是数组,除了第一维以外的所有维的长度都是元素类型的一部分。多维数组形参定义:

例如void fun(int (*a)[10],  int rowsize); void fun(int a[][10], int rowsize);

前一个语句声明a为一个指向有10int型元素的指针;后一个语句用数组语法定义了多维数组,并忽略了第一维的长度。

传递给函数的数组的处理

有三种常见的编程技巧确保函数的操作不超出数组实参的边界:

第一种方法就是在数组本身放置一个标记来检测数组的结束。C风格字符串就是采用这种方法的一个例子,它是一个字符数组,并以空字符null作为结束的标记。

第二种方法就是传递指向数组第一个元素和最后一个元素的下一个位置的指针。

第三种方法就是将第二个形参定义为表示数组的大小。

注意在标准C++中定义或声明函数时,没有显式指定返回值类型是不合法的。

但在C中,如果函数返回值是int类型,返回值类型可以省略,而且可以不用显式声明该函数。

posted @ 2012-02-21 15:52  whu-小磊  阅读(237)  评论(0编辑  收藏  举报