深入剖析C/C++函数的参数传递机制
深入剖析C/C++函数的参数传递机制
void Func3(int &x) //这个函数的参数使用引用传递方式 { x = x + 10; } 以下代码调用这些函数: int n = 0; Func1(n); acutPrintf(“n = %d”, n); // n = 0 Func2(&n); acutPrintf(“n = %d”, n); //n = 10 Func3(n); acutPrintf(“n = %d”, n); //n = 20 以上代码段中,当程序调用Func1()函数时,首先在栈(Stack)内分配一块内存用于复制变量n。若变量n的类型复杂,甚至重载了该类的默认拷贝构造函数: CMyClass(const CMyClass &obj); 这个过程可能会比较复杂。<类的默认拷贝构造函数使用“位拷贝”而非“值拷贝”,若类中包括指针成员,不重载该函数几乎注定程序会出错。关于这个问题以后再深入探讨。> 程序进入函数Func1()体内后,操作的是栈中的临时变量,当函数结束(或者说返回)时,栈内变量被释放。而对于函数Func1()来说的外部变量n并未起任何变化,因此随后的acutPrintf函数将输出n = 0。 程序调用函数Func2()时,在栈内分配内存用于存放临时的指针变量x。然后用&运算取得变量n的地址,并拷贝给临时指针变量x作为x的值。此时,指针x就成了指向变量n的指针。在函数体内,*x运算得到的是指针x指向的内容,即变量n。对*x操作实际上就是对n操作。因此,在函数Func2()中变量n的值起了变化。在分析Func2()函数时应该注意到,临时指针变量x要指向的内存地址,也就是说变量x的“值”仍然是采用了值传递方式从函数外部(或者说函数调用者)获得,那么“值”也就应该具有值传递方式的特点,它要在栈中复制临时变量,它在函数体内被修改不会影响到函数外部。比如说,在上面的代码段中,函数Func2()内可以让指针x指向另外的变量,但函数结束或返回后,在函数外部是无法得到这样的指向另外变量的指针。 程序调用函数Func3()时,临时变量x是一个变量n的引用,此时变量x就是变量n本身,对x操作的同时,外部变量n也起了变化。实际上,引用能做的事,指针也能做到。 以上的代码段确实简单,以至还不能充分显示指针和引用在传递函数参数时的许多其他功能。下面我们设计这样一个函数,函数需要两个参数,在函数内将两个参数的值互换。由于值传递方式尽管能通过返回值赋值的方法修改一个参数值,但不能同时修改两个参数值,因此这个函数不能使用值传递方式。使用指针传递方式,函数可以写成这样: bool swap(int *x, int *y) { int temp; temp = *x; *x = *y; *y = temp; return true; } 以下代码调用该函数: int *a = 10; int *b = 15; if (swap(a, b)) { acutPrintf(“整数a,b已交换数据,a = %d, b = %d”, a, b); } 在以上代码中,swap()函数设计成与常见的ARX函数一致的风格,用一个bool类型返回函数执行状态。<在ARX中,这个返回值通常使用Acad::ErrorStatus类。>在调用函数时,由于变量a和b已经声明为指针,使用标识符a和b访问的是int类型变量的内存地址。 使用引用传递参数,可以这样设计swap()函数: bool swap(int &x, int &y) { int temp; temp = x; x = y; y = temp; return true; } 使用代码swap(int a, int b)调用以上函数时,进入函数体内,x、y分别是变量a、b的引用,对x、y操作就是操作变量a、b。函数返回后,变量a、b的值互相交换了。 注意:以上代码只是交换两个变量(或者指针指向的变量)的值。即将变量a、b(或指针a、b指向的变量)的修改为b、a(或指针b、a指向的变量)的值,而不是将指针a指向原来指针b指向的变量。也就是说,swap()函数调用前后,指针a和b的值(地址)并没有发生任何变化。(当然,引用关系在任何时候都不能修改。)要修改指针的地址值,应该使用指向指针的指针或者使用对指针的引用。这样设计和调用函数: bool swap(int **x, int **y); //使用指向指针的指针传递参数 int *a = 10; int *b = 15; swap(&a, &b); 或者: bool swap(int *&x, int *&y); //使用对指针的引用传递参数 int *a = 10; int *b = 15; swap(a,b); 在以上的两个swap()函数以交换两个指针的值,使指针a指向原来指针b指向的变量,指针b指向原来指针a指向的变量。 另外,由于引用关系不可修改,指向引用的指针和引用一个引用没有实际意义。若编译器允许它们存在,实际上也会退化为普通指针(或对指针的引用)和引用。这一点请读者自行分析。 最后,我们看一个ARX程序中使用指针和引用传递参数的函数例子: AcDbDatabase *pDb = new AcDbDatabase(); AcDbBlockTable *pBlkTbl; pDb->getBlockTable(pBlkTbl, AcDb::kForRead); 从ARX帮助中可以查看到,getBlockTable()函数的原型是: Acad::ErrorStatus getBlockTable( AcDbBlockTable*& pTable, AcDb::OpenMode mode); 其中可以看到,函数的第一个参数是对一个AcDbBlockTable类型指针的引用,从而可以在函数体内部对指针pBlkTbl进行修改,使之指向pDb指针指向的图形数据库的块表。
深入剖析C/C++函数的参数传递机制的更多相关文章
- C++函数的参数传递机制以及参数的类型选择
C++primer之函数的参数传递以及参数的类型 一:函数的基本知识 (1) 函数要素:返回类型,函数名字,形参(参数之间用逗号隔开) (2) 函数调用机制:我们通过调用运算符来执 ...
- Python 函数参数传递机制.
learning python,5e中讲到.Python的函数参数传递机制是对象引用. Arguments are passed by assignment (object reference). I ...
- 深入浅出ghostbuster剖析NodeJS与PhantomJS的通讯机制
深入浅出ghostbuster剖析NodeJS与PhantomJS的通讯机制 蔡建良 2013-11-14 一. 让我们开始吧 通过命令行来执行 1) 进行命令窗口: cmd 2) 进入resourc ...
- <MFC_1>深入剖析MFC的WinMain和消息机制
一.开篇引论 熟悉Win32开发的朋友,应该非常了解它的基本组成和流程 1. WinMain:书写窗口类(WNDCLASS) -> 注册窗口类 -> 创建窗口 -> 显示窗口和更新窗 ...
- python中的*和**参数传递机制
python的参数传递机制具有值传递(int.float等值数据类型)和引用传递(以字典.列表等非值对象数据类型为代表)两种基本机制以及方便的关键字传递特性(直接使用函数的形参名指定实参的传递目标,如 ...
- 我的Java开发学习之旅------>Java语言中方法的参数传递机制
实参:如果声明方法时包含来了形参声明,则调用方法时必须给这些形参指定参数值,调用方法时传给形参的参数值也被称为实参. Java的实参值是如何传入方法?这是由Java方法的参数传递机制来控制的,Java ...
- 深入理解Java中方法的参数传递机制
形参和实参 我们知道,在Java中定义方法时,是可以定义参数的,比如: public static void main(String[] args){ } 这里的args就是一个字符串数组类型的参数. ...
- C++中的虚函数(表)实现机制以及用C语言对其进行的模拟实现
tfref 前言 C++对象的内存布局 只有数据成员的对象 没有虚函数的对象 拥有仅一个虚函数的对象 拥有多个虚函数的对象 单继承且本身不存在虚函数的继承类的内存布局 本身不存在虚函数(不严谨)但存在 ...
- C语言中如何将二维数组作为函数的参数传递
今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...
随机推荐
- python之socket编程
本章内容 1.socket 2.IO多路复用 3.socketserver Socket socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用[打开][读写][ ...
- IOS动画总结
IOS动画总结 一.基本方式:使用UIView类的UIViewAnimation扩展 + (void)beginAnimations:(NSString *)animationID context ...
- 『电脑技巧』浅谈Win7的文件共享设置
随着移动存储设备的普及,很少有小伙伴喜欢使用局域网“文件共享”这一捷径了 而且自从XP之后,Windows系列主机共享设置貌似比较麻烦 虽然事实并不是看上去那样(Win7也很Easy的说 = =) 现 ...
- 转:40多个关于人脸检测/识别的API、库和软件
文章来自于:http://blog.jobbole.com/45936/ 自从谷歌眼镜被推出以来,围绕人脸识别,出现了很多争议.我们相信,不管是不是通过智能眼镜,人脸识别将在人与人交往甚至人与物交互中 ...
- angularjs 1.3 综合学习 (one way bind , ng-if , ng-switch , ng-messages, ng-form ,ng-model )
主要讲解1.3后的一些新功能,和一些以前没有介绍的小功能 (ng-if,ng-switch). 1.one way bind 这个之前的版本已经有人自己实现了,但是在1.3之后,angularjs 有 ...
- 通过Shell和Redis来实现集群业务中日志的实时收集分析
http://www.linuxidc.com/Linux/2013-05/83935.htm
- Matrix控制平移、旋转和缩放的方法
1.setTranslate(float ds,float dy):控制Matrix进行平移.2.setSkew(float kx,float ky,float px,float py):控制Matr ...
- 用javascript向一个网页连接接口发送请求,并接收该接口返回的json串
一般前端与后端的互交都是通过json字符串来互交的,我的理解就是与网页接口的来回数据传递采用的数据结构就是json.一般是这样. 比如后端的代码是这样的: @RequestMapping(value ...
- 点击类名方法名如何连接到相应的Android源代码
. 找到Android SDK所在路径 “D:\androidDev\android-sdk-windows\” . 在该目录下选择platforms到 “D:\androidDev\android- ...
- POJ 2135 Farm Tour
题目大意:有一个无向图..农夫从1号点出发..要到达N号点..然后回到1号点..来回不能走相同的路径..问最短的距离是多少. 题解:又是不能走重复路径!基本图论算法直接扔掉上网络流.不能相同就边限1, ...