C Primer Plus(总结),感觉好像更理解了一次递归。
先来个程序:
#include<stdio.h>//递归动态理解
void up_and_down(int);
long rfact(int n);
void to_binary(unsigned long n);
unsigned long Fibonacci(unsigned n);
int main(void) {
up_and_down(1);
printf("%ld\n", rfact(3));
to_binary(3);
return 0;
}
void up_and_down(int n) {
printf("Level %d: n location %p\n", n, &n);
if (n <4)
up_and_down(n + 1);
printf("LEVEL %d: n location %p\n", n, &n);
printf("\n");
printf("%ld\n", Fibonacci(3));
}
long rfact(int n) {
// 使用递归的函数求n的阶乘
long ans;
if (n >0) ans = n * rfact(n - 1);
else ans =1;
return ans;
}
void to_binary(unsigned long n) { /* 递归函数求一个十进制的二进制表示*/
int r;
r = n % 2;
if (n >=2)
to_binary(n/ 2);
putchar(r== 0 ? '0' : '1');
return;
}
unsigned long Fibonacci(unsigned n) {//递归函数求斐波那契数值
if (n >2) return Fibonacci(n-1) + Fibonacci(n-2);
else return1;
}
第1,每级函数调用都有自己的变量。也就是说,第1级的n和第2级的n
不同,所以程序创建了4个单独的变量,每个变量名都是n,但是它们的值各
不相同。当程序最终返回 up_and_down()的第1级调用时,最初的n仍然是它
的初值1(见图9.4)。
第2,每次函数调用都会返回一次。当函数执行完毕后,控制权将被传
回上一级递归。程序必须按顺序逐级返回递归,从某级up_and_down()返回
上一级的up_and_down(),不能跳级回到main()中的第1级调用。
第3,递归函数中位于递归调用之前的语句,均按被调函数的顺序执
行。例如,程序清单9.6中的打印语句#1位于递归调用之前,它按照递归的
顺序:第1级、第2级、第3级和第4级,被执行了4次。
第4,递归函数中位于递归调用之后的语句,均按被调函数相反的顺序
执行。例如,打印语句#2位于递归调用之后,其执行的顺序是第4级、第3
级、第2级、第1级。递归调用的这种特性在解决涉及相反顺序的编程问题时
很有用。稍后将介绍一个这样的例子。
第5,虽然每级递归都有自己的变量,但是并没有拷贝函数的代码。程
序按顺序执行函数中的代码,而递归调用就相当于又从头开始执行函数的代
码。除了为每次递归调用创建变量外,递归调用非常类似于一个循环语句。
实际上,递归有时可用循环来代替,循环有时也能用递归来代替。
最后,递归函数必须包含能让递归调用停止的语句。通常,递归函数都
使用if或其他等价的测试条件在函数形参等于某特定值时终止递归。为此,
每次递归调用的形参都要使用不同的值。例如,程序清单9.6中的
up_and_down(n)调用up_and_down(n+1)。最终,实际参数等于4时,if的测试
条件(n < 4)为假。