【C++】C/C++中函数参数传递详解
2013-01-05 23:28
531 查看
对比两种传递方式:
按值传递变量,需要有复制实参内存以初始化形参,所以这将带来一些开销。在讨论简单变量时,内置的类型(如int、float)的开销可以忽略不计,但对于大型的对象(如代表整个3D世界的大对象)来说,复制的代价会很高昂。C语言也提供了一种指针式的“按值传递”,也可以解决传递大对象时代价过高的问题,然而“指针”由于安全问题一直为众多程序员所诟病。故而C++又提供了一个按引用传递。
按引用传递:按值传递无法修改实参的值,因为它形参永远是实参的副本;然而按引用传递可以修改实参的值。
某些情况下,我们需要修改实参的值,而某些情况下,我们不想修改实参的值。
在C语言中我们的解决方案:如果不想修改我们就直接传递实参,如果对象太大我们就传递指针,并且声明指针是指向const对象的;如果想修改实参的值,我们只能传递实参的指针,然而此时指针就不能用const修饰了。
在C++中,我们仍然可以使用C中的方式,然而也可以使用“引用”方式:如果不想修改实参的值,我们使用const引用(就是“常量引用”)方式,这样就不可以通过引用修改被引用对象的值;如果想修改实参的值,则使用平常性的引用实参就可以了(如上程序)。
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这些是通过返回值传递分配的动态内存的,自然是不会出现内存泄露的,这个后面再说。
按值传递变量,需要有复制实参内存以初始化形参,所以这将带来一些开销。在讨论简单变量时,内置的类型(如int、float)的开销可以忽略不计,但对于大型的对象(如代表整个3D世界的大对象)来说,复制的代价会很高昂。C语言也提供了一种指针式的“按值传递”,也可以解决传递大对象时代价过高的问题,然而“指针”由于安全问题一直为众多程序员所诟病。故而C++又提供了一个按引用传递。
按引用传递:按值传递无法修改实参的值,因为它形参永远是实参的副本;然而按引用传递可以修改实参的值。
某些情况下,我们需要修改实参的值,而某些情况下,我们不想修改实参的值。
在C语言中我们的解决方案:如果不想修改我们就直接传递实参,如果对象太大我们就传递指针,并且声明指针是指向const对象的;如果想修改实参的值,我们只能传递实参的指针,然而此时指针就不能用const修饰了。
在C++中,我们仍然可以使用C中的方式,然而也可以使用“引用”方式:如果不想修改实参的值,我们使用const引用(就是“常量引用”)方式,这样就不可以通过引用修改被引用对象的值;如果想修改实参的值,则使用平常性的引用实参就可以了(如上程序)。
C或C++中函数的参数传递包括:值传递、指针传递、引用传递这三种方法,这三种方法在《程序员面试宝典》中说的很明了,这里加上我自己的理解。
先看源代码,编译环境是vc6.0,因为调试方便。功能是要实现a和b值的交换。
1 // test.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 7 using namespace std; 8 9 //值传递 不能 10 void swap1(int p,int q) 11 { 12 int temp; 13 temp=p; 14 p=q; 15 q=temp; 16 } 17 18 //指针传递,函数体内只有指针值的变化 能 19 void swap2(int *p,int *q) 20 { 21 int temp; 22 temp=*p; 23 *p=*q; 24 *q=temp; 25 } 26 27 //指针传递,函数体内只有指针的变化 不能!!! 28 void swap3(int *p,int *q) 29 { 30 int *temp; 31 temp=p; 32 p=q; 33 q=temp; 34 } 35 36 //引用传递 能 37 void swap4(int &p,int &q) 38 { 39 int temp; 40 temp=p; 41 p=q; 42 q=temp; 43 } 44 45 int main() 46 { 47 int a=1,b=2; 48 swap1(a,b); 49 //swap2(&a,&b); 50 //swap3(&a,&b); 51 //swap4(a,b); 52 cout<<a<<" "<<b<<endl; 53 return 0; 54 }
共有四个函数,其中有两个是指针传递,但函数体内的实现不一样。下***体分析
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++中函数参数传递详解
- C/C++中函数参数传递详解
- C/C++中函数参数传递详解
- C/C++中函数参数传递详解
- C/C++中函数参数传递详解
- C/C++中函数参数传递详解
- C/C++中函数参数传递详解
- C/C++中函数参数传递详解
- C/C++中函数参数传递详解(二)
- C++中函数调用时的三种参数传递方式详解
- C/C++中函数参数传递详解
- C/C++中函数参数传递详解(一)
- C/C++函数参数传递机制详解及实例
- C/C++中函数参数传递详解
- C/C++中函数参数传递详解(从内存的分析)
- C/C++中函数参数传递详解
- C/C++中函数参数传递详解
- C/C++中函数参数传递详解
- C/C++中函数参数传递详解
- C/C++中函数参数传递详解