递归机制

学编程语言的人都知道递归,但不一定所有人都明白它是如何被执行的。接下来我想谈一下我对递归的认识和理解。
如果一个算法调用自己来完成它的部分工作,则这个算法是递归的。举一个小小的例子:
#include<iostream>
using namespace std;
void test(int a){
if(a>1){
test(a-1);
test(a-2);
}
cout<<a<<endl;
}
void main(){
test(3);
}
输出结果为:1 0 2 1 3
为什么会这样呢?这与递归的存储机制有关。
递归的子程序调用通过将有关子程序的一些必要信息(如返回地址、参数、局部变量等)存储到栈中来实现它的目的。栈结构的特点为FILO(先进后出)。 现在来看上面的例子,主函数中第一次调用test时,把test指令所在的地址保存到栈中,并把3传给test。 接下来test(a-1)对test进行递归调用,调用时参数变为2,这时test(a-1)指令所在的地址和参数2一起被保存到栈中。
test(a-1)继续递归调用test,参数变为1,这时test(a-1)指令所在的地址和参数1一起被保存到栈中。
第三次调用test时if(a>1)不满足,所以不执行if语句中的内容,执行cout语句,输出a(此时a为1)。注意此时test(a-1)对test的第三次调用结束,每一次从test返回都将弹出栈所保存的a的当前值,以及函数调用所返回的地址。所以返回到第二次调用时的地址,而第二次调用test函数没有执行完里面的内容,因此在第二次调用里继续接下来的语句(从程序的第六行到第九行),第六行又是一个递归调用,相当于递归里的递归。我们已经知道,此时a=1已经被弹出栈,现在的a=2,test(a-2)调用test后a变为0,由于0<=1,所以直接执行cout语句,输出0。这个过程中,test(a-2)和test(a-1)一样,也要保存它的指令地址和参数的值。a=0弹出栈后栈为空,test(a-2)的调用结束。最后一定不要忘记执行cout语句,输出2.至此,test(a-1)的第二次调用已全部完成。
最后返回test(a-1)第一次调用的地址,a=3,继续从程序的第六行到第九行执行下去(执行方式与第二次调用一样,在此我不再赘述)。不过要强调的一点就是,在执行递归的递归结束后,一定要知道程序具体返回到哪里, 不要混淆。此次输出1和3.至此,第一次调用结束,返回到程序的第十一行。
遇到不太清楚过程的程序一定要多上机调试,从每一步的结果中得到启发,才能对其有更深刻的理解。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值