函数的参数传递

一、函数参数传递机制的基本理论:

函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题。基本的参数传递机制有两种:值传递引用传递。以下讨论称调用其他函数的函数为主调函数,被调用的函数为被调函数。

值传递(passl-by-value)过程中,被调函数的形式参数作为被调函数的局部变量处理,即在堆栈中开辟了内存空间以存放由主调函数放进来的实 参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值(除非传递地址值)。

引 用传递(pass-by-reference)过程中,被调函数的形式参数虽然也作为局部变量在堆栈中开辟了内存空间,但是这是存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过堆栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

二、C语言中函数参数传递机制

在C语言中,值传递是唯一可用的参数传递机制。但受指针变量作为函数参数的影响,容易误认为这种情况是引用传递,这是错误的。使用“变量”作为函数参数进行传递,当调用函数时,其实本质是内存另外开辟一个空间,将传人的实参拷贝一份给形参,即函数中处理的实际上是实参的一个副本(形参),所以无论函数怎么处理,实参的值是不会发生任何的改变的。

使用“指针”作为参数传递的情况,实际上和使用“变量”作为参数传递的情况是一样的。只不过这里的变量是一个指针变量,传的值是地址值。所以本质上还是传值的方式。当我们将实参变量的地址,传递给函数的形参指针时,实际上是将实参的地址值赋给形参指针变量,然后后续的处理,都是根据这个地址值进行索引找到实参的实际值进行处理,所以函数处理的实际的实参的值,只不过是通过形参指针变量指向的。

int swap(int *x, int *y)
{
int temp;
temp = *x; *x = *y; *y = temp;
return temp;
}
void main()
{
int a = 1, b = 2;int *p1 = &a;int *p2 = &b;
swap(p1, p2)
}

函数swap以两个指针变量作为参数,当main()调用swap时,是以值传递的方式将指针变量p1、p2的值(也就是变量a、b的地址)放在了swap在堆栈中为形式参数x、y开辟的内存单元中。要点总结:

1)进程的堆栈存储区是主调函数和被调函数进行通信的主要区域。

2)C语言中参数是从右向左进栈的。
3)被调函数使用的堆栈区域结构为:
 
局部变量(如temp),返回地址,函数参数,低地址 ,高地址
4)由主调函数在调用后清理堆栈。
5)函数的返回值一般是放在寄存器中的。

三、C++语言中函数参数传递机制

C++既有C的值传递又有引用传递。在值传递上与C一致,这里着重说明引用传递。如本文前面所述,引用传递就是传递变量的地址到被调函数使用的堆栈中在C++中声明引用传递要使用"&"符号,而调用时则不用。下面的代码是使用引用传递的swap2函数和main函数:

int& swap2(int& x, int& y) 

{

int temp;

temp = x; x = y; y = temp;

return x;

}

void main()

{

int a = 1, b = 2;

swap2(a, b);

}

此时函数swap2将接受两个整型变量的地址,同时返回其中的一个。而从main函数中对swap2的调用swap2(a, b)则看不出是否使用引用传递,是否使用引用传递,是由swap2函数的定义决定的。

这里的swap2和前面的swap来讲,堆栈中的函数参数存放的都是地址,在函数中操作的方式是一致的。但是,对swap2来说这个地址是主调函数通过将实参变量的偏移地址压栈而传递进来的--这是引用传递;而对swap来说,这个地址是主调函数通过将实参变量的值压栈而传递进来的--这是值传递,只不过由于这个实参变量是指针变量所以其值是地址而已
这里的关键点在于,同样是地址,一个是引用传递中的变量地址,一个是值传递中的指针变量的值。虽然x是一个局部变量,但是由于其值是主调函数中的实参变量的地址,故在swap2中返回这个地址是合法的。

c++ 中经常使用的是常量引用,如将swap2改为:
     Swap2(const int& x; const int& y)
  这时将不能在函数中修改引用地址所指向的内容,具体来说,x和y将不能出现在"="的左边。

四、总结

      1. 传值和传常量引用实参是不会被形参改变的。而如果函数体要改变实参的值,必须是传指针或非常量引用

      2.一般c++可以使用值传递和引用传递,后者更多。因为这样不用另外在堆栈中开辟空间,而值传递就需要另外的开辟空间,对内存有一定的浪费。一般c中只使用值传递。

    3.另外关于存储数据方面,一般是将局部变量,函数返回地址,函数参数放到堆栈中,而函数返回值一般放到寄存器中,为的是方便中断,如果有临时中断就可以直接从寄存器中处理,不用再进行压栈出栈操作。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值