翻了一下list模块,看的时候,突然发现,尾递归其实是很容易展开成循环的。
想起读书时刚开始学程序,C语言,一直再纠结的一个问题,就是如何让一个函数返回两个参数的结果,哈哈,不要笑我。
do_sth([], [], SA, SB)->{SA, SB};
do_sth([HA|TA]=LA,[HB|TB]=LB, SA, SB)->
do_sth(TA, TB, HA+SA,HB+SB).
用erlang随便写了一个尾递归的函数,实现了对列表的一种计算
struct{int sa, int sb} do_sth(vector<int>:::iterator la, vector<int>::iterator lb, int sa, int sb){
if(...){
do_sth(....)
}else{struct{sa, sb}};
}
翻译成C++大概就是这个样子,代码写的很丑= =。
我觉得看尾递归代码的时候,就当他是循环,就很容易看了,终止条件就是else,其它就计算完后重新执行自己这个函数。
写尾递归也是这个思路,else上面的代码就把事情做完,else下面的代码就只做最后的清理,整理一下就是尾递归了。。
我觉得尾递归有一个特点,就是把中间值传到下一层递归里面去了,就是第三第四个参数,
一般C++写的递归是把中间值返回到上一层调用,然后继续计算,然后再把结果返回上一层调用。
这种区别就使得一般的C++代码一定要有个调用栈才能保证程序的正确性,如果把本层的计算结果传入到下一层进行计算,那么这个调用栈就不需要了,
就像完成了一次goto的过程。
即尾递归的计算顺序与递归是相反的。