精华内容
下载资源
问答
  • C语言函数参数入栈顺序从右到bai左是为了方便可变参数du函数。 一、在函数调用时,函数参数的传递,在C语言中是通过栈数据结构实现的。 在调用函数时,先根据调用函数使用的参数,自右向左依次压入栈中,然后调用...

    C语言函数参数入栈顺序从右到左是为了方便可变参数函数。
    一、在函数调用时,函数参数的传递,在C语言中是通过栈数据结构实现的。
    在调用函数时,先根据调用函数使用的参数,自右向左依次压入栈中,然后调用函数,在函数开始执行时,将参数再依次弹栈。根据栈数据结构先进后出的特点,在函数中弹栈的顺序就是从左向右的。
    二、对于参数固定的函数,无论是从左向右还是从右向左,都没什么区别,最终都是所有参数全部传递。
    三、对于可变参数,比如printf,会在第一个参数格式字符串中,指明后续有几个参数,各自是什么类型的。于是在函数中,参数格式字符串必须第一个弹栈,否则无法获取参数类型,也就无法获知后续参数占几个字节,导致无法正确获知参数。
    四、理论上来说,如果从左向右压栈,可变参数标记格式字符串的参数放在最后,那么也是可以的。 不过最早设计C语言的人采用了这种方式,后续也就延续下来了。

     

    源链接:https://zhidao.baidu.com/question/628286190320666284.html

    展开全文
  • 对技术执着的人,比如说我,往往对一些问题,不仅想做到“知其然”,还想做到“知其所以然”。...某天某地某人问我,C语言函数参数入栈顺序如何?从右至左,我随口回答。为什么是从右至左呢?我终究没有给

    http://blog.csdn.net/liangkaiming/article/details/6230779

    对技术执着的人,比如说我,往往对一些问题,不仅想做到“知其然”,还想做到“知其所以然”。C语言可谓博大精深,即使我已经有多年的开发经验,可还是有许多问题不知其所以然。某天某地某人问我,C语言中函数参数的入栈顺序如何?从右至左,我随口回答。为什么是从右至左呢?我终究没有给出合理的解释。于是,只好做了个作业,于是有了这篇小博文。

    #include <stdio.h>

    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语言中可变参数都是从左到右,所以不管你有多少个参数反正将最右面的那个压入栈底,最左面的参数出入栈顶。换句话说,如果不支持这个特色,C语言完全和Pascal一样,采用自左向右的参数入栈方式。


    参考scanf(char *p, int x, ...)函数,最左边参数在栈顶,压完后就能知道其首地址,通过解析这个参数的内容,就可以解析出后面所有的参数;反过来的话,就无法获知最左边参数的首地址了。


    展开全文
  • 由该文章知道计算机中栈的生长方向为由高到低,及栈底为高地址,栈顶为低地址,因此函数输入参数入栈顺序可以由栈地址大小判断,地址大的先入栈,地址小的后入栈 #include void Var_Order(int x, int y, int z) ...

    四种方法判断栈的生长方向 Determine the Direction of Stack Growth  (点击打开)

    由该文章知道计算机中栈的生长方向为由高到低,及栈底为高地址,栈顶为低地址,因此函数输入参数入栈顺序可以由栈地址大小判断,地址大的先入栈,地址小的后入栈



    #include<cstdio>
    void Var_Order(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[])
    {
        Var_Order(2012, 2013, 2014);
        return 0;
    }
    /*************************
    运行结果:
    x = 2012 at [22FF10]
    y = 2013 at [22FF14]
    z = 2014 at [22FF18]
    **************************/
    

    因为参数2014的栈地址最大,可知第三个参数先入栈,并且由三个参数的栈地址可以得到函数参数的入栈顺序是从右到左


    C程序栈底为高地址,栈顶为低地址,因此上面的实例可以说明函数参数入栈顺序的确是从右至左的。参数入栈顺序是和具体编译器实现相关的。比如,Pascal语言中参数就是从左到右入栈的,有些语言中还可以通过修饰符进行指定,如Visual C++.即然两种方式都可以,为什么C语言要选择从右至左呢?
    进一步发现,Pascal语言不支持可变长参数,而C语言支持这种特色,正是这个原因使得C语言函数参数入栈顺序为从右至左。具体原因为:C方式参数入栈顺序(从右至左)的好处就是可以动态变化参数个数。通过栈堆分析可知,自左向右的入栈方式,最前面的参数被压在栈底。除非知道参数个数,否则是无法通过栈指针的相对位移求得最左边的参数。这样就变成了左边参数的个数不确定,正好和动态参数个数的方向相反。
    因此,C语言函数参数采用自右向左的入栈顺序,主要原因是为了支持可变长参数形式。换句话说,如果不支持这个特色,C语言完全和Pascal一样,采用自左向右的参数入栈方式。 


    四种方式判断栈的生长方向:

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    using std::cout;
    static void find_stack_direction(void);
    static int stack_dir;
    static void stack_growth_v1(void)
    {
        static char *addr = NULL; /* address of first`dummy', once known */
        auto char dummy; /* to get stack address */
    
        if (addr == NULL)
        { /* initial entry */
            addr = &dummy;
            stack_growth_v1 (); /* recurse once */
        }
        else if (&dummy > addr)/* second entry */
            stack_dir = 1; /* stack grew upward */
        else
            stack_dir = -1; /* stack grew downward */
    }
    void stack_growth_v2(char *function_parameter)
    {
        char local;
        if (&local > function_parameter)
            printf("up\n");
        else
            printf("down\n");
    }
    void stack_growth_v3(volatile char *function_parameter)
    {
        volatile char local [64];
        if (&local [63] > function_parameter)
            printf("up\n");
        else
            printf("down\n");
    }
    void stack_growth_v4()
    {
        char *m1 = (char *)malloc(2);
        char *m2 = (char *)malloc(2);
        if (m2 > m1)
            printf("down\n");
        else
            printf("up\n");
    }
    int main(void)
    {
        cout<<"---------stack_growth_v1----\n";
        stack_growth_v1();
        if(stack_dir==1)
            puts("stack grew upward");
        else
            puts("stack grew downward");
    
        cout<<"---------stack_growth_v2----\n";
        char c = 'c';
        stack_growth_v2(&c);
        cout<<"---------stack_growth_3----\n";
        volatile char d[64];
        stack_growth_v3(&d[63]);
        cout<<"---------stack_growth_4----\n";
        stack_growth_v4();
        return 0;
    }
    
    /***********************
    运行结果:
    ---------stack_growth_v1----
    stack grew downward
    ---------stack_growth_v2----
    down
    ---------stack_growth_3----
    down
    ---------stack_growth_4----
    down
    
    Process returned 0 (0x0)   execution time : 0.640 s
    Press any key to continue.
    
    
    ************************/
    








    展开全文
  • C语言或C++笔试题中常遇到判断printf输出值的问题,看似很简单,但却是考察函数参数的入栈问题,例如: ...其实是因为C语言函数入栈顺序是从右到左的,若参数为一个表达式,那么先执行表达...

    在C语言或C++笔试题中常遇到判断printf输出值的问题,看似很简单,但却是考察函数参数的入栈问题。例如:

    #include <iostream>
    
    int main() 
    {
    	int a = 10; 
    	printf("%d %d %d", a--, a, a--);
    
    	return 0;
    }

    输出结果:

     函数参数从右向左入栈,先执行右边第一个表达式a--, 然后执行右边第二个表达式 a--,所以printf参数为:printf("%d %d %d", 9, 8, 10);

    展开全文
  • 函数参数入栈顺序的确是从右至左的。可到底为什么呢?查了一直些文献得知,参数入栈顺序是和具体编译器实现相关的。比如,Pascal语言中参数就是从左到右入栈的,有些语言中还可以通过修饰符进行指定,如Visual C++....
  • (转)C语言函数参数压栈顺序小结先看一个小程序:#include &lt;stdio.h&gt;int f(int i, int j, int k) { printf(&quot;%d at [%X]\n%d at [%X]\n%d at [%X]\n&quot;, i, &amp;i, j, &amp...
  • Get function name by address in LinuxSource file: 1: #define __USE_GNU //import! 2: #include 3: #include ...C&plus;&plus; 简易时间类.h file #ifndef LIBFRAME_DATETIME_H_ #define LIBFRAME_...
  • C语言函数参数入栈的汇编理解

    千次阅读 2013-12-04 22:11:51
    把字符串“%p\n”压栈 从第10,11步来看,两个参数入栈顺序,其实不管顺序了,两个参数,最右边的在高地址,最左边的在低地址 call printf//12.调用函数printf,又是压栈出栈的操作了 到此可以得到8个字节的缓冲...
  • C语言函数参数入栈顺序 先通过一个小程序来看一看: #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); } ...
  • 主要介绍了C语言函数参数入栈顺序详解及实例的相关资料,需要的朋友可以参考下
  • C语言函数参数入栈顺序
  • 看到面试题C语言函数参数入栈顺序如何? 自己不知道,边上网找资料。下面是详细解释 #include <stdio.h> void foo(int x, int y, int z){ printf("x = %d at [%X]/n", x, &x); printf("y = %d at ...
  • C语言函数参数入栈顺序 先通过一个小程序来看一看: #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 ...
  • c语言函数参数采用自右向左的入栈顺序,主要原因是为了支持可变长参数形式。(我使用gcc编译,在windows下用vs编译会有出入,请读者自己尝试)   阅读该文,从汇编语言的角度,查看函数的入栈顺序...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,296
精华内容 5,718
关键字:

c语言函数参数入栈顺序

c语言 订阅