函数的递归调用
2018-05-06 15:45
204 查看
一个函数在它的函数体内调用它自身称为递归调用,这种函数称为递归函数。执行递归函数将反复调用其自身,每调用一次就进入新的一层。
【示例】用递归计算 n!。阶乘 n! 的计算公式如下:
根据公式编程:
- long factorial(int n){
- long result;
- if(n==0 || n==1){
- result = 1;
- }else{
- result = factorial(n-1) * n; // 递归调用
- }
- return result;
- }
这是一个典型的递归函数。调用factorial后即进入函数体,只有当 n==0 或 n==1 时函数才会执行结束,否则就一直调用它自身。
由于每次调用的实参为 n-1,即把 n-1 的值赋给形参 n,所以每次递归实参的值都减 1,直到最后 n-1 的值为 1 时再作递归调用,形参 n 的值也为1,递归就终止了,会逐层退出。
例如求 5!,即调用factorial(5)。当进入factorial函数体后,由于 n=5,不等于0或1,所以执行
result = factorial(n-1) * n;,即
result = factorial(5-1) * 5;,接下来也就是调用
factorial(4)。这是第一次递归。
进行四次递归调用后,实参的值为 1,也就是调用factorial(1)。这时递归就结束了,开始逐层返回。factorial(1) 的值为 1,factorial(2) 的值为 1*2=2,factorial(3) 的值为 2*3=6,factorial(4) 的值为 6*4=24,最后返回值 factorial(5) 为 24*5=120。
注意:为了防止递归调用无终止地进行,必须在函数内有终止递归调用的手段。常用的办法是加条件判断,满足某种条件后就不再作递归调用,然后逐层返回。
递归调用不但难于理解,而且开销很大,如非必要,不推荐使用递归。很多递归调用可以用迭代(循环)来代替。
【示例】用迭代法求 n!。
- long factorial(int n){
- int i;
- long result=1;
- if(n==0 || n==1){
- return 1;
- }
- for(i=1; i<=n; i++){
- result *= i;
- }
- return result;
- }
关于函数调用的原理,请大家阅读《C语言和内存》中的《栈的概念以及栈溢出》《一个函数在栈上到底是怎样的》《详细分析一个函数进栈出栈的例子》几节,届时你将会明白递归调用的开销为什么很大。
相关文章推荐
- 笔记-<函数的递归调用>
- C语言简单函数递归调用问题
- python学习:函数的递归调用
- 函数及递归调用介绍
- 数据结构基础(6)--递归和函数调用--汉诺塔问题C语言实现
- C++ primer 这本书上有这么两句话“派生类虚函数调用基类版本时,必须显式使用作用域操作符。如果派生类函数忽略了这样做,则函数调用会在运行时确定并且将是一个自身调用,从而导致无穷递归。”
- 函数的递归调用
- c语言中的函数的定义以及相关的调用、嵌套、递归以及和数组的关系
- 函数递归调用通俗讲解
- 函数的递归调用
- c++ 函数的递归调用
- 函数的递归调用
- 函数的递归调用与分治策略
- 求两个数的最大公约数 (函数的递归调用)
- 复习4次课(12月1日) 1.1 函数定义 1.2 函数的参数 1.3 函数的默认参数 1.4 函数的变量 1.5 函数的返回值 1.6 多类型传值和冗余参数 1.7 函数的递归调用
- java开发C语言解释器:函数递归调用时的环境保护
- 函数的递归调用
- C++:函数的递归调用相关
- UE4 蓝图里的 函数递归调用
- 函数的类型,函数的声明,函数的定义,函数的调用,函数嵌套,函数递归,形参实参