C++ C++;递归问题

C++ C++;递归问题,c++,recursion,C++,Recursion,问这个我觉得有点傻,但我们走吧 当我试图在下面的网站上学习递归示例时,我遇到了一个让我困惑的路障 我稍微修改了代码,只是为了了解递归示例中的代码,我几乎完全了解它,但我不明白为什么变量“n”在“Pass B”中递增,而我没有告诉程序递增“n” 你能帮我解释一下吗 #include <stdlib.h> #include <iostream> using namespace std; long factorial (long n) { if (n > 1) {

问这个我觉得有点傻,但我们走吧

当我试图在下面的网站上学习递归示例时,我遇到了一个让我困惑的路障

我稍微修改了代码,只是为了了解递归示例中的代码,我几乎完全了解它,但我不明白为什么变量“n”在“Pass B”中递增,而我没有告诉程序递增“n”

你能帮我解释一下吗

#include <stdlib.h>
#include <iostream>

using namespace std;

long factorial (long n)
{
  if (n > 1)
{
   long r(0);
   cout << "Pass A" << endl;
   cout << "n = " << n << endl;
   cout << "r = " << r << endl;

   r = n * factorial (n-1);

   cout << "Pass B" << endl;  
   cout << "n = " << n << endl;
   cout << "r = " << r << endl;
   return (r);
}
  else
   return (1);
}

int main ()
{
  long number;
  cout << "Please type a number: ";
  cin >> number;
  cout << number << "! = " << factorial (number) << endl;
  system ("pause");
  return 0;
}
#包括
#包括
使用名称空间std;
长阶乘(长n)
{
如果(n>1)
{
长r(0);

您是否可以按顺序看到所有“通过A”-s,然后按相反顺序看到所有“通过B”-s,这给人的印象是,即使您只看到最初通过的n,n也会增加。

在我看来,您的程序工作正常,并且应该为数字=3输出类似的内容(为了可读性,请删除换行符):

通过A n=3 r=0[1]

通过A n=2 r=0[2]

通过B n=2 r=2[3]

通过B n=3 r=6[4]

所以我想我可以看到你们如何得出结论,在过程B中,n在增加,但事实并非如此。 您需要记住,n是一个函数局部变量,因此在这种情况下,在[3]中打印的n与[4]中的n是局部变量的不同实例


[1]和[4]中打印的n值来自函数的顶部调用(其中n=3),[2]和[3]中打印的值是因子的顶部版本(即n-1)中的调用。

如果您注意到,Pass B并不是第二次真正通过函数,它只打印递归的结果

factorial(3)
  factorial(2)
    factorial(1)  // returns 1
  factorial(2)    // r=2*1
factorial(3)      // r=3*2
因此,A打印4、3、2等,而背景词B打印432 1(即234)

尝试将第二个r打印替换为

   cout << "Pass B" << endl;  
   cout << "n = " << n << endl;
   cout << "r = " << r << " --- NOTICE RESULT ACCUMULATING AS WE UNNEST THE RECURSION" <<endl;

PS C:\temp> .\r.exe 4
Please type a number: 4
Pass A
n = 4
r = 0
Pass A
n = 3
r = 0
Pass A
n = 2
r = 0
Pass B
n = 2
r = 2 --- NOTICE RESULT ACCUMULATING
Pass B
n = 3
r = 6 --- NOTICE RESULT ACCUMULATING
Pass B
n = 4
r = 24 --- NOTICE RESULT ACCUMULATING
4! = 24
Press any key to continue . . .

cout这是因为您正在展开递归。

您并不是真正地递增
n
您只是返回到上一个函数调用,其中
n
在调用
factorial(n-1)
之前是
n+1

你一开始就去

   r = n * factorial (n-1);
这将导致对
阶乘的另一个函数调用


您一直这样做(从函数的开头开始,直到调用
factorial
,并将
n
递减1),直到您最终在调用
factorial
的函数中结束,其中
n在“展开”递归时会打印Pass B。它会递归,直到到达“else return(1)”部分,然后开始退出。因为它在每次进入的过程中用一个小于n的值调用自己,所以它似乎随着退出而递增。

在pass
A
和pass
B
中的
n
的值将始终与您在其间的任何地方都不更改它的值相同。您将n-1传递给递归调用,但是不会更改n的值

您可能感到困惑的原因是,对于给定的
n(n>2)
,您没有看到pass
A
和pass
B

When n=2, you'll see:
pass A for n=2
pass B for n=2

When n=3, you'll see:
pass A for n=3
pass A for n=2 // cuz of recursive call.
pass B for n=2
pass B for n=3 // looks like n has increment here..but this 'pass B' pairs with first pass A

因为那是递归倒转的时候

n
为2时,可能更容易考虑这种情况。在这种情况下,输入条件块并在“Pass A”之后递归。当您递归时,
n
为1,因此您通过
else
块返回。当您返回时,您返回到递归的前一帧,其中
n
为2。
r
根据递归调用的结果更新,
2*1
,但
n
仍保持
2
e

factorial(2)
  factorial(1)
factorial(2)
如果
n
最初是任何较大的值,那么您将继续倒带,并且
n
会将其值恢复到每次递归之前的每个值

factorial(3)
  factorial(2)
    factorial(1)  // returns 1
  factorial(2)    // r=2*1
factorial(3)      // r=3*2

一些答案使用缩进使其更容易理解发生了什么-您可以使用相同的效果使自己的调试输出更易于理解: 尝试将您的函数更改为以下内容:

long factorial (long n, std::string prefix= "") // default parameter
  ...
   cout prefix << "Pass A" << endl;
   cout prefix << "n = " << n << endl;
   cout prefix << "r = " << r << endl;

   r = n * factorial (n-1, prefix+ "  "); // increase indentation
   ...etc...

你确定你混淆了对
factorial
的不同级别递归调用的输出吗?请注意,对于给定级别的
Pass B
会在它引起的所有递归调用
Pass B
之后打印出来。这正是问题的类型。不要因为发布它而感到愚蠢。否则会怎样你学会了吗?
long factorial (long n, std::string prefix= "") // default parameter
  ...
   cout prefix << "Pass A" << endl;
   cout prefix << "n = " << n << endl;
   cout prefix << "r = " << r << endl;

   r = n * factorial (n-1, prefix+ "  "); // increase indentation
   ...etc...
Please type a number: 4

Pass A
n = 4
r = 0
  Pass A
  n = 3
  r = 0
    Pass A
    n = 2
    r = 0
    Pass B
    n = 2
    r = 2
  Pass B
  n = 3
  r = 6
Pass B
n = 4
r = 24

4! = 24