C++之参数总结
函数的形参为函数提供了已命名的局部存储空间,它是在函数的形参表中定义的,并由调用函数时传递给函数的实参初始化,而形参的
初始化与变量的初始化一样,如果形参具有非引用类型,则复制实参的值,如果形参为引用类型,则它只是实参的别名,具体分析如下:
1.非引用形参
普通的非引用类型的参数通过复制对应的实参实现初始化,而当实参副本初始化形参时,函数并没有访问所传递的实参本身,因此这不会
改变实参的值,例如:
int fun(int v1,int v2)
{
while(v2)
{
int temp=v2;
v2=v1%v2;
v1=temp;
}
return v1;
}
while循环体虽然修改了v1和v2的值,但是这些改变仅限于局部参数,而对调用fun()函数使用的实参没有任何影响,而一旦函数执行结束,
这些局部参数(局部变量)的值也就没有了也就是说,假如我们调用了函数:fun(a,b) 则a和b的值不受fun()执行的赋值修改的影响.
2.指针形参
与其他非引用类型的形参一样,如果函数的形参是指针,那么此时也将复制实参指针,所以,该类形参的任何改变也仅是作用于局部副本,不过
由于指针类型与普通变量的差异,在操作上也有点不同,指针实参的局部副本虽然不会改变主调函数使用的实参指针值,但是,如果函数形参是
非const类型的指针时,则函数可以通过修改指针所指向对象的值来扩大它的影响力。
例如:
void reset(int *ptr)
{
*ip=0;
ip=0;
}
调用reset()函数后,实参依旧保持原来的值,也就是说它还是指向原来的地方,不过,它所指向的那个地方的对象的值现在变为了0.
如果需要保护指针所指向的值,则可以将形参定义为指向const对象的指针,如下:
void fun(const int *ptr)
{
...................................
}
此时,我们即可以用int *也可以用const int *类型的实参来调用fun()函数,但是仅可以将int *类型的实参传递给reset()函数
3.const形参
如果函数使用的是非引用的非const形参,既然传递的只是实参的副本,当然既可以给该函数传递const实参也可以传递非const形参,如果
函数使用的是非引用的const类型,如:
void fun(const int i){
..............................
}
则在函数中,我们不可以修改实参的局部副本,不过,由于实参仍然是以副本的形式传递的,因此传递给fun()函数的既可以是const
对象也可以是非const对象
4.引用形参
与所有引用一样,引用形参将直接关联到其所绑定的对象,作为实参的别名,而非仅仅是这些对象的副本,因此,我们可以在实际运用中
通过引用形参让函数修改实参的值,这可以弥补函数只能返回单个值的缺陷,在函数需要返回的值不止一个时,我们可以通过传递额外的
引用形参来解决该问题。此外,我们还可以利用const引用来避免大型数据的复制,提供效率的同时,也可以保护所指向的对象。
如果函数具有普通的非const引用形参,则显然是不能通过const对象进行调用的,因为此时函数可以修改传递进来的参数,这样就违背了
实参的const特性,其实,在这个问题的处理上,C++显得更为严格,也就是说,非const引用形参只能与完全同类型的非const对象所关
联.
5.传递指向指针的引用
void fun(int *&v1,int *&v2)
{
int *temp=v2;
v2=v1;
v1=temp;
}
首先对于形参 int *&v1 我们可以这样理解,从右至左:v1是一个引用,它与指向int型对象的指针相关联,换句话说,v1只是传递
进fun()函数的任意指针的别名,因此,我们可以通过调用该函数来分别改变他们所指向对象的值。
6.数组形参
有三种方式就可以指定数组的形参:
void fun1(int *)
void fun2(int [])
void fun3(int [10])
这三种方式都是等价的,形参都是int*,这我们可以这样理解:使用数组名字时,数组名会自动转换为指向其第一个元素的指针,通常,将
数组形参直接定义为指针比使用数组语法定义更好,因为此时函数操作的是指向数组元素的指针,而不是数组本身,此外,编译器会忽略
为任何数组形参指定的长度,但是往往因为数组越界问题而导致运行失败。
7通过引用传递数组
大部分情况下,数组以普通的非引用类型传递时,数组会悄悄地转换为指针,因此,此时函数实质上操作的也是指针的副本,它不会修改
实参指针的值,但是函数可以通过这些指针改变它所指向的数组元素的值。但是,如果形参是数组的引用如:
void fun(int (&arr)[10]){
................
}
编译器不会将数组实参转换为指针,而是传递数组的引用本身,在这种情况下,数组大小成为形参和实参类型的一部分,编译器将严格检
查数组实参的大小与形参的大小是否匹配。
C++之参数总结的更多相关文章
- 【.net 深呼吸】细说CodeDom(6):方法参数
本文老周就给大伙伴们介绍一下方法参数代码的生成. 在开始之前,先补充一下上一篇烂文的内容.在上一篇文章中,老周检讨了 MemberAttributes 枚举的用法,老周此前误以为该枚举不能进行按位操作 ...
- Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数
上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...
- Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数
上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...
- Scrapy框架爬虫初探——中关村在线手机参数数据爬取
关于Scrapy如何安装部署的文章已经相当多了,但是网上实战的例子还不是很多,近来正好在学习该爬虫框架,就简单写了个Spider Demo来实践.作为硬件数码控,我选择了经常光顾的中关村在线的手机页面 ...
- 【每日一linux命令4】常用参数:
下面所列的是常见的参数(选项)义: --help,-h 显示帮助信息 --version,-V ...
- 【每日一linux命令3】参数(或称选项)顺序
一般除了特殊情况,参数是没有顺序的.举例而言,输入"–a –v"与输入"–v –a"以及"–av" 的执行效果是相同的.但若该参数后指定了要 ...
- C# 中参数验证方式的演变
一般在写方法的时候,第一步就是进行参数验证,这也体现了编码者的细心和缜密,但是在很多时候这个过程很枯燥和乏味,比如在拿到一个API设计文档的时候,通常会规定类型参数是否允许为空,如果是字符可能有长度限 ...
- js中参数不对应问题
因为js是一种弱类型的编程语言,对数据类型的要求没有其他编程语言的要求严格,所以在定义函数的时候不需要像java和C#一样对其传入参数的类型进行定义.那么传入参数的个数有没有影响呢?今天小猪就做了个实 ...
- C++中的变长参数
新参与的项目中,为了使用共享内存和自定义内存池,我们自己定义了MemNew函数,且在函数内部对于非pod类型自动执行构造函数.在需要的地方调用自定义的MemNew函数.这样就带来一个问题,使用stl的 ...
- nodejs进阶(5)—接收请求参数
1. get请求参数接收 我们简单举一个需要接收参数的例子 如果有个查找功能,查找关键词需要从url里接收,http://localhost:8000/search?keyword=地球.通过前面的进 ...
随机推荐
- BZOJ4810 Ynoi2017由乃的玉米田(莫队+bitset)
多组询问不强制在线,那么考虑莫队.bitset维护当前区间出现了哪些数,数组记录每个数的出现次数以维护bitset.对于乘法,显然应有一个根号范围内的因子,暴力枚举即可.对于减法,a[i]-a[j]= ...
- Android ListView 显示多种数据类型
ListView往往可能会有不同的数据类型,单类型的数据可能运用会比较少些,这也是最近项目中的一个需求{在发送消息的时候,需要选择联系人,而联系人列表由英文字母索引+联系人组成},上一篇文章只是一个基 ...
- SRM12 T2夏令营(分治优化DP+主席树 (已更新NKlogN)/ 线段树优化DP)
先写出朴素的DP方程f[i][j]=f[k][j-1]+h[k+1][i] {k<i}(h表示[k+1,j]有几个不同的数) 显然时间空间复杂度都无法承受 仔细想想可以发现对于一个点 i ...
- ContestHunter暑假欢乐赛 SRM 06
T1二分check...为什么这么显然的我没看出来TAT,还在想倒着加入并查集check什么的,题写太多思维定势啦QAQ T2是NOIP题的弱化版...当时没看出来,写了个DP.可以看出这一位比上一位 ...
- 使用JavaScript OOP特性搭建Web应用
最近,我面试了一个有五年 Web 应用程序开发经验的软件开发人员.四年半来她一直在从事 JavaScript 相关的工作,她自认为 JavaScript 技能非常好,但在不久之后我就发现实际上她对 J ...
- OS开发中的事件处理(二)-事件传递,响应者链条
事件处理的事件传递 简介: 发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件 队列中,UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理, ...
- Using CORS(译)
原文地址:https://docs.webplatform.org/wiki/tutorials/using_cors 总结 一篇对"Cross Origin Resource Sharin ...
- kafka 命令笔记
以下命令都是在kafka根目录下 启动自带的zookeeper bin/zookeeper-server-start.sh config/zookeeper.properties 启动kafka(启动 ...
- vijos 1069 新年趣事之红包 Prim水题
描述 xiaomengxian一进门,发现外公.外婆.叔叔.阿姨……都坐在客厅里等着他呢.经过仔细观察,xiaomengxian发现他们所有人正好组成了一个凸多边形.最重要的是,他们每个人手里都拿着一 ...
- HDU 5868 Different Circle Permutation Burnside引理+矩阵快速幂+逆元
题意:有N个座位,人可以选座位,但选的座位不能相邻,且旋转不同构的坐法有几种.如4个座位有3种做法.\( 1≤N≤1000000000 (10^9) \). 题解:首先考虑座位不相邻的选法问题,如果不 ...