IT技术博客大学习 共学习 共进步

小心递归次数限制

idea's blog 2012-08-13 13:42:31 浏览 3,943 次

    最近, 我在 review 组员的 Python 代码时, 发现了一个递归调用, 我立即发现了其中的问题.

    先说一下编程中递归. 只有会用递归, 并且能随心应手地写出递归程序的程序员, 才是已经入门了的程序员. 不过, 许多程序员并没有发现编程中的递归的一个限制: recursion depth limit, 逻辑上的递归可以无次数限制, 但语言执行器或者程序堆栈会限制递归的次数.

    例如一个 Cpy 编程语言(用 C 语法写 Python 代码)例子:

function func(i){
    if(i < 1000000){
        try{
            func(i + 1);
        }catch(Exception e){
            print \'maximum recursion depth exceeded\', i;
            print e;
            return;
        }
    }
}

func(1);

    因为 Python 语言有递归次数的限制, 试验结果是 997 次.

sys.setrecursionlimit( limit)

    而 C 语言的限制, 是程序堆栈的大小限制, 超过之后, 会产生 stack overflow. 比如下面这个 C 语言的例子在我的环境下只递归了 511 次:

void func(int i){
    int buf[1000];
    if(i < 100000){
        printf("depth = %d\\n", i);
        func(i + 1);
    }
}

int main(int argc, char **argv){
    func(1);
    return 0;
}

    再回到最先开始提到的, 我 review 发现的例子, 我为什么能一眼就发现那个递归有问题呢. 因为, 那段代码是一段按行分析文本的程序, 当发现某一行不符合条件时, 程序会递归调用分析函数递归地分析下一行. 显然, 如果连续 997 行文本不符合条件, Python 程序就会崩溃退出了.

建议继续学习

  1. PHP与递归Recursion (阅读 9,123)
  2. 循环、迭代、遍历和递归 (阅读 5,423)
  3. 递归并不一定非得是“自己调用自己的function” (阅读 4,164)
  4. PHP正则之递归匹配 (阅读 3,602)
  5. 倒置字符串中的单词 (阅读 3,485)
  6. 无限递归导致 Segmentation fault (阅读 3,322)
  7. 递归创建目录的一个函数 (阅读 3,122)
  8. 递归字符转义 (阅读 2,841)