zoukankan      html  css  js  c++  java
  • 4、对变量在栈上存储顺序,及函数返回值与参数在栈上存放顺序的思考(2)

     2)接下来,我们将讨论第二个问题,那就是函数返回值与参数在栈上存放顺序。

    我们设计如下程序:

    #include "iostream"

    using namespace std;

    int test(int a, int b){

    int c;

    printf("%p\n",&b); //最后一个参数

    printf("%p\n",&a); //第一个参数

    printf("%p\n",&c); //函数的返回值地址

    return c;

    }

    int main()

    {

    int a = 1;

    int b = 2;

    int (*f)(int, int);

    f = test;

    int t = f(a, b);

    cout << &a <<endl

         << &b <<endl;

    printf("%p\n",test);

    }

    GCC上结果如下所示:

    VS下执行结果如下所示:

        由上可以,确实最后一个参数是先入栈的。至于c的地址就是函数的返回地址,我是参考文章[1],网友jixingzhong如此说。我们在汇编语言中学过,函数的返回地址是将要执行的下一条指令的地址;这里的意思是,把调用函数的指令的下一条指令入栈,以便调用完函数后返回,而我觉得参考文章中jixingzhong理解错这句了,所以我认为是错的。

    在本程序中,test函数的返回地址应当是

    int t = f(a, b);

    cout << &a <<endl

    的汇编指令后,在执行完函数后下一条将要执行的指令的地址。

    网友Arthur_认为,通过如下程序可以求得这个地址:

    #include "iostream"

    using namespace std;

    int* test(int a, int b){

    int c;

    printf("%p\n",&b); //最后一个参数

    printf("%p\n",&a); //第一个参数

    printf("%p\n",&c); //函数的返回值地址

    return ((int*)&b-1);

    }

    int main()

    {

    int a = 1;

    int b = 2;

    int* (*f)(int, int);

    f = test;

    int *t = f(a, b);

    cout << &a <<endl

         << &b <<endl;

    printf("%p\n",t);

    }

        而很明显的,这个结果是a的地址。所以,我认为,网友Arthur的想法也是不正确的(欢迎争鸣)。而正确的结论就当是本文中,我用红色标明的地方。

        当然,我希望了解这方面知识的高手们一起来讨论一下这个问题。

    参考:

    [1] http://topic.csdn.net/t/20060901/14/4991970.html

  • 相关阅读:
    开发新手最容易犯的50个 Ruby on Rails 错误(1)
    Spring Data Redis 让 NoSQL 快如闪电(2)
    为什么每个程序员都应该懂点前端知识?
    如何在 Flickr 上找到又酷,又有趣,且版权自由的照片?
    微服务扩展新途径:Messaging
    为什么现代企业无法真正实现组合式监控?
    开发者和程序员需要关注的42个播客
    战略性情绪分析的5大数据来源
    Spring Data Redis 让 NoSQL 快如闪电 (1)
    对抗告警疲劳的8种方法
  • 原文地址:https://www.cnblogs.com/mydomain/p/1791561.html
Copyright © 2011-2022 走看看