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)
3
RecursiveMethod(3,3)
返回了。步骤2是这样的:return2+RecursiveMethod(3,3)
因此它变成:2+3
并返回5
5
,因此返回1+5
=6
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循环从答案中显示的内容,但我将其删除,因为人们似乎不理解