众所周知,在C++中有三种参数传递的方式:

  • 按值传递(pass by value)
  1. #include <iostream>
  2. using namespace std;
  3. void swap(int a,int b)
  4. {
  5. int temp = a;
  6. a = b;
  7. b = temp;
  8. }
  9. int main()
  10. {
  11. int a = 0, b = 1;
  12. cout << a << " " << b << endl;
  13. swap(a,b);
  14. cout << a << " " << b << endl;
  15. return 0;
  16. }



最好理解的一种方式。调用函数本身不对实参进行操作,也就是说,即使形参的值在函数中发生了变化,实参的值也完全不会受到影响,仍为调用前的值。

  • 按址传递(pass by pointer)
  1. #include <iostream>
  2. using namespace std;
  3. void swap(int* a,int* b)
  4. {
  5. int* temp = a;
  6. a = b;
  7. b = temp;
  8. }
  9. int main()
  10. {
  11. int a = 0, b = 1;
  12. cout << a << " " << b << endl;
  13. swap(a,b);
  14. cout << a << " " << b << endl;
  15. return 0;
  16. }



这种方式在函数定义时将形参说明成指针。把实参的存储地址传送给对应的形参,从而使得形参指针和实参指针指向同一个地址。因此,被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参

  • 引用传递(pass by reference)
  1. #include <iostream>
  2. using namespace std;
  3. void swap(int &a,int &b)
  4. {
  5. int temp = a;
  6. a = b;
  7. b = temp;
  8. }
  9. int main()
  10. {
  11. int a = 0, b = 1;
  12. cout << a << " " << b << endl;
  13. swap(a,b);
  14. cout << a << " " << b << endl;
  15. return 0;
  16. }



引用传递方式是在函数定义时在形参前面加上引用运算符“&”。如果以引用为参数,则既可以使得对形参的任何操作都能改变相应的数据,又使得函数调用显得方便、自然。

本文主要讨论采用这三种方法传递参数时函数的效率。

传递效率

这里所说传递效率,是说调用被调函数的代码将实参传递到被调函数体内的过程,正如上面代码中,这个过程就是函数main()中的 a、b 传递到函数swap()中的过程。这个效率不能一概而论。对于内建的 int char、short、long、float 等4字节或以下的数据类型而言,实际上传递时也只需要传递 1-4 个字节,而使用指针传递时在 32 位 cpu 中传递的是 32 位的指针,4 个字节,都是一条指令,这种情况下值传递和指针传递的效率是一样的,而传递 double、long long 等 8 字节的数据时,在 32 位 cpu 中,其传值效率比传递指针要慢,因为 8 个字节需要 2 次取完。而在 64 位的 cpu 上,传值和传址的效率是一样的。再说引用传递,这个要看编译器具体实现,引用传递最显然的实现方式是使用指针,这种情况下与指针的效率是一样的,而有些情况下编译器是可以优化的,采用直接寻址的方式,这种情况下,效率比传值调用和传址调用都要快,与采用全局变量方式传递的效率相当。

再说自定义的数据类型 —— class struct 定义的数据类型。这些数据类型在进行传值调用时生成临时对象会执行构造函数,而且当临时对象销毁时会执行析构函数,如果构造函数和析构函数执行的任务比较多,或者传递的对象尺寸比较大,那么传值调用的消耗就比较大。这种情况下,采用传址调用和采用传引用调用的效率大多数下相当,正如上面所说,某些情况下引用传递可能被优化,总体效率稍高于传址调用。

执行效率

这里所说的执行效率,是指在被调用的函数体内执行时的效率。 因为传值调用时,当值被传到函数体内,临时对象生成以后,所有的执行任务都是通过直接寻址的方式执行的,而指针和大多数情况下的引用则是以间接寻址的方式执行的,所以实际的执行效率会比传值调用要低。如果函数体内对参数传过来的变量进行操作比较频繁,执行总次数又多的情况下,传址调用和大多数情况下的引用参数传递会造成比较明显的执行效率损失。

综上所述,具体的执行效率要结合实际情况,通过比较传递过程的资源消耗和执行函数体消耗之和来选择哪种情况比较合适。而就引用传递和指针传递的效率上比,引用传递的效率始终不低于指针传递,所以从这种意义上讲,在c++中进行参数传递时优先使用引用传递而不是指针。

参考:C++中函数调用时的三种参数传递方式详解

C++中三种传递参数方法的效率分析的更多相关文章

  1. jsp中四种传递参数的方法

    jsp中四种传递参数的方法如下: 1.form表单 2.request.setAttribute();和request.getAttribute(); 3.超链接:<a herf="i ...

  2. (转)JSP中四种传递参数的方法:

    1.form表单 2.request.setAttribute();和request.getAttribute(); 3.超链接:<a herf="index.jsp"?a= ...

  3. iOS——浅谈iOS中三种生成随机数方法

    ios 有如下三种随机数方法:

  4. Sql Server中三种字符串合并方法的性能比较

    文章来自:博客园-DotNet菜园 最近正在处理一个合并字符吕的存储过程,在一个测试系统的开发中,要使用到字符串合并功能,直接在Sql中做.示例:有表內容﹕名称  內容1     abc1      ...

  5. C++中三种创建对象的方法【转】

    我们都知道C++中有三种创建对象的方法,如下: #include <iostream> using namespace std; class A { private: int n; pub ...

  6. iOS-浅谈iOS中三种生成随机数方法

    ios 有如下三种随机数方法:

  7. 分布式环境中三种Session管理方法的使用场景及优缺点

    在分布式环境,管理Session通常使用下面三种方式: 一.Session Replication 方式管理 (即session复制)         简介:将一台机器上的Session数据广播复制到 ...

  8. OpenCL中三种内存创建image的效率对比

    第一种:使用ION: cl_mem_ion_host_ptr ion_host_ptr1; ion_host_ptr1.ext_host_ptr.allocation_type = CL_MEM_IO ...

  9. js中三种全局变量声明方法

    声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量.该方式即为显式声明详细如下: <script> ...

随机推荐

  1. dom学习要点

    Dom操作 1.文本内容操作 - innerText:操作文本 - innerHtml:操作全内容 //innerText标签: <div id='i2' ><a>土味程序员& ...

  2. FICO(费埃哲)评分系统有什么优缺点?在国内的发展怎么样?

    权威回答: FICO的优点很明显: 在美国数据库较全面.一般存储有最近7-10年的个人信用记录,包括银行信用.商业信用甚至保险等. 客观性.计算机自动完成评估工作,克服人为操作的失误. 快捷性.出结果 ...

  3. 实验一linux 系统简介和实验二基本概念及操作

    作业 zy e

  4. iOS自学-UILabel常见属性

    #import "ViewController.h" #import <CoreText/CoreText.h> @interface ViewController ( ...

  5. Leetcode题库——26.删除排序数组中的重复项

    @author: ZZQ @software: PyCharm @file: removeDuplicates.py @time: 2018/9/23 13:51 要求: 给定一个排序数组,你需要在原 ...

  6. Leetcode题库——21.合并两个有序链表

    @author: ZZQ @software: PyCharm @file: mergeTwoLists.py @time: 2018/9/16 20:49 要求:将两个有序链表合并为一个新的有序链表 ...

  7. “吃神么,买神么”的第二个Sprint计划(总结)

    “吃神么,买神么”项目Sprint计划 ——5.28  星期四(第八天)第一次Spring计划结束   第一阶段Spring的目标以及完成情况: 时间:5月21号~5月28号(7天) 目标:第二阶段主 ...

  8. Internet History, Technology and Security (Week2)

    Week2. History: The First Internet - NSFNet coursera address Supercomputers Justify a National Netwo ...

  9. 小学四则运算结对项目报告(GUI)

    小学四则运算结对项目报告(GUI) 一.Coding.Net项目地址: https://git.coding.net/wsshr/Calculation.git 二.PSP表格(完成前): PSP 任 ...

  10. 关于Keil C关键字xdata和data的问题

    1.xdata表示这是一个外部RAM地址内的数据,数据最终将被保存至外部RAM的某个地址单元中:但是,外部RAM只能通过寄存器间接寻址来访问,也就是说,其地址需要保存在内部RAM中(其实或许是SFR中 ...