参数传递即实参向形参传递信息,使形参获得对应的存储空间及初值,C++中函数传递主要有3种方式:

1、按值传递。

以按值传递方式进行参数传递的过程为:首先计算出实参的值,然后给它所对应的形参变量分配存储空间,该空间大小等于该形参类型的长度,然后把实参值存入到为形参分配的存储空间里去,该值即为形参的初值,在函数被调用时使用。而这种方式被调用的函数对实参的值改变不会有任何的影响,也就是说,即使形参的值在函数中被改变,也不会对实参值产生任何影响,实参值仍为被调用之前的值。究其原因还是实参和形参各占独立的存储单元,彼此之间互不影响。

按值传递引例:
#include <iostream>
using namespace std;
void swap(int a,int b);
int main(void)
{
    int a=1,b=2;
    cout<<"a="<<a<<",b="<<b<<endl;
    swap(a,b);
    cout<<"a="<<a<<",b="<<b<<endl;
    return 0;
}
void swap(int a,int b)
{
    int c=a;
    a=b;
    b=c;

}

运行结果为:

a=1,b=2

a=1,b=2

注意,虽然形参和实参都是a b,但它们是被分配到了不同的存储空间,这涉及到作用域问题。

总结:(1)只有在函数被调用时,才为形参分配内存空间并赋予初值,当函数调用结束后,形参的内存空间被释放,同时函数返回值(如果有的话);

(2)调用函数时形参实参类型必须一致,int型对应int型,同理double型对应double型,以此类推,否则程序会出错;

(3)C++中函数参数的求值顺序也即传递顺序从右向左,例如:

#include <iostream>
using namespace std;
int sum(int x,int y);
int main(void)
{
    int a,b;
    a=1;b=2;
    cout<<sum(++a,a+b)<<endl;
    a=1;b=2;
    cout<<sum(a+b,++a)<<endl;
    return 0;
}
int sum(int x,int y)
{
    return x+y;
}

运行结果为:

5

6

2,、地址传递。

在定义函数的时候如果将形参值定义为指针变量,则调用该函数的时候实参应为地址,这种传递方式即为地址传递。与按值传递不同的是,地址传递是将实参的存储地址传递给对应形参,从而使形参指针和实参的指针都指向同一个地址,所以被调用函数中形参指针指向的地址中内容的改变同时会造成实参内容的改变。

地址传值引例:

#include <iostream>
using namespace std;
void swap(int *,int *);
int main(void)
{
    int a=1,b=2;
    cout<<"a="<<a<<",b="<<b<<endl;
    swap(&a,&b);
    cout<<"a="<<a<<",b="<<b<<endl;
    return 0;
}
void swap(int *,int *)
{
    int c=*a;
    *a=*b;
    *b=c;
}

运行结果:

a=1,b=2

a=2,b=1

注意:此时的实参和形参仍然占用不同的存储单元,只是它们的指针指向的是同一个地址。

3、引用传递

引用是C语言所没有而C++提供的一种新特性,引用可以看做是变量或者对象的别名,当建立引用的时候,程序用一个变量或者对象的名字初始化它,这样引用就可以当做该变量或者对象的别名所使用,因此对引用的改变就是对变量或者对象本身的改变。引用的语法格式如下所示:

变量类型& 引用名=变量名;

例如定义一个整型变量的引用:

int a;

int& refa=a;     \\refa作为a的别名

refa=10;

a-=40;

cout<<a<<endl;

输出结果为-30。此时系统没有为refa分配存储空间,它和a代表了相同的内存空间,对refa进行改变就是对a进行改变。引用的建立和使用引例:

#include <iostream>
using namespace std;
int main(void)
{
    int a=3,b=2;
    int &a=refa,&b=refb;
    refa=a+2;
    b=refa+1;
    cout<<refa<<" "<<a<<endl;
    cout<<refb<<" "<<b<<endl;
    refa=b;
    cout<<refa<<" "<<a<<endl;
    return 0;
}
运行结果为:

5 5

3 3

3 3

注意:(1)引用在定义的时候必须被初始化,必须指定是哪个变量或对象的别名,类型对应一致;

(2)引用仅仅是变量或者对象的别名,系统不会为它分配内存空间;

(3)引用一旦建立就不能被改变,即它已跟定了该变量或者对象,不能作为其它变量或对象的别名。

按值传递易理解但改变形参不能对实参产生影响,地址传递虽可以,但是在函数中多次用指针进行间接访问会使程序难以阅读,且易产生错误,而引用完美解决了上述两个问题。引用传递是在函数定义时在形参前面加上“&”。

引用传递引例:

#include <iostream>
using namespace std;
void swap(int &,int &);
int main(void)
{
    int a=1,b=2;
    cout<<"a="<<a<<",b="<<b<<endl;
    swap(a,b);
    cout<<"a="<<a<<",b="<<b<<endl;
    return 0;
}
void swap(int &,int &)
{
    int c=a;
    a=b;
    b=c;
}

以上即为C++函数调用时的三种传递方式。

C++函数调用时的参数传递

C++函数调用时的参数传递-3中传递方式的更多相关文章

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

    在C++中,参数传递的方式是“实虚结合”. 按值传递(pass by value) 地址传递(pass by pointer) 引用传递(pass by reference) 按值传递的过程为:首先计 ...

  2. C++中函数调用时的三种参数传递方式

    在C++中,参数传递的方式是“实虚结合”. 按值传递(pass by value) 地址传递(pass by pointer) 引用传递(pass by reference) 按值传递的过程为:首先计 ...

  3. python函数调用时参数传递方式

    python函数调用时参数传递方式 C/C++参数传递方式 对于C程序员来说,我们都知道C在函数调用时,采用的是值传递,即形参和实参分配不同的内存地址,在调用时将实参的值传给实参,在这种情况下,在函数 ...

  4. C/C++函数调用时传参过程与可变参数实现原理

    C/C++函数调用时传参过程与可变参数实现原理 C语言的经典swap问题 在学习C语言的时候,我们大都遇到过一些经典例题,这些经典例题背后所代表的是往往是C/C++背后的一些运行原理,比如下面这个示例 ...

  5. 如何才能实现在点击链接时直接在网页中打开word文档,但不提示保存

    一般要直接打开需要客户端 1.客户端有word支持 2.客户端浏览器的版本与设置 可寻找一下相关的控件或中间件,我的意见是看能否变通一下,把word转成HTML或PDF再展示给用户.(若用户不需要编辑 ...

  6. ssh下:系统初始化实现ServletContextListener接口时,获取spring中数据层对象无效的问题

    想要实现的功能:SSH环境下,数据层都交由Spring管理:在服务启动时,将数据库中的一些数据加载到ServletContext中缓存起来. 系统初始化类需要实现两个接口: ServletContex ...

  7. MVC4.0中项目发布遇到IE11时session存入URL中,导致记不住密码的问题

    ///MVC4.0中项目发布遇到IE11时session存入URL中,导致记不住密码的问题,在webconfig中配置<system.web><authentication mode ...

  8. 关于C#读取MySql数据时,返回DataTable中某字段数据是System.Array[]形式

    我在使用C#(VS2008)读取MySql数据库(5.1版本)时,返回的DataTable数据中arrivalDate字段数据显示为System.Array[]形式(程序中没有对返回的数据进行任何加工 ...

  9. jquery mobile 请求数据方法执行时显示加载中提示框

    在jquery mobile开发中,经常需要调用ajax方法,异步获取数据,如果异步获取数据方法由于网速等等的原因,会有一个反应时间,如果能在点击按钮后数据处理期间,给一个正在加载的提示,客户体验会更 ...

随机推荐

  1. js 社会主义点击事件

    index.js 效果演示地址: https://www.purecss.cn/ (function() { var coreSocialistValues = ["富强", &q ...

  2. ssh 反向代理和正向代理的文章

    搜索原因是,我希望访问家里内网的机器 技术要点: ssh 反向代理,正向代理 隧道 文章摘自: https://my.oschina.net/leejun2005/blog/94401 https:/ ...

  3. jumpserver 3.2修改排序规则

    在默认的情况下,我们使用jumpserver的时候 这里我使用xshell 客户端连接到堡垒机的时候, 这里我的显示规则是根据IP排序的,但是我这里的服务器的hostname 都是根据场景设置的hos ...

  4. 牛腩学ASP.NET CORE做博客(视频)

    牛腩学习ASP.NET CORE做的项目,边学边做. 目录: 01-dotnetcore网站部署到centos7系统上(时长 2:03:16) 02-前期准备及项目搭建 (时长:0:23:35) 03 ...

  5. 91平台iOS接入demo

    源码:http://pan.baidu.com/s/1DuBl6 今天整理硬盘,找到了一个有趣的demo.一年前,91助手游戏联运呈爆棚趋势,但是许多使用FlashAir开发的优秀的游戏和应用都卡在了 ...

  6. 【再话FPGA】在xilinx中PCIe IP Core使用方法

    采用Xilinx Virtex-5 XC5VSX50T-FF1136 FPGA或者Xilinx Virtex-5 XC5VSX95T-FF1136的板子.采用ISE13.2环境.步骤:一.建立一个IS ...

  7. 【Unity】4.5 树木创建器

    分类:Unity.C#.VS2015 创建日期:2016-04-11 一.简介 在地形编辑器一节中,已经告诉了你如何使用已经创建好的树来形成大片树林.这一节告诉你在 Unity 5.3.4中如何利用[ ...

  8. Tornado中gen.coroutine详解

    1.gen.coroutine的作用 自动执行生成器 2.Future对象 在介绍异步使用之前,先了解一下Future对象的作用. Future简单可以理解为一个占位符,将来会执行的对象,类似java ...

  9. lua 的 table 处理

    lua 的整体效率是很高的,其中,它的 table 实现的很巧妙为这个效率贡献很大. lua 的 table 充当了数组和映射表的双重功能,所以在实现时就考虑了这些,让 table 在做数组使用时尽量 ...

  10. DPDK(mtcp)vs RDMA/ROCE

    0. 缠论: http://52investing.com/ 1. 简书.DPDK: http://www.jianshu.com/p/dcb6ccc83ea52. mTCP 和 DPDK 构造百万千 ...