2014-10-16 72 views
0

以下程序的执行什么是绑定在一个时间在堆栈变量的最大数量时:如何找到变量的最大数量在堆栈

int x, y, z; 

int g(int a, int b) { 
    int c = 5 * a + b; 
    return c; 
} 

int f(int a, int b) { 
    a = g(a, 5); 
    return g(b, a); 
} 

int main() { 
    int a, b, c; 
    x = y = z = 0; 
    a = 5; b = 6; 
    c = f(a, b); 
    printf("%d", c); 
} 

如果有谁知道请如何发现。你能解释我该怎么做才能在每个可能给出的代码中找到它。 没有任何优化。

又如:

int x,y; 

int f(int a){ 
    if (a!=5) 
    return f(--a); 
    else 
    return a; 
} 

int main(){ 
    int a,b; 
    a=8;b=6; 
    x=f(a); 
    y=f(b); 
    printf("%d", x+y); 

    return 0; 
} 

这是答案6以上?因为第一次返回,返回一个变量3次..第二次返回一次返回一个数字,我们有两个变量在主要所以6?

+0

@Ilya我认为根据您的约定编辑代码可能不是最好的事情,并且不遵循SO规则。 – tomsoft 2014-10-16 10:23:14

+0

@tomsoft,感谢您的反馈!我会再读一遍SO规则。 (对我来说,很难阅读问题的初始版本,所以我决定改进它,但可能是错误的决定,谢谢!) – Ilya 2014-10-16 10:25:56

回答

1

这取决于编译器和优化设置。好的优化算法会产生如下的结果:

int main() { 
    printf("%d", 155); 
} 

其他算法会产生别的东西。所以,尝试使用反汇编器来编译结果。

+0

@cbegi,所以你可以认为没有任何优化。他们只是检查你是否了解什么是堆栈。 – Ilya 2014-10-16 10:27:29

+0

是的,你可以帮我吗?向我解释堆栈中保存了哪些变量? – cbegi 2014-10-16 10:28:44

+0

你读过关于栈上变量的东西吗?我们需要知道你懂什么来解释其他事情。 – Ilya 2014-10-16 10:34:40

2

您可以在您的脑海中(或在调试器中)一步一步地运行程序,并且可以计算call stack每帧中的所有活动变量(然后获取它们的最大和)。

在您的具体示例中,假设没有进行优化,最深层调用堆栈发生在greturn c;语句中,f调用main。因此,我们有3个变量3个调用栈帧为gabc;!我假设甲缩醛就像局部变量,这并不总是正确的做法),2个变量fab),和main有3个变量。

您的老师可能希望您在最深的状态下绘制调用堆栈。我把它留给你。

实际上,一些变量不会占用任何堆栈空间,例如,因为他们坐在一个寄存器中,或与另一个变量共享一个栈槽。这是编译器和ABI以及特定于处理器架构和操作系统。

但是,作为Ilya answered,一个好的编译器会将您的程序转换为optimization purposes,所以实际上答案可能不同。

如果使用GCC,您可以尝试在生成的汇编代码看(使用gcc -fverbose-asm -S),你会看到结果和使用的变量的数量取决于优化参数(即-O1-O2等。或缺乏它们)。您也可以使用GCC特定的-fstack-usage标志。您甚至可以尝试使用-fdump-tree-all标志gcc,该标志给出了数百个转储文件,详细说明编译器内部程序的各种中间表示(Gimple,SSA,...)。

阅读也wikipages上continuations(也可能是call/cc),tail callrecursioninline expansion

顺便提一下,C99标准所要求的调用堆栈的存在并不是严格意义上的(但我知道没有实现C不使用任何调用堆栈)。如果你很好奇,你应该阅读A.Appel的旧论文garbage collection can be faster than stack allocation(它解释了SML不使用任何调用堆栈的实现,因为它正在垃圾收集堆中分配每个“调用帧”,也就是“连续帧”)。

我也建议编译你的例子(用gcc -Wall -g)然后在gdb调试器中运行它们一步一步。经常使用display,step,backtrace,framecommandsgdb

+0

好的,你能解释一下这个案子的答案吗? – cbegi 2014-10-16 10:30:17

+0

@Basile,谢谢你的这些链接! – Ilya 2014-10-16 10:43:18

+0

然后你应该在纸上绘制*演变*调用堆栈,或者在板上用粉笔绘制更好的*。我记得去年在大学(巴黎第6期,计算机科学硕士)完成了那个 - 阶层3的递归实现 - 递归实现的电路栈。我花了20分钟。 – 2014-10-16 10:48:00