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函数交互的接口程序)
传递给函数形参的是实参的拷贝值,形参的改动不会引起实参的改动。
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函数交互的接口程序)
相关文章推荐
- Mootools 1.2教程 函数
- autoit InputBox 函数
- 文件遍历排序函数
- Oracle 函数大全[字符串函数,数学函数,日期函数]第1/4页
- ASP下经常用的字符串等函数参考资料
- PostgreSQL教程(五):函数和操作符详解(1)
- DOS批处理 函数定义与用法
- asp Chr 函数 数字转字母的方法
- Lua中的函数精讲笔记
- Lua中的闭合函数、非全局函数与函数的尾调用详解
- Lua中调用C++函数示例
- Lua实现split函数
- Lua常用时间函数使用实例
- Lua函数与字符串处理简明总结
- Lua学习笔记之表和函数
- Lua中实现sleep函数功能的4种方法
- Lua函数用法研究
- Lua基础教程之赋值语句、表达式、流程控制、函数学习笔记
- PowerShell函数简明教程
- 探索PowerShell(十一)函数介绍