Linux 版 (精华区)

发信人: netiscpu (夜☆星光点点☆), 信区: Linux
标  题: ◇ 星星流讲座 0041
发信站: 紫 丁 香 (Sun Nov  8 18:37:49 1998), 转信


寄信人: guest.bbs@hgluo.hust.edu.cn 
标  题: ◇ 星星流讲座 0041
发信站: 华南理工大学 BBS木棉站
日  期: Thu Feb 20 14:55:55 1997

发信人: ax.bbs@bbs.ee.nthu.edu.tw. (athena), 信区: test
标  题: 星星流讲座 0041
发信站: ☆清华电机☆ (Sat Jul  8 17:37:54 1995)


;35m第 6 讲 之 4            函数
                        Topic: Recursion (1)m

我们前面提到过,呼叫一个函数,就是把程式的控制权交给函数,
当函数执行完之後,再把控制权交回来。例如:

void main (void)                        ↓ main() 开始执行
{                                       ↓
    /* main() start here */             ↓
    foo ();                              —┐ 把控制权交给 foo()
    /* main() continue here */       ┌→  │
}                                    │    │
                                     │  —┘
void foo (void)                      │ ↓ foo() 开始执行
{                                    │ ↓
    /* foo() work here */            │ ↓
}                                    └— 执行完毕,把控制权还给 main()

那如果我们在函数之中呼叫函数本身呢?例如:

void foo (void)
{
    foo ();
}

这时候控制权的流向就会如下:

        (第一个) foo()
                  ↓ 呼叫 foo(),把控制权交给 foo()
        (第二个) foo()
                  ↓ 呼叫 foo(),把控制权交给 foo()
        (第三个) foo()
                  ↓ 呼叫 foo(),把控制权交给 foo()
                  :
                  :

控制权交出去之後就不会回来了,这是一种很危险的动作,其实这就是一种
错误的递回 (recursion)。什麽叫做递回呢?m递回就是函数直接或间接地叫
用自己0m。什麽时候我们会用的上递回函数呢?一个常见的例子是求某数的阶
乘:

int factor (int n)
{
    if (n < 0)
        return factor (n + 1) * n;
    else if (n > 0)
        return factor (n - 1) * n;
    else                                /* n == 0 */
        return 1;                       /* 0! = 1 */
}

我们知道

        n * (n - 1)! if n > 0
   n! = n * (n + 1)! if n < 0
        1            if n = 0

直觉地写成程式就变成了上面 factor() 这个函数 (当然,这个函数在实
际上并不实用,实用的阶乘函数并不容易作出来),这是一个标准的递回
的写法。m递回函数有三大要件:起始条件、递回终止条件、递回本体。0m
在我们上面的例子中,起始条件就是参数 n (要求 n 的阶乘),而递回
终止条件则是 n == 0 (当 n = 0 时传回 1,不再继续递回),递回的本
体是 factor (n + 1) * n 及 factor (n - 1) * n 这两个实际呼叫递回
函数的部份。

我们现在花点时间来 trace 一下 factor (3) 的动作:

        呼叫 factor (3)
             │
         m□0m  │
             ↓
       return factor (2) * 3    m□0m传回 2*3=6,函数结束
                    │      □—————————┐
   m□0m呼叫 factor(2) │                          │
                    ↓                          │
            return factor (1) * 2       m□0m传回 1*2=2 给 factor(3)
                      │          □————————┐
     m□0m呼叫 factor(1) │                            │
                      ↓                            │
               return factor (0) * 1      m□0m传回 1*1=1 给 factor(2)
                        │          □—┐
       m□0m呼叫 factor(0) │              │
                        ↓              │
                     return 1 —————┘ m□0m传回 1 给 factor(1)

为什麽我们说终止条件是 n == 0 呢?因为它是递回函数不再继续呼叫
自己的判断条件,所以叫做递回终止条件。m每一个递回函数都必须设定
递回终止条件0m,至於递回终止条件要如何找出来呢?它通常是数学中所
谓的边界条件 (boundry condition),只要多多练习大概就能一眼就看
出来了。
--
本文原作者为徐振家,原作刊载於星星神教总坛 ☆清华电机☆ test 板。
你可以以电子文件的形式将本文自由流传於台湾学术网路,但必须包含此版权声明。
原作者依中华民国著作权法之规定,享有本文之著作权,请勿抄袭以免触法。
未经授权任何人不得以任何形式对本文做任何修改及商业上之应用。
其他网路的转载或其他用途的应用,请先知会作者,并取得其同意。
对本文有任何疑问或意见请 mail 给 ax.bbs@bbs.ee.nthu.edu.tw,谢谢。


--
m;32m※ 转寄:.华南网木棉站 bbs.gznet.edu.cn.[FROM: mtlab.hit.edu.cn]
--

                              Enjoy Linux!
                          -----It's FREE!-----

※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: mtlab.hit.edu.cn]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.232毫秒