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;
    }
}
运行结果

posted @ 2022-02-07 11:05  shucharjer  阅读(32)  评论(0)    收藏  举报