递归函数过程
在嵌入式Linux开发《C语言专题(五:(1)函数基本概念)》文章中对C语言中函数的基本概念做了详细讲解,这些基本概念必须理解和掌握,这一部分将讲解C语言中的递归函数。将从(1)什么是递归函数及需要哪些注意事项?、(2)递归函数的使用场景?和(3)递归函数代码演示及对比 三方面介绍。
(1)什么是递归函数及需要哪些注意事项?
1)递归函数就是函数中直接或者间接调用了自身的函数,类似于循环但不等同于循环。
2)递归函数需要注意的地方:必须有一个终止递归的条件,类似于循环中的循环终止条件,否则递归一直执行,就不会得到我们想要的结果。另外一个原因就是递归函数最可能也最适合在栈内存上递归,而栈内存大小是固定了,一旦一直递归很可能出现栈溢出,是代码运行停止。因此在使用递归函数时一定要注意递归终止条件,要在合适的场景中进行应用。所以递归函数在每一次递归之后都应该更加接近于递归终止条件。理解了递归之后,当我们阅读关于递归函数的代码时,不要纠结于它的执行过程,而应该找到递归的终止条件,并且要相信递归函数会完成它的功能。
(2)递归函数的使用场景?
常见的递归函数的应用:求阶乘、求斐波那契数列。一个正整数的阶乘是所有小于及等于该数的正整数的积,并且0的阶乘为1,自然数n的阶乘写作n!亦即n!=1×2×3×...×n。斐波那契数列又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
(3)递归函数代码演示及对比
1)用递归求阶乘 代码如下图所示
递归求阶乘代码
代码执行结果如下图所示:
递归求阶乘代码结果
有时候用递归并不是最好的方法,因为递归函数被调用时将涉及到一些开销:参数压到栈中,为所有的局部变量分配内存空间,保存相应的值,当递归函数每次调用返回时,必须回复栈中变量的值。从代码的结果中输出语句可以看出。我们能够发现上面代码中递归调用返回之后不再执行了,所以也可以用简单的while循环来实现相应的功能。如下面所示:
2)用while循环求阶乘 同样可以实现阶乘功能代码如下图所示:
循环求阶乘代码
3)用递归求菲波那切数列 代码如下图所示:
递归求菲波那切数列代码
代码执行结果如下图所示:
递归求菲波那切数列结果
4)用迭代求菲波那切数列 代码如下图所示:
迭代求菲波那切数列代码
迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。比如上面代码中的s1 s2 result 每一次执行后都把s2的值赋值给s1 result的值赋值给s2 最后result的值为s1与s2的和。另一种迭代的定义:对计算机特定程序中需要反复执行的子程序*(一组指令),进行一次重复,即重复执行程序中的循环,直到满足某条件为止。
当一个问题非常复杂,用迭代方式实现比较困难,这时候使用递归可以利用递归的简介性可以弥补它运行时带来的开销。
综上所述当使用递归方式来进行实现功能时(不论是求阶乘还是菲波那切数列或者其它),一定要想清楚所带来的好处是否抵得上由它所产生的代价。