static int Factorial(int n)
{
if (n == 0)
return 1;
else
return n * Factorial(--n);
}
当然,代码本身实现了它的预期目的,我需要了解它的工作逻辑。看来我了解递归(和复杂递归)的工作和“返回”的工作,但是这个例子中的一些事情并不是那么简单。具体来说,我想知道为什么没有终止“if”的第一个“return”和它返回的数字,这种计算是不可能的?我还在“VS”中“单步执行”了这段代码,目前还不清楚这个阶乘是如何计算的?因为如果你记下计算的值,那么这些是以下表达式:
5 * 4 = 20
4 * 3 = 12
3 * 2 = 6
2 * 1 = 2
1 * 0 = 0
<- 这些表达式是在代码单步执行时由“VS”显示给我的(当然,“VS”并没有以我在这里编写它们的形式显示给我),即第一个因素是我们的“n”第二个因素是 - Factorial(--n),因此,产品是这些因素的产品。我问,有了这样的产品和因子,如何正确计算阶乘?是的,我知道这些问题是由于对整个经济的逻辑(递归、“返回”关键字等)了解不足而引起的 D,因此,事实上,我问了这个问题。我希望我已经把问题说清楚了。)
此代码递归地计算阶乘如下:
其中括号是单独的递归级别
这只是循环退出的一个条件(任何递归都只是一个奇怪的循环——现代编译器中的大多数优化器会立即将它们转换为常规循环),加上等于 0 到 1(因为 1*<any number> = <any number> ) - 如果我们没有将 0 等同于 1,那么最后我们会将所有内容乘以 0 并得到 .. 0
对于您示例中的数字“5”,不是计算您上面写的内容,而是:
在这里,在第一个条件返回 1 期间,我们不调用 Factorial 函数——在这一步,循环被中断。
如果没有递归,那么相同的函数将如下所示:
当调用 Factorial(5) 时,会创建一个堆栈帧。此堆栈存储 n 的值,等于 5。
有一个与零的比较。由于它不相等,因此有一个转移到 else 分支。
乘法尚不可能,稍后将完成。
阶乘被调用,n 的值减一。那是阶乘(4)。
保存值 5 的堆栈继续存在。
一切都以同样的方式发生:创建一个新的堆栈帧,它存储 n 的值,等于 4。
又是一个分支。乘法仍然是不可能的。
对 Factorial(3) 的新调用。
保存值 4 的堆栈继续存在。
然后调用 Factorial(2)。然后是阶乘(1)。堆栈继续存在。
最后,调用 Factorial(0)。
同样,n 的值存储在堆栈中。
在这里,if 分支最终被执行。将一个返回到下一个级别。
当前堆栈为零的堆栈被销毁。
这是最终完成乘法的地方:1 * 1。结果在上面返回。
持有 1 的堆栈被销毁。
这一直到顶部:取返回值,乘以存储在当前堆栈帧中的值,然后向上推。
当前堆栈被销毁。
当执行到达值为 5 的最顶层堆栈时,也会发生乘法运算并释放堆栈的内存。结果值返回给调用函数。