除了尾递归之外,是否还有可能进行尾调用优化?我一直试图找到或想到一个不涉及递归的,但没有成功。可能吗?有什么例子吗?
答案 0 :(得分:3)
当然,“尾调用优化”实际上是这种优化的术语,它是最常见的递归不可知形式。此优化不会使用等效的while
循环或类似的东西替换递归。而是转换尾部调用,以便重新使用调用者的堆栈帧。 return f(...)
或f(...); return
形式的任何代码都可以修改。它适用于任何 f
,即使对于函数指针/闭包/虚拟方法,编译器也不可能知道被调用的内容。因此,对于单独的编译,高阶函数,后期绑定等,它也可以更好地工作。
如果你看一下足够的代码,无论是功能性的还是命令性的,你都会偶尔看到一些没有任何代码的电话。一个常见的情况是,调用者委托被调用者执行主任务,并且只做一些额外的准备工作。在功能代码中,你经常会发现许多小函数只做一件事并且是用其他小函数实现的,所以你最后应用了一些简单的转换到参数,然后执行一个尾调用。下一层(将转换后的数据作为参数)。 TCO优化了第二步,它(理想情况下)使调用像简单的jump
一样便宜,并使得漂亮的模块化代码占用的堆栈空间比单片实现更少。在面向对象的设计中,您可能希望组合其他对象的对象并公开委派的便捷方法:
SomeClass doSomething(Argument a) {
log.debug("Doing something");
return this.somethingDoer.doIt(a, this.someExtraData);
}
另一个技术上相互递归的例子,但通常只有很少的任何给定函数的激活(其间有数十或数百个其他激活),是通过每个状态具有一个函数并调用它进入该状态来实现的状态机:
void stateA() {
// do actual work
// determine which transition applies
stateB();
}
void stateB() {
// do actual work
// determine which transition applies
state...();
}
// dozens, possibly hundreds of other states
答案 1 :(得分:1)
int bar(int x);
int foo(int x) { return bar(x); }
foo
可以直接跳转到直接返回来电者的bar
;任何地方都不需要递归。