研究C语言的参数执行顺序

2008年8月23日 1:49 . 分类 编程相关 . 被踩 538 次 .

文章作者:Slyar 文章来源:Slyar Home (www.slyar.com) 转载请注明,谢谢合作。

今天看以前做过的题,发现一段代码,引起了我的研究兴趣。。。

#include <stdio.h>
main()
{
int i=9;
printf("%d %d %d\n",++i,i,--i);
printf("%d %d %d\n",i++,i,i--);
}

这段程序的结果是什么?

可能光给上面那个还真容易迷糊,不过两个都给那就简单了,结果是:

9 8 8
8 8 9

因为书上写着:printf的参数是右集合,也就是从右往左运行,可是为什么呢?

研究了一下,发现关键就在一个字:

计算机当然没有我们聪明了,更没有Slyar聪明了,所以他肯定不会知道看书要从左往右看。当然了,你可以说计算机还停留在古代,因为古人都是从右往左看书滴。。。嘎嘎,就因为这样,所以计算机不知道怎么来传递这个参数,这时就要引入一种数据结构来传递参数了,这个数据结构就是----栈!

关于栈,我们很清楚了,规则是后进先出。。。所以当函数被调用时,参数被压栈,然后调用函数在堆栈中进行计算。。。当我们输出参数的时候是从左向右(--->)输出的,输出时先从栈顶取数据,那么栈顶的数据一定是最后放进去的,这也就是为什么参数要从右向左(<---)压栈并求值的原因。。。

唔,当然也不是所有的参数都这样啦,有的参数是靠寄存器存取的。。。不管那么多了~

您可能还对以下内容感兴趣

收藏、分享这篇文章! 用 RSS feed 订阅本博客 什么是订阅? Trackback

评论

9 条评论 关于 “研究C语言的参数执行顺序”

  1. sfox 发表于 2008年8月23日 22:32

    我学了半年的C语言都没去研究过这东西。。

    其实不同的编译器对这个前后缀加的递增运算会有不同结果的吧?

    Slyar 回复 于 08月 23rd, 2008 22:45:

    不会,这个是C语言本身的规则,栈而已。不管什么编译器也得这么来。

  2. Tony 发表于 2008年8月24日 18:28

    9 9 9
    8 9 9

    Press ENTER to continue.

    Slyar 回复 于 08月 24th, 2008 20:46:

    呵呵,怎么也不会是这个结果的,9 9 9.......

  3. Tony 发表于 2008年8月24日 21:40

    hnxgf@hnxgf-compter:~$ cd /home/hnxgf/桌面/c语言/
    hnxgf@hnxgf-compter:~/桌面/c语言$ gcc -Wall a.c -o a
    a.c: 在函数‘main’中:
    a.c:5: 警告: ‘i’上的运算结果可能是未定义的
    a.c:5: 警告: ‘i’上的运算结果可能是未定义的
    a.c:6: 警告: ‘i’上的运算结果可能是未定义的
    a.c:6: 警告: ‘i’上的运算结果可能是未定义的
    a.c:7: 警告: 在有返回值的函数中,程序流程到达函数尾
    hnxgf@hnxgf-compter:~/桌面/c语言$ ./a
    9 9 9
    8 9 9
    hnxgf@hnxgf-compter:~/桌面/c语言$

    我是想说这个和编译器有关.........编译器会优化..

    #include
    #include
    int bar()
    {
    return 20;
    }
    int main()
    {
    int len = 3;
    printf("%d, %d\n", len=bar(), len);
    return 0;
    }
    测试结果:
    gcc 3.4.3, gcc 3.4.4 输出结果为: 20, 20
    gcc 3.2.2 及以下输出结果为: 20, 3
    VC++ 6.0 输出结果为: 20, 3

    该程序在 windows, linux, cygwin (x86, arm, mips) 上均得到同上的结果.

    不是因为入栈顺序变了,而是编译器优化的结果。
    C语言的参数入栈顺序雷打不动。

    Slyar 回复 于 08月 24th, 2008 21:51:

    呃。。。我还真没试过,我一般都不开编译器优化。。。

    我只是知道用寄存器处理的话结果会不一样~

    有时间看一下~~

  4. Felix021 发表于 2008年8月30日 00:54

    只要编译器肯做,什么花样都出得来

    比如这一句执行完i是多少?
    i++=(i++)+(i++)+i+(++i);
    写编译器的人自己都不一定能在不测的情况下说出自己编译器的结果。

    所以最好的办法就是不要滥用运算符。。。

    Slyar 回复 于 08月 30th, 2008 01:04:

    不要开优化,一半都会按逻辑来吧。写这个就是研究了一下参数执行顺序了,哈哈~

  5. zonghua 发表于 2008年8月30日 15:56

    C语言博大精深

发表您的评论[审核后显示]




关闭
E-mail It