C语言的函数参数

如有出入,本文按Linux GCC位实验标准

 

1. 参数压栈顺序, 这段为转载来自博客园

先通过一个小程序来看一看:

#include 

    void foo(int x, int y, int z) 

    { 

    printf("x = %d at [%X]n", x, &x); 

    printf("y = %d at [%X]n", y, &y); 

    printf("z = %d at [%X]n", z, &z); 

    } 

    int main(int argc, char *argv[]) 

    { 

    foo(100, 200, 300); 

    return 0; 

    }

运行结果:

x = 100 at [BFE28760]

y = 200 at [BFE28764]

z = 300 at [BFE28768]

C程序栈底为高地址,栈顶为低地址,因此上面的实例可以说明函数参数入栈顺序的确是从右至左的。可到底为什么呢?查了一直些文献得知,参数入栈顺序是和具体编译器实现相关的。比如,Pascal语言中参数就是从左到右入栈的,有些语言中还可以通过修饰符进行指定,如Visual C++.即然两种方式都可以,为什么C语言要选择从右至左呢?

进一步发现,Pascal语言不支持可变长参数,而C语言支持这种特色,正是这个原因使得C语言函数参数入栈顺序为从右至左。具体原因为:C方式参数入栈顺序(从右至左)的好处就是可以动态变化参数个数。通过栈堆分析可知,自左向右的入栈方式,最前面的参数被压在栈底。除非知道参数个数,否则是无法通过栈指针的相对位移求得最左边的参数。这样就变成了左边参数的个数不确定,正好和动态参数个数的方向相反。

因此,C语言函数参数采用自右向左的入栈顺序,主要原因是为了支持可变长参数形式。换句话说,如果不支持这个特色,C语言完全和Pascal一样,采用自左向右的参数入栈方式。

 

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值