用交换的程序来理解函数传递
来源:互联网 发布:金蝶软件报价 编辑:程序博客网 时间:2024/05/27 20:16
C或C++中函数的参数传递包括:值传递、指针传递、引用传递这三种方法,这三种方法在《程序员面试宝典》中说的很明了,这里加上我自己的理解。
先看源代码,编译环境是vc6.0,因为调试方便。功能是要实现a和b值的交换。
共有四个函数,其中有两个是指针传递,但函数体内的实现不一样。下面具体分析
1.值传递
swap1函数实现的值传递,值传递传递的是实际参数的一个副本,如果对这句话不理解,那一步步调试看下内存分配情况。
执行到48行时,a和b的情况如下
接着进入swap1函数体内,如下所示
可以看到的是,p和q的地址和a与b的地址不一样,只是把a和b的值拷贝过去了,在swap1中对p和q操作只是对临时分配的栈中内容进行操作,函数执行完后形参就消失了,对原来的a和b不产生任何影响。所以swap1不能完成交换a和b值的功能
2.指针传递
swap2和swap3都是指针传递,swap2函数体内交换了p和q指向地址的值,swap3函数体内交换了p和q指向的地址。
先说swap2,进入swap2函数体内,如下所示
可以看到,形参指针p和q指向的是a和b的地址,而不是像值传递那样将实参的值拷贝到另外分配的地址中,运行到函数尾时,如下图
可以看到、指针p和q指向的地址没变,但地址中的值变了,也即a和b地址中的变了,就是a和b的值成功交换,继续调试可以看到正确的结果,如下图
再来看swap3,swap3运行到函数尾时的情况如下
可以看到p和q交换了地址,但最后函数执行完后的结果又如下所示
a和b的值并未交换,这是为什么呢?
swap3中,形参p和q会保存在栈中,p指向a的地址,q指向b的地址,使用temp指针完成了p和q的地址交换,即p指向b的地址,q指向了a的地址,但a和b地址中的值并未发生变化,这与swap2不同,swap2中是p指向的地址中的值(就是a)与q指向的地址中的值(b)交换,所以swap2执行完后a和b的值是交换了的。
3.引用传递
引用传递时,对形参的操作等同于对实参的操作,即传递的不会是实参的副本,而就是实参,进入swap4函数体内如下所示
看到这个内存分配,很明了了吧。最后会交换a和b的值。
到此,完了。当然函数参数也可以是指向指针的指针,这也是很常见的,但通常用在需要动态分配内存的地方以避免内存泄露。在使用cuda时调用cudaMalloc其参数就是这样,指向指针的指针。而malloc、CPLMolloc、new这些是通过返回值传递分配的动态内存的,自然是不会出现内存泄露的,这个后面再说。
- 用交换的程序来理解函数传递
- 用交换函数来理解指针
- 函数参数传递的理解!
- <深入理解计算机系统> 通过程序的机器级表示来理解函数栈
- 【c++程序】通过指针来交换两个数的值
- 【c++程序】通过别名来交换两个数的值
- 写一个交换函数,在主程序中调用该函数,来实现实参值的交换。
- 对函数中指针传递的理解
- 关于构造函数传递参数的理解
- JAVA中函数调用参数传递的理解(值传递和引用传递的理解)
- 分组交换 的理解
- 用GCC来跟踪程序的函数调用关系
- 用GCC来跟踪程序的函数调用关系
- C/C++ 用函数返回值来传递动态申请的内存
- 使用函数传递参数来执行相应的数据库操作
- 将应用程序的函数指针传递给驱动程序来调用
- Java:理解Java中函数参数传递的【按值传递】和【按引用传递】
- 交换函数的两种不同的实现方式------地址传递和引用参数
- 搭建高可用mongodb集群(三)—— 深入副本集内部机制
- nginx 的多个参数解析
- 10大最适合编程的字体推荐下载,让代码看起来更美更舒服(转载)
- Hive总结
- mvn package 打包常见错误及解决方案
- 用交换的程序来理解函数传递
- 搭建高可用mongodb集群(四)—— 分片
- 第九周项目四——我的小九九
- C# - as
- Mybatis分页插件更新
- 大学
- curl用法总结
- 基于有限状态机的交互组件设计与实现
- Android 自定义指示器<NBIndicatorView>