#include <iostream>
void myFunction(int counter);
int main(){
myFunction(4);
}
void myFunction( int counter)
{
if(counter == 0)
return;
else
{
std::cout << "hello" << counter << std::endl;
myFunction(--counter); //function call
std::cout << counter<< "X" << std::endl;
return;
}
}
以下是输出结果:
hello4
hello3
hello2
hello1
0x
1x
2x
3x
在我看来,在打印“hello1”之后,计数器应该下降到0,因此应该满足if(counter == 0)语句并且函数应该结束。为什么不呢?
答案 0 :(得分:4)
尝试使用缩进来跟踪调用。
答案 1 :(得分:2)
令您困惑的输出:
hello1
0x
是由以下行引起的:
std::cout << "hello" << counter << std::endl;
myFunction(--counter); //function call
std::cout << counter<< "X" << std::endl;
当counter
为1
时,它:
hello1
myFunction(0)
0x
答案 2 :(得分:1)
以下是控制流程的工作原理。让我们简化一下这个功能,然后测试myFunction(1)
:
---myFunction(1)--
prints hello1
executes myFunction(0)
---myFunction(0)--
returns
prints 1X
returns
解决此问题的方法是return myFunction(--counter);
答案 3 :(得分:1)
当你调用一个递归函数时,它会为该函数创建一个堆栈帧,并继续为每个调用创建堆栈帧。
这些堆栈帧将存储每个调用的状态,直到它返回。
第一个调用将创建一个堆栈框架counter = 4
。然后它将递减计数器并再次调用该函数,创建一个新的堆栈帧,同时保留堆栈中的旧堆栈。这一直持续到达到基本情况。
一旦基本案例返回,那么基本案例的调用者将执行下一条指令(在导致基本情况的函数调用之后),即打印它已存储的counter
的值在它的堆栈框架中。打印后,它将返回,其调用者将打印它存储的值。
答案 4 :(得分:1)
它确实结束了。请记住,在递归结束时堆栈将展开。您在每个“循环”结束时进行std::cout << counter<< "X" << std::endl;
调用。这可能是你感到困惑的地方。您可以看到“Hello”在进入每个步骤时打印出来,然后在该步骤后打印出“x”。
查看上一次迭代的下一个。打印“hello1”,调用myfunction(0)
,打印“0x”然后返回。递归中的每一步都是这样做的。
答案 5 :(得分:1)
您的递归逻辑实际上正在运行。它的输出是坏的。它无法打印4x
的事实应该是一个暗示。
问题是,当你将计数器传递给递归调用并且然后打印它时,你会减少计数器。
尝试替换
myFunction(--counter)
带
myFunction(counter - 1)
你应该得到你期望的输出。
您可以通过使递归计数器成为const值来避免此类错误,这样您就不会在调用中意外修改它。
void myFunction(const int counter)