C允许函数调用它自己,这种调用过程成为递归(rcursion)。
结束递归室递归的难点。如果递归代码中没有终止递归的条件测试部分,一个调用自己的函数会无线递归。
一般可以使用循环的地方通常都可以使用递归。有时使用循环解决问题比较好,但有时使用递归更好。递归
方案耕机安检,但效率却没有循环高。
递归的基本原理:
1. 每级别函数调用都有自己的变量;
2. 每次函数调用都会返回一次;
3. 递归函数中位于递归调用之前的语句,都按被调函数的顺序执行。
4. 递归函数中位于递归调用之后的语句,都按被调函数相反的顺序执行。
5. 虽然每级递归都有自己的变量,但是并没有拷贝函数的代码。
6. 递归函数必须包含能让递归调用停止的语句。
演示源码1:
// Len_Rcursion.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
void up_and_down(int n)
{
printf("In %d: n location %p\n", n, &n);
if (n < 4)
{
up_and_down(n + 1);
}
else if (n >= 4)
{
printf("\n");
}
printf("Out %d: n location %p\n", n, &n);
}
// 使用循环的函数,实现 n!=1*2*...*n
long Fact(int n)
{
long ans;
for (ans = 1; n > 1; n--)
{
ans *= n;
}
return ans;
}
// 使用递归的函数,实现 n!=1*2*...*n
long RFact(int n)
{
long ans;
printf("In %d: n= %p\n", n, &n);
if (n > 0)
ans = n * RFact(n - 1);
else
{
ans = 1;
printf("\n");
}
printf("Out %d: n= %p\n", n, &n);
return ans;
}
int main()
{
up_and_down(1);
//long fact1 = Fact(5);
//printf("fact1=%ld\n\n", fact1);
//long fact2 = RFact(5);
//printf("fact2=%ld\n", fact2);
return 1;
}
示例说明:
执行结果:
演示源码2:
// Len_Rcursion.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
// 使用递归的函数,实现 n!=1*2*...*n
long RFact(int n)
{
long ans = 0;
printf("In n=%d, local(n)= %p\n", n, &n);
if (n > 0)
{
ans = n * RFact(n - 1);
}
else
{
ans = 1;
printf("\n");
}
printf("Out ans=%d, n=%d, local(n)= %p\n", ans, n, &n);
return ans;
}
int main()
{
long fact2 = RFact(5);
printf("fact2=%ld\n", fact2);
return 1;
}
示例说明:
执行结果:
递归的优缺点:
优点是递归为某些编程问题提供了最简单的解决方案。
缺点是一些递归算法会快速消耗计算机的内存资源,其次递归不方便阅读和维护。