递归两个重要特性:
1.存在限制性,当符合这个条件时,递归便不再继续
2.每次递归后越来越接近这个限制条件
摘自《C和指针》
例子:一个无符号整型值,转换为字符串并打印它
#include<stdio.h>
void binary_to_ascii(unsigned int value)
{
unsigned int quotient;
quotient = value/10;
if(quotient != 0)
{
binary_to_ascii(quotient);
}
putchar(value%10 + '0');
}
下面让我们追踪递归函数调用过程
追踪一个递归函数执行过程的关键是理解函数中所声明的变量是如何存储的。当函数被调用时,它的变量的空间是创建于运行时堆栈上的。以前调用的函数的变量仍保留在堆栈上,但它们被新函数的变量所掩盖,因此是不能被访问的。
如上例,参数value和局部变量quotient。下面一些图显示了堆栈的状态,当前可以访问的变量位于栈顶。所有其它调用的变量饰以灰色阴影,表示它们不能被当前正在执行的函数访问。
假设value第一次为 4267
当函数刚开始执行时,堆栈内容如下图
除法运算后,quotient为426
接着if语句判断quotient值非零,所以对该函数递归调用,第二次递归调用,堆栈内容如下:
堆栈上创建了一批新的变量,隐藏了之前的那批变量,除非当前的递归调用返回,否则它们是不能被访问的,再次执行除法运算后,堆栈内容如下:
quotient值非0,需要继续执行递归调用,并再创建一批变量。在执行完这次调用的除法运算后,堆栈内容如下:
quotient值非0,继续执行递归调用。堆栈内容如下:
当quotient值非0时,把它的值作为初始值重新开始循环,但是递归调用会保存一些信息,也就是保存在堆栈中的变量值
现在quotient值为0,递归函数便不再调用自身,而是开始输出打印。然后函数返回并销毁堆栈上的变量值。
输出: 4
接着函数返回,它的变量从堆栈中销毁。接着,递归函数的前一次调用重新继续执行,它所使用的是自己的变量,它们现在位于堆栈的顶部。递归调用返回的堆栈信息如下:
最后,这个递归函数就彻底返回到其它函数调用它的地点。最后的打印结果为字符4267。