1月23日 C Primer Plus学习
9.3 递归
函数调用它自己,这种调用过程称为递归。
结束递归是使用递归的难点,因为如果递归代码中没有终止递归的条件测试部分,一个调用自己的函数会无限递归。
可以使用循环的地方通常都可以使用递归。有时用循环解决问题比较好,但有时用递归更好。递归方案更简洁,但效率却没有循环高。
9.3.1 演示递归
/* recur.c -- 递归演示 */
#include <stdio.h>
void up_and_down(int);
int main(void)
{
up_and_down(1);
return 0;
}
void up_and_down(int n)
{
printf("Level %d: n location %p\n", n, &n); // #1
if (n < 4)
up_and_down(n + 1);
printf("LEVEL %d: n location %p\n", n, &n); // #2
}
9.3.2 递归的基本原理
除了为每次递归调用创建变量外,递归调用非常类似于一个循环语句。
实际上,递归有时可用循环来代替,循环有时也能用递归来代替。最后,递归函数必须包含能让递归调用停止的语句。通常,递归函数都使用if或其他等价的测试条件在函数形参等于某特定值时终止递归。为此,
每次递归调用的形参都要使用不同的值。
9.3.3 尾递归
最简单的递归形式是把递归调用置于函数的末尾,即正好在 return 语句之前。这种形式的递归被称为尾递归(tail recursion),因为递归调用在函数的末尾。尾递归是最简单的递归形式,因为它相当于循环。
一般而言,选择循环比较好。首先,每次递归都会创建一组变量,所以递归使用的内存更多,而且每次递归调用都会把创建的一组新变量放在栈中。递归调用的数量受限于内存空间。其次,由于每次函数调用要花费一定的时间,所以递归的执行速度较慢。
9.3.4 递归和倒序计算
递归在处理倒序时非常方便(在解决这类问题中,递归比循环简单)。
9.3.5 递归的优缺点
递归既有优点也有缺点。优点是递归为某些编程问题提供了最简单的解决方案。缺点是一些递归算法会快速消耗计算机的内存资源。另外,递归不方便阅读和维护。
在程序中使用递归要特别注意,尤其是效率优先的程序。
所有的C函数皆平等
程序中的每个C函数与其他函数都是平等的。每个函数都可以调用其他函数,或被其他函数调用。这点与Pascal和Modula-2中的过程不同,虽然过程可以嵌套在另一个过程中,但是嵌套在不同过程中的过程之间不能相互调用。
main()函数是否与其他函数不同?是的,main()的确有点特殊。当 main()与程序中的其他函数放在一起时,最开始执行的是main()函数中的第1 条语句,但是这也是局限之处。main()也可以被自己或其他函数递归调用
——尽管很少这样做。
编程练习第8&9题
点击查看
// power.c -- 计算数的整数幂
#include<stdio.h>
double power(double n, int p);// 用while计算
double powerRecursion(double n, int p);//用递归计算
int main(void)
{
double x, xpow;
int exp;
printf("Enter a number and the positive integer power");
printf(" to which\nthe number will be raised. Enter q");
printf(" to quit.\n");
while (scanf("%lf%d", &x, &exp) == 2)
{
xpow = power(x, exp); // 函数调用
printf("%.3lf to the power %d is %.5lf\n", x, exp, xpow);
printf("%.3lf to the power %d is %.5lf(calculated by recursion)\n", x, exp, powerRecursion(x, exp));
printf("Enter next pair of numbers or q to quit.\n");
}
printf("Hope you enjoyed this power trip -- bye!\n");
return 0;
}
double power(double n, int p)// 函数定义
{
if (n == 0 && p == 0)
{
printf("The %lf to the power %d is not define, return 1\n", n, p);
return 1;
}
else if (n == 0)
{
return 0;
}
else if (p == 0)
{
return 1;
}
else if (p > 0)
{
double num = n;
for (int i = 1; i < p; i++)
{
n = n * num;
}
return n;
}
else
{
p = -p;
double num = n;
for (int i = 1; i < p; i++)
{
n = n * num;
}
return 1/n;
}
}
double powerRecursion(double n, int p)
{
if (n == 0 && p == 0)
{
printf("The %lf to the power %d is not define, return 1\n", n, p);
return 1;
}
else if (n == 0)
{
return 0;
}
else if (p == 0)
{
return 1;
}
else if (p > 0)
{
return n * power(n, p - 1);
}
else
{
return power(n, p + 1) / n;
}
}
运行结果


浙公网安备 33010602011771号