这次我们要透过一个简单的函数swap深入理解函数传参的本质以及在C++中如何选择传参方式。

先来看第一段程序:

void swap(int x, int y) {
int temp = y;
y = x;
x = temp;
}

通过main函数的调用,我们发现x,y并未实现交换:

int main()
{
int x = ;
int y = ; swap(x, y); cout << x << ":" << y << endl;
return ;
}

原因是整形x和y在函数swap内为按值传递,按值传递时,函数不会访问当前调用的实参。函数处理的值是它本地的拷贝,这些拷贝被存储在运行栈中,因此改变这些值不会影响实参的值。一旦函数结束了,函数的活动记录将从栈中弹出,这些局部值也就消失了。

在按值传递的情况下,实参的内容没有被改变。这意味着程序员在函数调用时无需保存和恢复实参的值。如果没有按值传递机制,那么每个没有被声明为const 的参数就可能会随每次函数调用而被改变。按值传递的危害最小,需要用户做的工作也最少。毫无疑问,按值传递是参数传递合理的缺省机制。

另外,如果作为实参的变量是一个大型类的对象,分配并拷贝到栈中的时间和空间开销往往过大。

要实现swap函数的效果,我们应如何处理呢?第一个可行的做法是将形参声明成指针:

void pswap(int *x, int *y) {
int temp = *y;
*y = *x;
*x = temp;
}

在pswap函数中,由于传递的是两个变量的内存地址(指针)使得我们可以直接操作对应的值。实际上这里还是存在按值传递的问题,只是由原先的整形传递变成了指针传递。我们可以修改指针指向的内存却依然无法修改指针本身。第二个可行的做法是想形参声明为指针的引用:

void prswap(int *&x, int *&y) {
int temp = *y;
*y = *x;
*x = temp;
} void prswap(int *&x, int *&y) {
int *temp = y;
y = x;
x = temp;
}

请注意,同一个函数原型下我提供了两种函数定义。可无论哪一种,在实参传递的阶段都不会发生按值传递的问题。那么两种定义到底哪一种更满足我们需求:

(1)交换内存中的值

(2)交换指针地址

如果单独考虑本文的需求,第一种方法更满足。但是,如果我们需要交换的是一个大型类对象,第二种的效率则更高。

总结:内存管理是C++学习的一个难点,初学者往往不容易掌握。但越是如此就越能体现一个开发者的语言内功。

C++学习笔记(二)——交换函数(swap)的更多相关文章

  1. linux shell学习笔记二---自定义函数(定义、返回值、变量作用域)介绍

    linux shell 可以用户定义函数,然后在shell脚本中可以随便调用.下面说说它的定义方法,以及调用需要注意那些事项. 一.定义shell函数(define function) 语法: [ f ...

  2. [C语言学习笔记二] extern 函数的用法

    extern 用来定义一个或多个变量.其后跟数据类型名和初始值.例如: extern int a =10 它与 int,long long int,double,char的本质区别,在于 extern ...

  3. ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring

    接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...

  4. python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法

    python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法 在Python中字符串处理函数里有三个去空格(包括'\n', '\r', '\t', ' ')的函数 ...

  5. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  6. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  7. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  8. IOS学习笔记06---C语言函数

    IOS学习笔记06---C语言函数 --------------------------------------------  qq交流群:创梦技术交流群:251572072              ...

  9. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  10. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

随机推荐

  1. tensorflow显存管理

    在运行上面的blog的Tensorflow小程序的时候程序我们会遇到一个问题,当然这个问题不影响我们实际的结果计算,但是会给同样使用这台计算机的人带来麻烦,程序会自动调用所有能调用到的资源,并且全占满 ...

  2. python解决matplotlib中文坐标值乱码的问题

    加上这句话即可 plt.rcParams['font.sans-serif']=['SimHei'] 效果:

  3. 主成分分析(PCA)学习笔记

    这两天学习了吴恩达老师机器学习中的主成分分析法(Principal Component Analysis, PCA),PCA是一种常用的降维方法.这里对PCA算法做一个小笔记,并利用python完成对 ...

  4. AI+教育落地,百度大脑如何让校园更智能?

    人工智能作为影响社会底层技术革命逐渐向传统行业渗透,“AI+”已经替代“互联网+”成为创业创新的新引擎,出人意料的是,在AI在教育业的率先落地并且相当火爆. 现在,人工智能教育已成为从业者心目中的“教 ...

  5. python之路----模块调用

    如何使用模块? 1 import 示例文件:自定义模块my_module.py,文件名my_module.py,模块名my_module #my_module.py print('from the m ...

  6. bzoj2982: combination(Lucas定理)

    Description LMZ有n个不同的基友,他每天晚上要选m个进行[河蟹],而且要求每天晚上的选择都不一样.那么LMZ能够持续多少个这样的夜晚呢?当然,LMZ的一年有10007天,所以他想知道答案 ...

  7. c++ sleep(windows/linux)

    c标准中包含了一个sleep用以实现当前线程暂停执行n毫秒,如下所示: 函数名: sleep 功 能: 执行挂起一段时间 用 法: unsigned sleep(unsigned seconds); ...

  8. 关于cp命令的编写

    关于cp命令的编写 娄老师在课上详细的讲了命令who的编写过程~对此,我很有启发!于是想亲自动手试试~ 有什么不足的地方请大家提出来! Learning by doing ~ 做中学,真的只有自己动手 ...

  9. devicePixelRatio手机图片模糊的原因

    一.移动设备图片模糊问题 手机上图片模糊问题原因就是一个像素在电脑上和手机上代表的实际像素的不同. 我们在样式表中使用的px(独立像素)单位其实并不一定代表着实际的一个像素(物理像素),这还要看硬件的 ...

  10. JAVA I/O(一)基本字节和字符IO流

    最近再看I/O这一块,故作为总结记录于此.JDK1.4引入NIO后,原来的I/O方法都基于NIO进行了优化,提高了性能.I/O操作类都在java.io下,大概将近80个,大致可以分为4类: 基于字节操 ...