为什么在满足基本情况后继续调用此递归函数?

时间:2014-04-12 00:02:00

标签: c++ recursion

#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)语句并且函数应该结束。为什么不呢?

6 个答案:

答案 0 :(得分:4)

尝试使用缩进来跟踪调用。

  • 调用myFunction(4)
    • print&#34; hello4&#34;
    • 调用myFunction(3)
      • print&#34; hello3&#34;
      • 调用myFunction(2)
        • print&#34; hello2&#34;
        • 调用myFunction(1)
          • print&#34; hello1&#34;
          • 调用myFunction(0)
            • 返回
          • print 0x
          • 返回
        • print 1x
        • 返回
      • print 2x
      • 返回
    • print 3x
    • 返回

答案 1 :(得分:2)

令您困惑的输出:

hello1
0x

是由以下行引起的:

std::cout << "hello" << counter << std::endl;
myFunction(--counter); //function call
std::cout << counter<< "X" << std::endl;

counter1时,它:

  • 输出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)