C primer Plus 9.3.4 递归和倒序计算 DE3

递归在处理倒序时非常方便

(在解决这类问题中,递归比循环简单)
我们要解决的问题是:编写一个函数,打印一个整数的二进制数,

二进制表示法根据 2 的幂来表示数字

例如,十进制数 234 实际上是 2×102+3×101+4×100,所以二进制数101实际上是1×22+0×21+1×20。二进制数 由0和1表示。

我们要设计一个以二进制形式表示整数的方法或算法。例如:如何用二实际上是进制表示十进制数5?

在二进制中,奇数的末尾一定是1,偶数的末尾一定是0

所以通过5%2即可确定5的二进制数的最后一位是1还是0.一般而言,一

般而言,对于数字n,其二进制的最后一位是 n % 2

因此,计算的第一位数字实际上是待输出二进制数的最后一位。这一规律提示我们,在递归和递归调用之前计算n%2,在递归调用之后打印计算结果。这样,计算的第一个值正好是最后一个打印的值

要获得下一位数字,必须把原数除以二,这种计算方法相当于在十进制下把小数点左移一位,如果计算结果是偶数,那么二进制的下一位数就是0,是奇数,就是1;

5%2余1 是奇数 第一位就是1
5/2商 2是偶数 2%2商1 余0 ,那么二进制的第二位数就是0
1/2余1 第三位二进制数就是1
那么表示5的二进制数就是101

那么程序何时停止计算? 当与2相除的结果小于2时,停止计算

因为只要结果大于或等于2,就说明还有二进制位,每次除以二就相当于去掉一位二进制,直到计算出最后一位为止
(如果不好理解, 600可以拿十进制数来做类比:628%10得8,因此8就是该数最后一位;而 628/10得62,而62%10得2,所以该数的下一位是2,以此类推)。程序清单 9.8演示了上述算法)

/*以二进制的形式打印制整数*/
#include <stdio.h>
#include <stdlib.h>


int main()
{
     unsigned long number;   ///用无符号长整型是为了提高能输入的数的范围
     printf("Enter an integer ( q to quit): \n");  ///提示用户输入信息
     while( scanf("%ld",&number) == 1)
     {
         printf("Binary equivalent:\n");
         to_binary(number);
         putchar('\n');
         printf("Enter an integer ( q to quit): \n");
     }
    printf("Hello world!\n");
    return 0;
}

void to_binary( unsigned long n)  ///递归函数
{
    int r;
    r=n%2;
    if(n>=2)
        to_binary(n/2);    ///这个位置的意思其实就是n=n/2  ,在除的过程中就已经将n的值改变了

     putchar( r == 0 ? '0' : '1');
     return;
}

在该程序中,如果r的值是零,to_binary()函数就显示字符‘0’;如果r的值是1,则其显示1条件表达式r == 0 ? ‘0’ : '1’用于把数值转 换成字符
不用递归,是否能实现这种用二进制形式表示整数的想法?
但由于这种算法要首先计算最后一位二进制数,所以在显示结果之前必须把所有的位数都储存在别处(例如:数组)

9.3.5 递归的优缺点

优点是递归为某些编程问题提供了最简单的解决方案
缺点是一些递归算法会快速消耗计算机的内存资源。另外,递归不方便阅读和维护

**

斐波那契数列如下:第一个和第二个数字都是1 ,而后续的每个数字都是前两个数字之和

**
例如,该数列的前几个数是:1、1、2、3、5、 8、13。
下面,

我们要创建一个函数,接受正整数n,返回相应的斐波那契数值

,首先,来看递归。递归提供一个简单的定义。如果把函数命名为Fibonacci();那么如果n是1或2,Fibonacci(n)应返回一;对于其他数值,则应返回Fibonacci(n-1)+Fibonacci(n-2);
在这里插入图片描述

双递归

为了说明这个问题,假设调用 Fibonacci(40)。这是第1 级递归调用,将 创建一个变量 n。然后在该函数中要调用Fibonacci()两次,在第2级递归中要 分别创建两个变量n。这两次调用中的每次调用又会进行两次调用,因而在 第3级递归中要创建4个名为n的变量。此时总共创建了7个变量。由于每级递 归创建的变量都是上一级递归的两倍,所以变量的数量呈指数增长!在第 5 章中介绍过一个计算小麦粒数的例子,按指数增长很快就会产生非常大的 值。在本例中,

指数增长的变量数量很快就消耗掉计算机的大量内存,很可 能导致程序崩溃。

虽然这是个极端的例子,但是该例说明:在程序中使用递归要特别注 意,尤其是效率优先的程序

C函数皆平等

程序中的每个C函数与其他函数都是平等的。每个函数都可以调用其他 函数,或被其他函数调用

。这点与Pascal和Modula-2中的过程不同**,虽然过 程可以嵌套在另一个过程中,但是嵌套在不同过程中的过程之间不能相互调 用**。
main()函数是否与其他函数不同?是的,main()的确有点特殊。当 main()与程序中的其他函数放在一起时,最开始执行的是main()函数中的第1 条语句,但是这也是局限之处。

main()也可以被自己或其他函数递归调用 ——尽管很少这样做。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值