人较笨且记性不好,故记录在此.折叠代码打不开请F5.本博中很多是转载收录其他网友的文章(原文地址请见博文末尾),所有权为原作者所有!!!
此博客已不再更新和维护,欢迎关注我的github新博客

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

相关概念:

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

 

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

总结:传引用=传指针

 参考资料:

http://www.cnblogs.com/Jamedy/archive/2007/03/25/687150.html

http://myturn.blog.hexun.com/15584978_d.html

http://lovemelovemydogs.blog.163.com/blog/static/9778560200721012092/

 

以上内容摘自:http://www.cnblogs.com/skyseraph/archive/2010/10/25/1860032.html   感谢作者!

 下面我补充图解:

图解:

传值调用:

 

 

传址调用:

引用调用:

 

posted on 2011-01-06 14:49  子坞  阅读(995)  评论(0编辑  收藏  举报