c语言函数参数传递的是值还是拷贝

今日在看c语言return的相关章节时,不明白return返回的是值还是值的考博,同时对函数形参传递的是值还是拷贝也不解?比如int *p(int *pA);这个函数声明,当主函数调用该函数时,传递给形参pA的实参是一个指针还是该指针的拷贝呢?同理返回的函数P内部的指针还是那个待返回指针的拷贝呢??求帮助

一 参数
1 所有的参数传递,都是传递值的拷贝。(如果想知道为什么,去学习编译原理的函数调用的参数压栈和出栈对应内容)。
2 C传指针进去,其实也是把这个指针值按拷贝传送进去。但是因为指针值指向一块外部内存空间(其实更多是堆空间,或外层栈变量空间),所以感觉可以在函数里改变外部变量。其实本质还是按拷贝传递,只是传递进去的是一个访问变量的渠道。
因此,如果我们希望函数内能改变外部的指针值,往往传进去的是指针变量的指针。呵呵,很多初学C的程序员,对**非常难理解。

二 返回值
返回值是按拷贝传递,函数出栈后,会传出一个值,该值在调用函数的代码段的生命周期里一直有效。相当与调用点形成一个匿名的栈变量。

变量a = function(); 而a并不等于函数里return的那个值。
其实function()执行结果自身就是一个匿名变量。(其实编译器会检查语法,如上面a=function这样的语法,匿名变量不会生成,直接使用a变量拷贝返回值)
例如: function()返回int值。 完全可以 int x = function() + 6;//注意:+运算时,函数已经执行完毕,所有函数出栈操作已经结束。
很明显function()必须有一个变量或常量参与计算,而函数里return的值会随函数调用结束出栈而被删除,所以必须拷贝构造传递出来。追问

大虾,你好!你说的参数传递我看懂了。但是你说的返回值的这块不是很懂!比如说:int *p();{statements; return pA}这个函数,函数返回pA指针,但是它返回的到底是pA还是pA的一个副本或是其他的东西呢?

追答

传回的是int指针的拷贝。Pa的一个拷贝副本。

pa和返回值都是指向的内存空间是在堆空间里,换句话说,指向函数空间外独立的空间。
所以感觉把值传递出来了。

但这个感觉是错误的。
传递出来的是这块int指针的拷贝。本质上还是按拷贝传递。

本质上和参数传递进去变量指针是一个道理。

我可以给你举个例子:
1 变量:
int function(){
int a;
return a;
}
int x =function(); 函数调用完毕,函数里的a就不存在了。那x是什么?当然只能拷贝。
function()+4; 函数调用完毕,函数里的a就不存在了。那什么在参与计算?当然只能拷贝。

2 指针
int* function(){
int* a;
return a;
} //道理如上,a都不存在了,外面使用的是什么?

追问

哦,明白了,也就是说无论是形参传递还是return返回值,都会产生一个临时变量用来拷贝实参或者返回值,是吗?另外,大虾,你的这句话没看明白:变量a = function(); 而a并不等于函数里return的那个值。function的返回值是赋给a的,赋值后a应该是等于function的返回值吧??

追答

是值等于,但不是同一个内存空间代表的变量。

就是说虽然值相等,但不是一个东西。

温馨提示:内容为网友见解,仅供参考
第1个回答  2012-09-25
在一个函数的内部,return的时候返回的都是一个拷贝,不管是变量、对象还是指针都是返回拷贝,但是这个拷贝是浅拷贝。
可以看看这篇文章:http://blog.csdn.net/vivi_wang_11/article/details/7438692
如果还有不懂的可到网上多对比看看相应资料

int *p(int *pA); 这里是以一个指针作为形参,并返回一个指向int型的指针
因此传递进去的是一个指针(即 地址),这个时候传递的不是参数的拷贝,经过这个函数处理后 可能会修改pA指向的数据,因此很多时候(尤其是字符串作为参数的时候)都会在形参之前添加const如下所示 int *p(const char *pA);这样可以防止pA所指向的数据不会被函数修改
第2个回答  2012-09-25
return是用来做函数返回值的(也就是说函数也是有其类型的),比如函数定义为int类型,则return返回的也是int型(不管你return后面跟的是什么类型,都要被强制转换为int型)。形参传递都是对实参值的拷贝,指针变量传递过去的是地址(也是拷贝哦,只不过是地址),然后在函数中通过地址直接操作地址中所保存的变量的值(相当于直接操作变量)来达到更改实参指针所指向的变量的值(有点拗,不懂可以联系我,慢慢讲解一下,指针是非常重要的哦)。接下来讲解一下int *p(int *pA);
首先你定义的是一个指针函数(即该函数返回值是一个指针,并且是一个指向int类型的指针,也可以研究一下函数指针的作用哦),然后该函数的参数也是一个指向Int类型的指针变量。调用该函数时,传递给pA的是指针(指针的意思就是地址,指针变量是用来存放该地址的变量),也是实参指针变量的值的拷贝(明白了吧?^_^);接下来是返回值,从定义只能看出,其返回值为指向int类型的指针,而这个指针指向什么地址,就要看你的具体return返回值语句了。
第3个回答  2012-09-25
如果return值的话,就将值拷贝到cpu寄存器中,函数形参传递值的话是拷贝实参的,但函数结束后就释放拷贝的数据,被拷贝的还存在。
int *p(int *pA);这个是在栈里开辟一块内存,该内存里拷贝了传递过来的地址,所以对该地址里的数据操作也就是对被传递的地址里的数据操作。
如果用在函数中用形参pA=new int[1]申请一块动态内存,但是实参却不是这块动态内存的首地址,原因是形参是拷贝的指针变量,申请新地址时,只是复制品的地址变了,如果没有delete的话还会造成内存泄露
第4个回答  推荐于2017-09-29

C语言中函数参数的传递有两种方式:传值与传地址。

传值就是将实参的值传递给形参,使得形参的值与实参一样。

传地址就是将实参所在内存单元的地址传递给形参,使得形参指向实参所在的内存地址。


举例说明如下:

#include<stdio.h>
int fun1(int a, int b);
{
    return a>b ? a : b;
}
int fun2(int *a, int *b);
{
    return *a>*b ? *a : *b;
}
void main()
{
    int x=5, y=3;
    int z1 = fun1(x, y);   // 传值调用方式
    int z2 = fun2(&x, &y); // 传地址调用方式
}

相似回答