学习 C 语言的递归函数
《C Primer Plus》函数章节:递归函数。结合 Visual Studio 调试理解 C 语言的递归函数,下面是书上一模一样的代码,贴在这里:
#include<stdio.h>
void up_and_down(int);
int main(void)
{
up_and_down(1);
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);
}
通过指针运算符可以查看到这个变量的内存地址信息。在格式化打印语句里取值就是%p
,按照十六进制输出,而%d
是按十进制输出。
可以看到变量 n 的地址在前 4 次都发生变化,这是因为传递给函数的变量是属于函数的,它是一个局部变量,因此地址不一样。后四次 n 变量的地址与前面的地址信息呈倒转的现象,是因为递归函数在往回执行导致的结果。
if n < 4,所以最多只能执行四次up_and_down()
函数。请注意,这四次执行完成之后,后面还有一个打印语句,它还没有被执行,也就是说,递归函数在哪里,那么后面的代码就被“截断”暂时不执行:
可以发现,行 18 累计了 4 次,然后依次从高到低由往回执行,也就是图1显示的效果。下图是递归函数执行的流程图:
第 1~4 级函数执行自己的时候,n 在逐步自增 1,直到第 4 级递归函数不符合 if 条件,就开始从第 4 级函数依次返回执行。根据图1可知,每一级函数接收的变量 n 都是独立的内存地址。所以,依次返回执行每一级的函数的变量 n 看似就是在自减。
递归有时候难以捉摸,有时候却很方便实用。结束递归是使用递归的难点,因为递归代码中没有终止递归的条件,就会无限递归。可以使用循环的地方通常可以使用递归,有时候用循环解决问题比较好,但有时候用递归更好。递归比较消耗计算机内存,每递归一次,里面的变量就要重新创建一次,图1已经证实了这一点。