在函数的执行过程中无可避免的会涉及到参数存储的问题,而函数的参数是存储栈中,栈最大的特点是“先进后出”,之前创建的参数在当前已经被其他变量覆盖,无法访问,但是是存在的,不能认为已经被销毁了。函数在被递归调用时让人疑惑的主要原因也因为参数的存储引起的。
下面的程序可以很好的解释递归的过程中参数的存储以及使用过程。
#include<stdio.h> void binary_to_assic(unsignde int value ){ unsigned int a=value/10; if(a!=0) binaray_to_assic(a);//递归调用函数的过程就是将参数入栈的过程 putchar(value%10+'0'); //使用参数的过程就是讲参数出栈的过程 } void main(){ binaray_to_assic(4267); }
binary_to_assic()函数在执行过程中不断的对自身进行递归调用,将参数“value”压栈,压栈完成后从上到下的顺序是:4、42、426、4267。
接下来putchar语句会对变量进行引用,按照变量存储在栈中的顺序依次处理。所以最终会打印出:4267。
具体的函数流程能帮助我们进一步理解递归:
binaray_to_assic(4267)----binaray_to_assic(426)----binaray_to_assic(42)----binaray_to_assic(4) binaray_to_assic(4267){ binaray_to_assic(426){ binaray_to_assic(42){ binaray_to_assic(4){ binaray_to_assic(0)//结束递归 putchar(4%10) } putchar(42%10) } putchar(426%10) } putchar(4267%10) }
当开始执行第4级调用时,a的值为0,if判断不再满足,这时候不在继续调用binary_to_assic()函数,第4级调用则继续执行其后面的语句:putchar();此时第4级调用结束,把控制权返回给该函数的调用函数,也就是第3级调用函数。依次类推。
递归的基本原理:
1 每一次函数调用都会有一次返回.当程序流执行到某一级递归的结尾处时,它会转移到前一级递归继续执行.
2 递归函数中,位于递归调用前的语句和各级被调函数具有相同的顺序.如打印语句 #1 位于递归调用语句前,它按照递归调用的顺序被执行了 4 次.
3 每一级的函数调用都有自己的私有变量.
4 递归函数中,位于递归调用语句后的语句的执行顺序和各个被调用函数的顺序相反.
5 虽然每一级递归有自己的变量,但是函数代码并不会得到复制.
6 递归函数中必须包含可以终止递归调用的语句
关于递归的讲解《C和指针》讲解的很细致,有兴趣的可以看看。