Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 递归:显示从a到b的数字,并显示它们的和_C#_Recursion - Fatal编程技术网

C# 递归:显示从a到b的数字,并显示它们的和

C# 递归:显示从a到b的数字,并显示它们的和,c#,recursion,C#,Recursion,我想知道,这笔钱从哪里来?我知道什么是递归,但我不知道inti是如何得到和的。我读过关于堆栈的文章。。。但我还是不明白。请帮忙:) 代码如下: static void Main(string[] args) { int i = RecursiveMethod(1,3); //Console.ReadLine(); } static int RecursiveMethod(int a, int b) { Console.WriteLine(a); if (a ==

我想知道,这笔钱从哪里来?我知道什么是递归,但我不知道
inti
是如何得到和的。我读过关于堆栈的文章。。。但我还是不明白。请帮忙:) 代码如下:

static void Main(string[] args)
{
    int i = RecursiveMethod(1,3);
    //Console.ReadLine();
}

static int RecursiveMethod(int a, int b)
{
    Console.WriteLine(a);
    if (a == b)
    {
        return a;
    }
    else 
    {
        return a + RecursiveMethod(a + 1, b);
    }
}

让我们一步一步地了解调用
RecursiveMethod(1,3)时发生的事情

  • 代码进入else分支,因为a不等于b
  • 调用递归方法(2,3)
  • 代码再次进入else分支,因为a不等于b
  • 调用递归方法(3,3)
  • 如果条件满足,我们将第一次返回,返回
    3
  • 现在我们进入步骤2的else分支,因为
    RecursiveMethod(3,3)
    返回了。步骤2是这样的:
    return2+RecursiveMethod(3,3)
    因此它变成:
    2+3
    并返回
    5
  • 现在我们到了最后一次返回,我们在第1步,没有更多的内部返回了。步骤2返回
    5
    ,因此
    返回1+5
    =
    6
  • 通过每次递归调用,您可以更深一层。您必须在某个时候点击return,否则该方法将继续被调用,最终您将得到一个
    StackOverFlowException
    。这是因为每个方法都有一个堆栈,用于保存参数、局部变量和其他内容。当您继续调用函数时,所有这些值都会一次又一次地推送到堆栈中,每次调用都会耗尽堆栈空间


    您点击的return语句的数量应该等于您进行的递归调用的数量。不包括返回给调用者的最后一次返回。在上面的函数中,我们进行了两次递归调用,我们点击了两次返回,最后一次返回到
    Main
    i
    值来自递归本身的结果。
    第一次调用
    RecursiveMethod
    时,它将以两种不同的方式完成:

    1) 如果
    a==b

    2) 返回(递归)调用方法的结果
    RecursiveMethod

    在您的示例中,当使用
    (1,3)
    调用该方法时,它将在第二种情况下着陆,因此需要递归调用该方法的另一次迭代

    第二次迭代将执行相同的检查,但这次它将不会将
    (1,3)
    作为值,而是将
    (2,3)
    作为值

    结果将是最后的第三次迭代,其中结果将是
    3
    ,因为
    (3,3)
    参数将满足条件
    a==b

    最后,结果将是
    a(as 1)+a(as 2)+3(as递归结果)=1+2+3=6

    查看:查看如何在调试器中单步执行代码并查看值如何更改

    递归方法的关键在于它们总是有一些条件,在这些条件下它们返回一个实际值(而不调用它们自己)。在您的例子中,它是在
    a==b
    时出现的。递归部分是当它递增
    a
    然后再次调用自身时。因此,对该方法的第一个调用将等待第二个调用返回,第二个调用将等待第三个调用返回。在第三次调用中,我们满足了条件
    a==b
    ,因此返回一个值,然后堆栈“展开”

    也许这个图解说明了通过堆栈的流程(某种程度上)会有所帮助。为了避免混淆,我省略了主要逻辑(并在每个步骤中显示每个变量值),只包括调用的
    return
    部分:

    i = RecursiveMethod(1, 3);
        ┗► return 1 + RecursiveMethod(2, 3);
                      ┗► return 2 + RecursiveMethod(3, 3);
                                    ┗► return 3;
                         return 2 + 3 ◄┛
           return 1 + 5 ◄┛
    i = 6 ◄┛    
    

    请注意,此方法中存在一个致命缺陷,即它假定
    a
    小于或等于
    b
    。尝试使用
    a=3
    b=1
    调用该方法,它将递归调用自己,直到堆栈溢出,因为递增
    a
    将永远不会满足退出条件
    a==b

    我试图通过在伪代码中将递归显示为嵌套调用来可视化该过程:

    static int RecursiveMethod(int a(=1), int b(=3))
    {
        if (a == b) // FALSE
        {
            return a; // NOT EXECUTED
        }
        else 
        {
            return a(=1)                                                 // ==> RETURNS 1 + 5 = 6
                + RecursiveMethod(int a+1(=2), int b(=3))                                   ^
                  {                                                                         |
                      if (a == b) // FALSE                                                  |
                      {                                                                     |
                          return a; // NOT EXECUTED                                         |
                      }                                                                     |
                      else                                                                  |
                      {                                                                     |
                          return a(=2)                               // ==> RETURNS 2 + 3 = 5
                              + RecursiveMethod(int a+1(=3), int b(=3))                 ^
                                {                                                       |
                                    if (a == b) // TRUE                                 |
                                    {                                                   |
                                        return a;                        // ==> RETURNS 3
                                    }
                                    else 
                                    {
                                        return a + RecursiveMethod(a + 1, b); // NOT EXECUTED
                                    }
                                }                                           
                      }
                  }                                           
        }
    }
    

    首先,递归调用自上而下进入,直到递归停止,因为
    a==b
    ,然后结果冒出气泡

    递归方法中的
    return
    语句设置
    i
    ,这就是为什么方法的类型是
    int
    ,它返回一个整数,因此通过说
    inti=RecursiveMethod(1,3)
    意思是将
    i
    设置为从
    RecursiveMethod
    返回的值。尝试将i更改为其他类型,如string或double,您将得到一个编译器错误recursion@realdoctor可能我没有解释您的问题,递归方法将继续执行,直到达到条件a==b为止,此时,它将返回Main并将i设置为递归方法的值,在递归方法的else部分,它表示返回a的当前值加上另一次迭代(调用递归方法)返回的值,因此在第一次传递时,它将是1+递归方法的返回(2,3)对函数的递归调用也可以通过while循环来完成。@realdoctor在纸上写下递归每一层中所有变量的值。然后,编写一个简单的for循环,它执行与递归相同的操作。你会看到递归与简单循环非常相似,只是不容易看到发生了什么,在大多数情况下,使用递归比使用for循环更容易。你的递归函数中有一个bug。如果
    a
    大于
    b
    ,您将有无限递归,并且可能会得到
    StackOverflowException
    。感谢您在答案中添加额外的文本部分,这就是我试图通过while循环从答案中显示的内容,但我将其删除,因为人们似乎不理解