1.参数传递

每次调用函数时,都会重新创建该函数所有的形参,此时所传递的实参将会初始化对应的形参。
形参的初始化与变量的初始化一样;如果形参具有非引用类型,则复制实参的值,如果形参为引用类型,则他只是实参的别名。

2.非引用形参

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

2.1 指针形参

函数的形参可以是指针,此时将复制实参指针。与其他非引用类型的形参一样,该类形参的任何改变也仅作用于局部副本。如果函数将新指针赋给形参,主调函数使用的实参指针的值没有改变。
事实上,被复制的指针只影响对指针的赋值。如果函数形参是非const类型的指针,则函数可通过指针实现赋值,修改指针所指向对象的值。
<span style="font-size:18px;">#include <iostream>
using std::cout;
using std::endl;
void Reset(int* ip);int main()
{int i = 100;int* p = &i;cout<<"Befor"<< *p<<endl;Reset(p);cout<<"After"<<*p<<endl;return 0;
}
void Reset( int* ip)
{*ip = 0;ip = 0;
}</span>

上述程序运行结果为 100,0;
解释:调用reset后,实参依然保持原来的值(指的是指针的名字,而非指针指向的内容),但是它所指向的对象的值将变为零。

如果保护指针指向的值,则形参需定义为指向const对象的指针
#include <iostream>
using std::cout;
using std::endl;
void Reset(const int* ip);int main()
{int i = 100;int* p = &i;cout<<"Befor"<< *p<<endl;Reset(p);cout<<"After"<<*p<<endl;return 0;
}
void Reset(<strong><span style="color:#3333ff;">const</span></strong> int* ip)
{<span style="color:#ff6666;"><strong>*ip = 0;</strong></span> //error:不能给指向const int类型的指针赋值ip = 0;
}

指针形参是指向const类型还是非const类型,将影响函数调用所使用的实参。我们既可以用int*也可以用const int*类型的实参调用Reset()函数;但仅能将int*类型的实参传递给Reset函数。这个差别来源于指针的初始化规则:

可以将指向const对象的指针初始化为指向非const对象
<p><span style="font-family: Arial, Helvetica, sans-serif;">i = 100;</span></p>const int* cip = &i; //OK:This is Right

但不可以让指向非const 对象的指针指向const对象;

const int i = 100;
int* ip = &i; //error C2440: “初始化”: 无法从“const int *”转换为“int *”

2.2 const形参

在调用函数时,如果该函数使用非引用的非const形参,则既可以给该函数传递const实参,也可以传递非const

的实参。例如:

int gcd(int v1, int v2) // 求最大公约数
{while(v2){int temp = v2;v2 = v1 % v2;v1 = temp;}return v1;
}int main()
{const int i = 3, j = 6;int k = gcd(3,6); //OK,k initialized to 3
}

这种行为源于const对象的标准初始化规则。因为初始化复制了初始化式的值,所以可用const对象初始化非const对象,反之亦然。

如果将形参定义为非引用的const类型:
void fcn(const int i) { /* fcn can read but <strong><span style="color:#ff0000;">not write to i</span></strong> */ }

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

3. 复制实参的局限性

复制实参并不是在所有的情况下都合适,不适宜复制实参的情况包括:
1.当需要在函数中修改实参的值时;
2.当需要以大型对象作为实参传递时。对实际的应用而言,复制对象所付出的时间和存储空间代价往往过大;
3.没有办法实现对象的复制时。
对于上述几种情况,有效的解决办法是将形参定义为引用或指针类型

C++Primer:函数(参数传递-非引用形参)相关推荐

  1. C++Primer:函数(参数传递:引用形参)

    1.问题的引入 考虑下面不适宜复制实参的例子,该函数希望交换两个实参的值: <span style="font-size:18px;">void swap(int v1 ...

  2. [Javascript 高级程序设计]学习心得记录 函数参数传递与引用

    最近开始啃js的红宝书:<Javascript 高级程序设计>,偶有心得,记录一下. 先上代码 function howManyArgs() {alert(arguments.length ...

  3. ARTS-19(C++引用形参,查理芒格的智慧)

    Algorithm 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的 ...

  4. C++ Primer 第五版 第6章 6.2——函数参数传递阅读笔记

    习题答案请参考:C++ Primer 第五版 第6章 6.2--函数参数传递习题答案 目录 6.2 函数参数传递 6.2.1 传值参数(值传递) 指针形参 6.2.2 传引用参数(引用传递) 使用引用 ...

  5. C++ 函数参数传递:传值,传指针,传引用

    PS:首先理解形参   实参概念.形参是在函数定义的括号内定义的专用变量,它们的目的是保存按实参传递给它们的信息,实参被列在函数调用语句的括号内. int func(int x)//x是形参 {ret ...

  6. C++ Primer 第五版 第6章 6.2——函数参数传递习题答案

    理论讲解请参考:C++ Primer 第五版 第6章 6.2--函数参数传递阅读笔记 目录 6.10 指针形参交换两个数 6.12 引用形参交换两个数 6.13 6.14 6.15 6.16 6.17 ...

  7. 函数参数传递三种方式(传值方式,地址传递,引用传递)

    函数参数传递三种方式(传值方式,地址传递,引用传递) 形参与实参 形参即形式上的参数,对实参的一种抽象类型描述只是声明一个函数能够接受什么类型的实参,而不确定接受的实参的具体内容是什么 实参即传递给函 ...

  8. c++之指针和引用作为函数参数传递时的区别

    之前写过c++之值传递.引用传递.指针传递,今天再单独区分一下指针和引用作为函数参数传递时的区别. 本文参考浅谈C++中指针和引用的区别 一.指针作为函数参数传递时 1.类似于值传递,传入函数的指针只 ...

  9. 函数的形参(普通形参、指针形参、引用形参)

    以一些代码段为例: 1.普通形参 int n=10; add1(n);void add1(int v1) { v1+=1;//对实参无影响 } 这是最普通的形参方式,形参仅仅为实参的一个副本,对形参的 ...

最新文章

  1. 直播|清华谢晓晖——面向互联网图像搜索的用户行为模型研究
  2. mdpi的手机_【初印象】Android手机屏幕适配API:nodpi,xhdpi,hdpi,mdpi,ldpi
  3. PHP使用GD库封装验证码类
  4. 某虚拟化项目总结:一条光纤引发的故障
  5. 数字图像处理--图像二阶导数的推导
  6. 获2017中国最佳创业投资机构百强,西高投二次创业实现超越
  7. 四、python沉淀之路--元组
  8. Apple Music成为全球第二大音乐流媒体服务 远落后Spotify
  9. PostgreSQL在何处处理 sql查询之五十三
  10. Python Scrapy 爬虫框架实例(一)
  11. 在 Kali Linux安装环境中,配置网络出现DHCP错误,解决方案。(安装kali Linux的网络配置失败问题)
  12. C#图片无损转换为ico格式
  13. JEECMS V8.1常用标签举例
  14. [LetCode-1438] 绝对差不超过限制的最长连续子数组
  15. SQL/PL SQL
  16. TabControl控件在左侧绘制tabPage页面
  17. DDOS攻击相关问题
  18. SAP MB5B报表ALV显示
  19. 【P02】47耳放的优化版本,全资料下载
  20. NBA表格_双红!34中24!NBA季后赛【掘金vs湖人】

热门文章

  1. 学习笔记——基本光照模型简单实现
  2. java 读取中文配置文件问题
  3. eclipse 3.6的VE配置 Visual Editor for eclipse3.6
  4. NYOJ 620 真实的谎言
  5. 欧拉函数和最大公约数的组合应用
  6. iis 防火墙防止恶意ip攻击
  7. SCU3033 Destroying a Painting(最小费用最大流)
  8. KVM(Keyboard、Video、Mouse)
  9. Reporting Service 钻取
  10. 正则表达式匹配C++代码实现