函数递归调用

我们学习了函数的嵌套调用,可以在函数中调用函数。那么,如果在一个函数中,调用自己这个函数,那么,这个执行过程称为:函数递归调用。这个函数也称为:递归函数。程序测试例子:

函数递归调用

 

程序运行结果如下:

函数递归调用

 

在这个测试例子中,我们定义了func函数,在func函数中又调用了func函数自己;所以,这个过程称为:递归调用

我们知道,在程序的执行过程中,碰到函数调用的时候,就跳转到函数定义的函数体中执行,那么,函数的递归调用。就是函数又跳转到自己定义的函数体中运行;那么,我们分析上面例子中,函数的递归调用执行过程:

(1) 程序从main函数开始,执行到func(3);代码,就跳转到func函数中执行;

(2) 执行func(3);代码,就是把实参3数值,传递给形参变量x;然后,执行x--;形参变量x的值变为2;接着执行if(x <= 0)判断,由于变量x的值等于2,大于0,所以,没有执行return语句,继续执行:

printf("x = %d\n", x);

func(x);

此时,输出调试信息,然后,执行func(x);代码,就是在func函数中调用func函数,就是递归调用,由于x变量值为2,相当于执行func(2);代码。

(3) 执行func(2);代码,把实参2数值传递个形参变量x,然后,执行x--;形参变量x的值变为1;接着执行if(x <= 0)判断,由于变量x的值等于1,大于0,所以,没有执行return语句,继续执行:

printf("x = %d\n", x);

func(x);

此时,输出调试信息,然后,执行func(x);代码,递归调用,由于x变量值为1,相当于执行func(1);代码。

(4) 执行func(1);代码,把实参1数值传递个形参变量x,然后,执行x--;形参变量x的值变为0;接着执行if(x <= 0)判断,由于变量x的值等于0,所以,执行return语句,结束func(1)函数调用。

(5) 结束func(1)函数调用,就返回到func(2)的调用,func(2)函数执行结束之后,返回到func(3)函数的调用;

(6) 最后,func(3)函数调用结束,就返回到main函数中继续执行。

那么,这个函数递归调用的过程,可以总结成如下图:

函数递归调用

 

可以看到,函数的调用调用流程如下:

func(3) à func(2) à func(1)

那么,当调用到func(1)的时候,进入func函数,执行x--语句,变量x的值变为0,然后,判断if(x <= 0)语句,由于 x<=0 表达式的值为真,所以,执行return语句,结束func(1)函数的调用。

结束func(1)函数的调用之后,返回到func(2)函数,然后,执行:

printf("call end, x = %d\n", x);

输出 call end, x = 2 语句,就是说明返回到func(2)函数的调用中。然后,结束func(2)函数的调用之后,返回到func(3)函数。结束func(3)函数调用之后,就返回到man函数中。

注意:递归函数就是重复调用自己的函数。那么,函数不可以无限地调用自己,否则,出现函数栈调用异常。所以,递归调用的函数,应该有结束递归调用的时候。例如上面测试的例子中,func函数递归调用,会判断变量x,如果 if(x <= 0)判断成立,则执行return语句,退出函数运行,不再递归调用func函数。这样,就结束了函数的递归调用。