前几天我遇到了一个问题。 问题在于......
int func(n){
if(n < 4)
return func(++n) + func(++n);
return n;
}
我编译&amp;通过调用func(0)
运行该程序,结果为35。
但是我无法将堆栈树可视化。
任何人都可以描述堆栈。
答案 0 :(得分:4)
这个问题涉及两个不相关的问题。
编写的代码具有未定义的行为。未指定函数是用(n + 1)和(n + 2)调用,还是用(n + 1)或(n + 2)调用两次或完全不同。该标准的相关部分是:C11 n1570 S6.5 / 2:[编辑]
如果相对于不同的副作用,对标量对象的副作用未被排序 在相同的标量对象上或使用相同标量的值进行值计算 对象,行为未定。如果有多个允许的排序 表达式的子表达式,如果这样一个未经测序的一方,行为是不确定的 效果发生在任何排序中。 84)
这可以通过对代码的微小更改轻松解决,如下所示。
int func(n){
if(n < 4) {
return func(n+1) + func(n+2);
}
return n;
}
真正的问题是这一切是如何运作的。显然,每个函数都会调用两次,或者根本不调用它,它只能从最低级别返回4或5。这是二叉树的结构。写出树并标记每个值,你将获得一个4s和5s的字符串。它们总计达35个。
答案 1 :(得分:1)
乐趣(0)
Stack- fun(1)+fun(2)
--------------------
stack- fun(2)+fun(3)+fun(2)
stack- fun(3)+fun(4)+fun(3)+fun(2)
stack- fun(4)+fun(5)+fun(4)+fun(3)+fun(2)
stack- 4+fun(5)+fun(4)+fun(3)+fun(2)
stack- 4+5+fun(4)+fun(3)+fun(2)
stack- 9+fun(4)+fun(3)+fun(2)
等等你会发现结果为35;首先考虑堆栈顶部。
答案 2 :(得分:1)
所以就这样了。
func(1) + func(2)
func(2) + func(3) + func(3) + func(4)
func(3) + func(4) + func(4) + func(5) + func(4) + func(5) + 4
func(4) + func(5) + 4 + 4 +5 +4 + 5 +4
4 + 5 + 4 + 4 +5 +4 + 5 +4
35
答案 3 :(得分:0)
不同编译器和不同机器的输出可能不同。这就像询问未定义的自动变量的值。
未定义行为的原因是,在这种情况下,运算符+
没有标准的操作数定义评估顺序。可以先执行func(++n)
或func(n++)
。这来自C中序列点的概念。