所以我刚刚开始进行C ++编程,并且稍微停留在一个用于演示递归函数如何工作的特定程序上。我确实知道递归函数的前提,即在满足退出条件之前调用自身的函数。我理解了使用阶乘计划的概念,
int factorial(int n)
{
if (n==1)
{
return 1;
}
else
{
return n*factorial(n-1);
}
}
if语句是上述代码中的退出条件。
然而,绊倒我的代码来自这个链接: http://www.cprogramming.com/tutorial/lesson16.html
特别是这段代码:
#include <iostream>
using namespace std;
void printnum ( int begin )
{
cout<< begin<<endl;
if ( begin < 9 ) // The base case is when begin is greater than 9
{ // for it will not recurse after the if-statement
printnum ( begin + 1 );
}
cout<< begin<<endl; // Outputs the second begin, after the program has
// gone through and output
}
int main()
{
printnum(1);
return 0;
}
OP:
1
2
3
4
5
6
7
8
9
9
8
7
6
5
4
3
2
1
在上面的代码中,我理解输出直到第9个。但在那之后,为什么if循环后面的cout语句导致begin变量开始向后计数,直到它达到printvalue为时的最初值。第一个叫?我想我不太了解这里的退出条件。
不确定我错过了什么,并且非常感谢任何帮助。
感谢。
答案 0 :(得分:1)
每个begin
都是唯一的,属于“当前”活动函数 - 它的值永远不会改变。
递归函数的工作方式与其他函数完全相同;一个人的参数被命名为什么并不重要。
如果你有这些:
void f(int x);
void g(int x)
{
cout << x << endl;
f(x+1);
cout << x << endl;
}
如果g
打印了两个不同的数字,你会非常惊讶(我希望)。
您的递归与此(更小)的示例完全相同,该示例使用唯一函数而不是使用参数递归:
void printnum_3()
{
cout << 3 << endl;
cout << 3 << endl;
}
void printnum_2()
{
cout << 2 << endl;
printnum_3();
cout << 2 << endl;
}
void printnum_1()
{
cout << 1 << endl;
printnum_2();
cout << 1 << endl;
}
int main()
{
printnum_1();
}
答案 1 :(得分:0)
因此,让我们看看调用printnum(1)
时会发生什么。
begin
等于1
,打印时会显示cout
,然后调用printnum(2)
。
但是当程序离开printnum(2)
函数时会发生什么?它会从调用printnum(1)
的地方继续执行printnum(2)
。因此,下一行要执行的是cout << begin
。 begin
仍然等于1
,因为我们正在执行printnum(1)
函数。这就是为什么1
在最后再次打印的原因。其他函数调用的情况完全相同。
例如,当调用printnum(9)
时,会打印9
,然后if
检查失败(开始不小于9
),然后9
为再次打印。
答案 2 :(得分:0)
为什么if循环后面的cout语句会导致begin变量开始向后计数,直到达到printvalue首次调用时最初的值为止?
首先,无循环。有一个你需要了解的调用堆栈。当(begin < 9)
变为false
时,即begin = 9
时,递归调用会停止。您正在看到调用堆栈展开。
该函数中的第一个cout
是打印序列[1..9]
,第二个cout
正在打印递减序列[9..1]
。
您的代码执行方式如下:
cout<< 1 <<endl; //enter1
cout<< 2 <<endl; //enter2
cout<< 3 <<endl; //enter3
...
cout<< 8 <<endl; //enter8
cout<< 9 <<endl; //enter9
cout<< 9 <<endl; //exit9
cout<< 8 <<endl; //exit8
...
cout<< 3 <<endl; //exit3
cout<< 2 <<endl; //exit2
cout<< 1 <<endl; //exit1