文档章节

函数调用三种方式:传值&传引用&传指针

o
 onedotdot
发布于 2017/08/27 11:25
字数 1075
阅读 21
收藏 1

相关概念

c++三种传递参数方式

传参数的值(称值传递,简称传值),传参数的地址(称地址传递,简称为传址),和引用传递(称为传引用),相应的函数传值调用,传址调用和传引用调用

形参、实参

 函数定义时参数表中的参数称为形式参数,简称形参;函数调用时参数表中的参数称为实际参数,简称实参。实参和形参之间的数据传递称为形实结合

说明

通常情况下,C++是传值调用,它是单向的,只能从实参到形参。形参实质上市实参的一种拷贝,所以传递时不会改变外部实参的值

引用的含义及功能

即别名,功能主要是传递函数的参数和返回值

引用的规则

(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。

(2)不能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL)。

(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。

 

 

 

 

实例

#include <iostream>

using namespace std ;

void Swap(int x, int y) ;

int main(void)

{

int a = 1 ;

int b = 2 ;

 

cout << "a = " << a << ", " << "b = " << b << endl ;

 

Swap(a, b) ;

 

cout << "a = " << a << ", " << "b = " << b << endl ;

 

system("pause") ;

return 0 ;

}

 

一:值传递

void Swap(int x, int y)

{

int temp = x ;

x = y ;

y = temp ;

}

 

输出结果:

a = 1, b = 2

a = 1, b = 2

原因:Swap(int x, int y)函数采用值传递的方式,传入的实参实际上是a和b的副本而非其本身,所以对副本的改变并不会反应到a和b本身上。

 

二:引用传递

void Swap(int &x, int &y)

{

int temp = x ;

x = y ;

y = temp ;

}

输出结果:

a = 1, b = 2

a = 2, b = 1

原因:Swap(int x, int y)函数采用引用传递的方式,传入的实参实际上是a和b的引用,对引用的改变会直接反应到a和b本身上。

 

三:指针传递

1.  改变指针本身

void Swap(int *x, int *y)

{

int *temp = x ;

x = y ;

y = temp ;

}

 

调用方法:Swap(&a, &b) ;

 

输出结果:

a = 1, b = 2

a = 1, b = 2

原因:Swap(int x, int y)函数采用指针传递的方式,传入的实参实际上是a和b的指针的副本,而且改变的是副本本身而非其间接引用,所以不会影响的指针所指向的值,即a和b本身上。

 

2.  改变指针的间接引用

 

void Swap(int *x, int *y)

{

int temp = *x ;

*x = *y ;

*y = temp ;

}

 

调用方法:Swap(&a, &b) ;

 

输出结果:

a = 1, b = 2

a = 2, b = 1

原因:Swap(int x, int y)函数采用指针传递的方式,传入的实参虽然也是a和b的指针的副本,但是改变的是副本的间接引用,无论是指针本身还是其副本,都指向相同的值,所以这个改变会反应到a和b本身上。

效率比较

程序代码

//#include "stdafx.h"

#include "iostream"

#include "windows.h"

//#include "winbase.h"

using namespace std;

void TestValue(double val1,double val2);

void TestRef(double &val1,double &val2);

void TestPointer(double *val1,double *val2);

main()

{

double a = 1.5;

double b = 5.0;

DWORD dwStartTime;

DWORD dwEndTime;

dwStartTime= GetTickCount();

int i;

for(i=0;i<100000000;i++)

TestValue(a,b);

dwEndTime= GetTickCount();

cout << "\nTime1=" << dwEndTime - dwStartTime << endl;

dwStartTime= GetTickCount();

for(i=0;i<100000000;i++)

TestRef(a,b);

dwEndTime= GetTickCount();

cout << "\nTime2=" << dwEndTime - dwStartTime << endl;

dwStartTime= GetTickCount();

for(i=0;i<100000000;i++)

TestPointer(&a,&b);

dwEndTime= GetTickCount();

cout << "\nTime3=" << dwEndTime - dwStartTime << endl;

cin.get();

return 0;

}

void TestValue(double val1,double val2)

{

double val = val1 + val2;

}

void TestRef(double &val1,double &val2)

{

double val = val1 + val2;

}

void TestPointer(double *val1,double *val2)

{

double val = *val1 + *val2;

}

运行结果

Debug下:

第一次:1713 1718 1719

第二次:1714 1708 1709

第三次:1713 1718 1719

Release下:

第一次:266 266 218

第二次:282 265 219

第三次:266 265 235

可以进一步查看反汇编代码,分析比较其指令

总结:传引用=传指针

 

===================

 

第二个传引用,传的不就是指针变量么?

第三个传指针,传的实际是地址类型变量?

因为    int i = 10;   int * p = &i;   第二个写法 是对的?

第一个传值,其实就是函数从新开辟新的动态内存,然后从新声明的新的变量在赋值而已;

 

 

本文转载自:http://blog.csdn.net/gyysmall/article/details/8247059

共有 人打赏支持
o
粉丝 8
博文 364
码字总数 14726
作品 0
朝阳
私信 提问
C++传值、传引用

C++传值、传引用 C++的函数参数传递方式,可以是传值方式,也可以是传引用方式。传值的本质是:形参是实参的一份复制。传引用的本质是:形参和实参是同一个东西。 传值和传引用,对大多数常见...

lovedan
2017/05/07
0
0
C语言-传值,传地址(指针),传引用区别和联系

很多编程老手对传值,传地址,传引用的区别搞的也不会很清楚,今天我就花一点时间再次介绍一下这些概念的本质。 其实,不用分为三类,只有两类即可。传值和传引用。为什么会出现传地址(即传...

abaojin
2015/11/11
0
0
PHP传值和传引用、传地址的区别是什么?

传值, 是把实参的值赋值给行参 那么对行参的修改, 不会影响实参的值 传地址 是传值的一种特殊方式,只是他传递的是地址,不是普通的如int 那么传地址以后,实参和行参都 指向同一个对象 传...

morebetter1
2018/07/02
0
0
Go语言的传参和传引用

传参和传引用的问题 很多非官方的文档和教材(包括一些已经出版的图书), 对Go语言的传参和引用的讲解都有很多问题. 导致众多Go语言新手对Go的函数参数传参有很多误解. 而传参和传引用是编程语...

chai2010
2013/09/14
16.9K
30
详解 JAVA 创建对象 NEW

假设我们在函数中写了如下这个简单的语句:   StringBuffer str = new StringBuffer("Hello world");   别看这个语句简单,其实包含了如下三个步骤:   首先,newStringBuffer("He...

klog
2016/11/27
18
0

没有更多内容

加载失败,请刷新页面

加载更多

MySQL查询执行

当我们希望MySQL能够以更高的性能运行查询时,最好的办法就是弄清楚MySQL是如何优化和执行查询的。一旦理解了这一点,很多查询优化工作实际上就是遵循一些原则让优化器能够按照预想的合理方式...

问题终结者
51分钟前
1
0
CDH5动静态资源池配置与回滚

关于动态 静态资源池的配置以前都有提过,可以从以下几篇了解: YARN动态资源池配置案例 https://yq.aliyun.com/ziliao/346856# Hadoop YARN配置参数剖析(4)—Fair Scheduler相关参数 Hadoop...

hblt-j
56分钟前
3
0
WordPress仿站实战教程

有一个月没有写blog了,一直在学习wordpress的知识,现在能够进行简单的政府企业门户网站的仿制,wordpress的主题订制,一般是对前端要求比较高,wordpress学会了,建站还是非常的快的。下面...

临江仙卜算子
59分钟前
3
0
图像库stb_image

https://github.com/nothings/stb 目前一般主流的图像格式也就是bmp,jpg,png,tga,dds,除了DDS一般是给DX用的,虽然一堆OpenGL程序也有用的,但是我一般只用png和tga, png不用说了,带a...

robslove
今天
1
0
Spring 事务提交回滚源码解析

前言 在上篇文章 Spring 事务初始化源码分析 中分析了 Spring 事务初始化的一个过程,当初始化完成后,Spring 是如何去获取事务,当目标方法异常后,又是如何进行回滚的,又或是目标方法执行...

TSMYK
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部