众所周知,在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. 009--EXPLAIN用法和结果分析

    在日常工作中,我们会有时会开慢查询去记录一些执行时间比较久的SQL语句,找出这些SQL语句并不意味着完事了,些时我们常常用到explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有 ...

  2. Netty源码分析第4章(pipeline)---->第2节: handler的添加

    Netty源码分析第四章: pipeline 第二节: Handler的添加 添加handler, 我们以用户代码为例进行剖析: .childHandler(new ChannelInitialize ...

  3. Harbor 学习分享系列2 - Harbor项目介绍

    云盘链接 链接:https://pan.baidu.com/s/19yZCZMijf1c3rTwYOqiZzw 密码:netv 通过本文无法把本文中的实验进行成功,请联系作者本人,作者会录制视频发送给 ...

  4. 分享一篇IBN(Intent-based networking)调研报告

    IBN调研报告 背景 SDN(Software-defined network):最大特点在于具有松耦合的控制平面与数据平面.支持集中化的网络状态控制.实现底层网络设施对上层应用的透明.具有灵活的软件 ...

  5. Streamr助你掌控自己的数据(1)——教你5分钟上传数据至Streamr

    博客说明 所有刊发内容均可转载但是需要注明出处. 教你5分钟上传数据至Streamr 本系列文档主要介绍怎么通过Streamr管理自己的DATA,整个系列包括三篇教程文档,分别是:教你5分钟上传数据至 ...

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

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

  7. 学习笔记 | Set

    目录 Set Set 前言 不会数据结构选手 当几乎没写过什么数据结构的菜鸡遇上了毒瘤的splay和treap 时间正一点一点地被续走TAT 听说set有时候可以替代treap和splay 那么菜鸡L ...

  8. gulp-babel 阻止了js文件编译的进程?

    现象 :   编译打包的js没有输出到目标文件夹里,只是单单的生成了一个目标目录,目录里没有文件 解决方法:gulp-babel ^8.0.0 使用了 ^7.0.1的 依赖插件.统一gulp-babe ...

  9. 互评Beta版本——可以低头,但没必要——取件帮

    基于NABCD评论作品,及改进建议 1. 根据(不限于)NABCD评论作品的选题 (1)N(Need,需求) 取件帮是一款有偿互助取件的微信小程序,很大程度上解决了学生因为距离.时间等原因无法取快递的 ...

  10. Notes of Daily Scrum Meeting(11.11)

    Notes of Daily Scrum Meeting(11.11) 今天是11月11号光棍节,不知道大家的购物热情被点燃没有,有没有买到自己心仪的东西.额,今天我们的团队任务进度和昨天差不多, 每 ...