您的位置:首页 > 编程语言 > C语言/C++

C++ 函数--参数传递

2015-10-11 10:37 323 查看
一. 传值参数

传递给函数形参的是实参的拷贝值,形参的改动不会引起实参的改动。

1. 指针形参

传递给函数形参的是指针实参的拷贝值,形参的指针和实参的指针不是同一个,但此时形参和实参指向的是同一个对象,所以可以通过形参改变实参指向的对象的值。

二. 传引用参数

传递给函数形参的是实参的值,即形参实际上只是实参的别名。通过引用参数可以修改函数的多个形参(实际上直接修改了形参绑定的实参);可以避免拷贝(有些类型不支持拷贝操作,如IO类型,此时只能通过引用传值);也可以返回额外信息(函数只有一个return值,通过引用形参直接修改实参可以得到额外的信息)。

三. const形参和实参

当形参有顶层const时(顶层const作用于对象本身),传递给它的实参可以是常量对象也可以是非常量对象。如:

void f(const char *p){…}

char str[]=”Hello”;

const char *cstr=str;

f(str); //true,忽略形参的顶层const

f(cstr); //true,精准匹配

1. 指针或引用形参与const

可以将非常量实参传递给常量形参,但是不能把常量实参传递给非常量形参。如:

void fnc(char *s){…}

void fc(const char *s){…}

char snc[]=”Hello”;

const char *sc=snc;

fnc(snc); //true,精准匹配

fnc(sc); //false,不能把常量实参传递给非常量形参

fc(snc); //true,可以把非常量实参传递给常量形参

fc(sc); //true,精准匹配

引用形参类似。

2. 尽量使用常量引用

对于函数中不会改变其值的参数,最好使用常量指针或常量引用。这样做的目的一个是说明此参数在函数执行过程中不会改变,另一个也避免了参数传递过程中的编译错误。如:

void fnc(char *str){…}

void fc(const char *str){…}

char snc[]=”Hello”;

const char *sc=snc;

fnc(snc); //精准匹配

fnc(sc); //false,不能把常量实参传递给非常量形参

fnc(“Hello”); //false,不能把常量实参传递给非常量形参

fc(snc); //true,可以把非常量实参传递给常量形参

fc(sc); //true,精准匹配

fc(“Hello”); //true,把字面常量传递给常量形参

可以看到,使用常量指针或常量引用可以把非常量、常量、字面常量实参传递给形参;但若形参只是简单的指针或引用,则只能把非常量实参传递给形参,而且并没有说明此参数在函数执行过程中是不被改变的。

四. 数组形参

由于数组的两个性质–不能拷贝,使用时通常被转换为指针;所以不能以值传递的方式传递数组。当为函数传递一个数组时,实际上传递的是指向数组首地址的指针。如:

void f(const char[]);

void f(const char *);

是等价的。

因为数组是以指针的形式传递给函数的,所以一开始函数并不知道数组的大小,所以调用者应该为此提供一些额外的信息,这里主要有3种方式。

1.使用标记指定数组长度–C++中的数组以’\0’结尾

2.使用标准库规范–使用beg和end

3.显式传递一个表示数组大小的形参

1. 数组形参和const

若数组形参在函数执行过程中不变,则使用常量数组。

2. 数组引用形参

可以使用引用类型的数组形参。如:

void f(int (&arr)[10]) {

for (auto elem : arr)

cout << elem << endl;

}

3. 传递多维数组

在C++中没有真正意义上的多维数组,所谓多维数组实际上是数组的数组。

当把一个多维数组传递给函数时,因为多维数组也是数组,所以实际上传递的是多维数组的首地址。又有多维数组实际上是数组的数组,所以传递给函数的其实是指向数组的指针(这个指针指向多维数组第一个元素,也就是数组)。如:

void f(const char ms[][3]){…} //这里的3只是为说明方便,具体的值视情况而定

void f(const char *ms[]){…}

void f(const char **ms){…}

实际上是等价的。

五. 含有可变形参的函数

有时无法提前预知应该向函数传递几个实参,此时可以使用可变形参的函数。C++主要提供了两种方式:

1.若所有形参类型相同,可以传递一个initializer_list的标准库类型;若形参的类型不同,则可以编写一个可变参数模板。

2.使用”…”(一般用于与C函数交互的接口程序)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  函数