说到递归这个词,听起来就比较模糊,不是十分好懂。那么今天就让我们看看函数递归到底是怎么回事吧!
什么是递归及递归的限制条件
首先我们先了解一下递归的具体意思吧,在C语言中递归就是函数自己调用自己。分开来看下,其中“递”是地推的意思,“归”是回归的意思。
还是有点难以理解,那让我们来看下这个超简单的递归吧。
int main()
{
printf("hehe\n");
main();
return 0;
}
在这个函数中main函数自己调用自己,实现不断打印hehe的效果,但过不了多久这个程序就会崩掉。进行调试后可发现会出现如下报错
这个就是递归不当所产生的比较常见的错误,叫做栈溢出(每次函数调用都会占领栈区一块空间,经过多次递推而无回归会使栈的空间被占用完,而产生栈溢出的错误)。
那么如何避免这个错误呢,这就涉及到递归的限制条件了
- 递归要有一个限制条件,当达到这个条件时递归讲不再继续。
- 每次递归后要更加接近这个递归条件
递归举例
上面大概就把递归介绍完了,那我们来举个例子看看吧。
让我们用递归来进行顺序打印一个数的每一位吧。
先来分析一下,如果是逆序打印1234这个数的话就会简单一些,让这个数字模10就可以拿到最后一位数,再把他除10再模10就可以拿到倒数第二位,那根据类似的原理我们可以把顺序打印理解为先顺序打印123在打印一个4,同理,顺序打印123也可以看做先顺序打印12在打印3,以此类推就可以顺序打印出1234。
根据上面的分析可知,这个过程就是递归,而递归的限制条件就是这个数字为一位数,每次递归后通过将原数字一次次除10使递归接近限制条件,让我们来看下推演图更直观的理解一下这个过程吧。
理解了过程后就可以打出如下代码
void Print(int n)
{
if(n>9)
{
Print(n/=10);
}
else
printf("%d",n%10);
}
int main()
{
int n=0;
scanf("%d",&n);
Print(n);
return 0;
}
递归的缺陷
让我们来用实例来说明这件事吧,用递归写一个求斐波那契数的代码。斐波那契数运算表示如下
根据提示,我们可以很快写出递归的代码
int Fib(int n)
{
if(n<=2)
return 1;
else
return Fib(n-1)+Fib(n-2);}
int main()
{
int n = 0;scanf("%d", &n);
int ret = Fib(n);
printf("%d\n", ret);
return 0;}
但如果在这里输入50,那么你会发现计算机在不断计算但不返回结果,这是为什么呢?
因为根据递归所以在计算第50个斐波那契数时会算第49和48个,在计算第49个时,有需要计算第48和47个…这样就会产生很多次循环计算,是结果返回的很慢。
所以递归固然写代码很简单,但他有一定的缺陷,在计算斐波那契数时如使用递归则会造成多次重复运算,减缓计算速度,从而不如用循环简便。并且如果递归层次太深也会导致栈溢出的现象。递归虽好,但不要迷恋哦。