值传递和地址传递的根本区别在哪,形参和实参的值各是怎样变化

 我来答
CodeBlove
推荐于2016-09-28 · TA获得超过3363个赞
知道小有建树答主
回答量:936
采纳率:79%
帮助的人:235万
展开全部
首先,参数一般是通过压栈和弹栈来传递(根据不同约定采用不同传递方式,有的采用寄存器传递,调用约定有__stdcall,__cdecl,__fastcall,__thiscall,__nakedcall,__pascal,详情查询百度),常用约定为__stdcall,即调用前按参数的顺序从右到左压栈,然后执行调用,调用执行时退栈获得数据。

无论是值还是指针,都是取得数据后压栈,区别在于数据类型,编译器知道哪种类型的数据如何在函数中正确使用,除非源代码有错误,那预编译时会报错。

压栈时,其实就是将外部程序中的值复制一份写入栈空间。从源代码角度看,就变为形参,外部程序中用于参数传递的变量叫实参。

比如
int a=10;
int b;
int *p =&b;

函数
fun(int a1,int *p1);

调用
fun(a,p);
当调用fun时,
先取得p的值,由于p已赋值为a的地址,因此将p的值也就是a的地址压栈。
然后取得a的值,也就是整数10,压栈。
在执行汇编指令CALL时,通过弹栈取出数据,顺序是先取出a的值,再取出p的值(先进后出);此时a的值对应的名称叫a1,p的值对应的名称叫p1,在汇编层实际上是确定了参数地址,以便函数内代码可访问。

确定(取得)数据后,进入函数体,由于函数已定义,编译器知道a1是整数,p1是地址。只要源代码不错,会根据不同类型决定不同的操作方式,虽然看起来他们都是一个4字节的数据。

如果函数内的代码如下
*p1=a1;
编译器会安排如下操作(参数地址已确定):
取得参数a1的值
取得参数p1的值
将a1的值写入p1的值所指向的内存空间(p1的值是个地址)。

所以,无论是值变量还是指针变量,传递的都是副本,函数内改变形参值本身都不会影响实参的值。问题在于指针变量传递后,操作时是间接访问,所以会影响实参。
追问
抱歉这么晚回复,值传递将实参的值复制一份副本,对副本操作,保留最后的值,值传递直接传递实参的地址,保留结果,是这样吗?
追答
可能你说的保留是指数据的生存期。值传递是将实参的值复制一个副本给函数,指针传递是将实参的地址复制一个副本,副本生存期就是整个函数,函数处理结束,函数内数据会丢弃的(弹栈释放)。值传递和指针传递区别就是取值区别,一个是取变量值,一个是取变量地址,就这区别,当然,函数内对两种不同类型的数据操作方式也不同,但这不属于数据传递范畴的概念了。
IveArthur
2014-08-24 · TA获得超过256个赞
知道小有建树答主
回答量:467
采纳率:0%
帮助的人:190万
展开全部
值传递就是复制,地址传递就是把本体交出去
追问
说清楚点吧
追答
值传递是复制,形参得到实参的值,形参改变,实参并不改变,也就是生成了另一个对象。
地址传递就是形参变成了实参的一个引用,形参改变,实参也改变
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式