函数参数值传递

来源:互联网 发布:天拓游戏 知乎 编辑:程序博客网 时间:2024/05/14 18:56
以C(C++)为例,函数参数传递一般来说有三种方式:值传递,指针传递,引用传递。其中引用传递属于C++对C函数参数传递方式的扩展。 实际上C语言的所有参数都以“传值调用”方式进行传递,这意味着函数获得的是参数值的一份拷贝,函数可以放心的修改这个拷贝值,而不会影响实参。---《C和指针》

值传递:值传递是传递一个实参的拷贝副本,因此在函数内部对参数的操作,相当于对该实参拷贝副本的操作,对实参本身没有任何的影响。代码示例如下:

#include <stdio.h>void swap2Element(int , int);void main(){    int k = 10;    int j = 20;    swap2Element(k,j);    printf("k = %d\n",k);    return;}void swap2Element(int a, int b){    int tmp;    tmp = a;     a  = b;     b  = tmp;}

上例中函数swap2Element(int a, int b) ,本意是实现两个函数参数值的交换。但是由于函数参数a跟b是所传递实参k和j的拷贝副本,也就是说a和b相当于在内存中又重新开辟了两块内存,这两块内存存储的值是k和j的拷贝。在函数内部对新开辟内存直接进行操作,与原实参无关。 
指针传递:

为了在函数内部对实参的值进行修改,此时我们可以采用指针传递,把实参的地址或者某指向要修改内容的指针作为函数参数,传递给函数。如下例:

#include <stdio.h>void swap2Element(int *, int *);void main(){    int k = 10;    int j = 20;    swap2Element(&k, &j);    printf("k = %d\nj = %d\n",k,j);    return;}void swap2Element(int *a, int *b){    int tmp;    tmp = *a;     *a = *b;     *b = tmp;}

成功交换两者的值。

引用传递:

引用传递其实很多地方类似于指针传递,引用是原实参的另一个名字,比如一个人在家叫:阿狗,他在学校叫:张三,虽然名字不一样,但是代表了同一个人。因此引用是同一个东西的不同叫法,你对其中一个更改了,另一个也要跟着变(相当于指针,指向同一块内存)。

int a = 10;//!< b为引用类型,&为申明符号,不是取地址。引用类型声明的同时需要定义。const int &b = a;  b = 20; // error,b is const typea = 20; //rightprintf("b =%d\n",b);  //!< b = 20

引用传递一定意义上没有指针传递灵活,还是有它的适用情况。当我们要给函数传递参数时,有这样的一个不成文的约定,对于在函数内部要修改的函数参数,建议使用指针传递;对于在函数内部无需修改的函数参数,且函数参数是一个很大的类或一个大的结构体,建议使用引用传递,这样可以不用对实参复制拷贝,减小开销,为了防止该参数在函数内部被改变,可以加上const声明。 
如: beifa(const int &a) 
则在函数beifa()内部不能修改a的值。

综上所述,心细的我们可以发现,即使我们声称,函数参数传递有三种不同的方式,分别为:值传递,指针传递,引用传递。且这三种不同的方式各有优缺点和不同的适用情况。但从一个更高的角度考虑,其实函数参数传递只存在值传递一种方式,对于所有的函数参数,我们在函数内部对函数参数的直接修改都是无效的。 
什么叫对函数参数的直接修改呢?

实参传递:swap2Element(int a,int b) 
我们在函数内部对 a 和 b的修改都是无效的;

指针传递: swap2element(int *a, int *b) 
为什么我们可以修改a 和 b的值呢,因为指针传递的是a和b的地址,地址才是真正的函数参数,a和b是对地址的取值,我们是可以修改地址的取值,却无法修改a和b的地址,对地址的修改是无效的。 
谨记08年汶川地震,愿越来越好。 
2015/5/12 
by LB


1 0
原创粉丝点击