递归:
递归分为两步,第一步到达函数最深层,第二步原路返回到函数第一层,并返回最终返回值。
例如:
int fun(int x)
{
if(x == 0) return 0; //x == 0时,进行此步骤,return 0;就不会再进行下一语句了
return x + fun(x - 1);
}
int main()
{
cout<<fun(10)<<endl;
}//输出55
它的内部操作是如何进行的呢?
是按照 10 + 9 + 8 + ...+1+0 的顺序相加? 还是按照 0 + 1 + 2 + 3 + ...+10的顺序相加?
答案:递归函数fun(10) 是按照 0 + 1 + 2 + 3 + ...+10的顺序相加。
我们可以自己动手进行调试验证。(我使用的是Visual Studio 2022 社区版)
按F10 开始调试 按F11 一步一步执行程序步骤
第一步:从函数第一层(10)逐渐到达最深层(0)
10
9
8
...
1
0
第二步:从函数最深层(0)不断返回值给上一层函数直到返回到第一层(10)
运行到最深层, 进行返回操作 按F10 一步一步执行返回命令
返回值0 返回到倒数第二层 1 + 0
返回值1 返回到倒数第三层 2 + 1
返回值3 返回到倒数第四层 3 + 3
...
返回值45 返回到第一层 10 + 45
再按一次F10 返回 最终值 55
即验证了递归函数分两步走。
结论:
递归分为两步,第一步到达函数最深层,第二步原路返回到函数第一层,并返回最终返回值。即递归是嵌套的调用函数,进入函数的过程是递去,函数返回的过程是归来。
且,若没有if (x == 0) return 0;这个条件,执行fun(10),进行输出cont<<fun(10)<<endl;运行结果会出错 将不会显示结果,因为递归一直在进行,没有一个确切的最终值。
void类型递归:
那么:
如果不是返回值类型的递归函数还是会分两步走吗?
这与调用递归函数的位置有关
(不是返回值类型的递归,因为没有返回值,需要用if语句进行终止。)
可以分为两种情况:
定义 干事情:函数体的具体功能
(1): 调用递归函数在前,干事情在后。此情况递归函数分为两步走。
即会先走到最深层(0),当x == 0时,不再调用fun函数;那么还有事情没干呢,所以应该再返回上一层函数fun(1),进行输出工作,事情还是没有干完,继续返回上一层函数fun(2),进行输出工作...直到事情全部干完,此程序才会最终运行结束。
void fun(int x)
{
if (x == 0) return;//调用递归函数
fun(x-1);//干事情
cout << "x = " << x << endl;
}
(2): 干事情在前,调用递归函数在后。此情况递归函数只会走第一步。
因为干事情在前,递归函数走到最深层时,已经没事干了,就正常结束运行了。
void fun1(int x)
{
if (x == 0) return;//干事情
cout << "x = " << x << endl;//调用递归函数
fun1(x - 1);
}
总结:
递归:递归分为两步,第一步到达函数最深层,第二步原路返回到函数第一层,并返回最终返回值。void类型递归情况特殊,与调用递归函数的位置有关,分为两种情况:1.调用递归函数在前,干事情在后。此情况递归函数分为两步走。2.干事情在前,调用递归函数在后。此情况递归函数只会走第一步。