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

  • 按值传递(pass by value)
#include <iostream>
using namespace std; void swap(int a,int b)
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int a = 0, b = 1;
cout << a << " " << b << endl;
swap(a,b);
cout << a << " " << b << endl;
return 0;
}



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

  • 按址传递(pass by pointer)
#include <iostream>
using namespace std; void swap(int* a,int* b)
{
int* temp = a;
a = b;
b = temp;
} int main()
{
int a = 0, b = 1;
cout << a << " " << b << endl;
swap(a,b);
cout << a << " " << b << endl;
return 0;
}



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

  • 引用传递(pass by reference)
#include <iostream>
using namespace std; void swap(int &a,int &b)
{
int temp = a;
a = b;
b = temp;
} int main()
{
int a = 0, b = 1;
cout << a << " " << b << endl;
swap(a,b);
cout << a << " " << b << endl;
return 0;
}



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

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

传递效率

这里所说传递效率,是说调用被调函数的代码将实参传递到被调函数体内的过程,正如上面代码中,这个过程就是函数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. python OptionParser模块使用

    OptionParser是python中用来处理命令行的模块,在我们使用python进行流程化开发中必要的工具 Optparse,它功能强大,而且易于使用,可以方便地生成标准的.符合Unix/Posi ...

  2. 【Unity】 Cursor学习

    CursorLockMode.None 光标行为未修改,第一人称视角下鼠标可以突破窗口. CursorLockMode.Locked 光标锁定到游戏窗口的中心,与全屏与否无关,同时隐藏光标(这一点在3 ...

  3. centos7以上安装python3,一条命令搞定。

    直接复制下面的命令就搞定 yum install python34 python34-pip python34-setuptools 使用方法: python3 ---.py pip3 install ...

  4. HackRF 升级固件到新版本

    本文内容.开发板及配件仅限用于学校或科研院所开展科研实验! 淘宝店铺名称:开源SDR实验室 HackRF链接:https://item.taobao.com/item.htm?spm=a1z10.1- ...

  5. 初学node.js-nodejs中实现HTTP服务(3)

    一.node.js实现服务端 创建hello-world-server.js文件,服务端源码如下: /** * node.js实现http服务端 */ var http = require('http ...

  6. 占位符golang

    定义示例类型和变量 type Human struct { Name string } var people = Human{Name:"zhangsan"} 普通占位符 占位符 ...

  7. e2fsck命令详解

    原文链接:https://ipcmen.com/e2fsck Linux e2fsck命令用于检查使用 Linux ext2 档案系统的 partition 是否正常工作. 语法 e2fsck [-p ...

  8. Django_cookie+session

    一.cookie和session介绍 cookie 由服务器产生内容,浏览器收到请求后保存在本地:当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁 ...

  9. sprint2(第三天)

    展板 燃尽图

  10. mysql和oracle查询出的一条结果中的多个字段拼接

    1,mysql concat('a','b','c')和concat_ws('a','b','c')的区别:前者如果有某个值为空,结果为空;后者如果有某个值为空,可以忽略这个控制 SELECT con ...