递归示例中的混淆

Confusion in Recursion example

本文关键字:递归      更新时间:2023-10-16

我的讲义中有一个递归的例子

void print(int n)
{
    if (n<1) {return;}
    print(n-1);
    cout<<n;
}

我尝试在 DEV C++ 中实现此代码,在调试模式下,我发现打印函数一次又一次地调用自己,直到n=0。然后它转到cout<<n并开始在n中增加并显示输出1 2 3 4 5我不明白为什么它显示此输出,在我看来,它应该只在输出中显示0

程序的执行(从上到下):

print (5)
    if (5<1) {return;} // <-- False; going on
    print (5-1) // print (4)
        if (4<1) {return;} // <-- False; going on
        print (4-1) // print (3)
            if (3<1) {return;} // <-- False; going on
            print (3-1) // print (2)
                if (2<1) {return;} // <-- False; going on
                print (2-1) // print (1)
                    if (1<1) {return;} // <-- False; going on
                    print (1-1) // print (0)
                        if (0<1) {return;} // <-- True; returning
                    cout << 1;
                cout << 2;
            cout << 3;
        cout << 4;
    cout << 5;

这很简单。它正在展开堆栈并打印存储在堆栈上的n的本地副本。让我们一步一步来做:打印(3);- 3 不小于 1,因此此函数不返回- 然后在下一行中,此函数调用自身,但参数递减那么会发生什么呢?下一个堆栈帧是用 n-1 值创建的,该值被复制,然后故事是相同的,它调用 print 直到 n = 0;每次复制N!因此,在本地n值上具有以下堆栈:
1 <--下一个调用是 print(0),它返回不执行任何操作
阿拉伯数字
3 <--我们从这里开始

因此,然后堆栈被展开:在打印(n-1)后进入下一行,在顶部帧中n == 1,然后当下一个堆栈帧展开并且本地n副本== 2,然后是3,发送到cout的内容。

现在清楚了吗?

每次调用print()局部变量(如 n)的当前值都会与调用它的函数中的位置一起存储在堆栈(调用堆栈)上。

然后,当您从函数返回时,将从调用堆栈中检索以前的局部变量,并在调用函数后立即返回到函数的位置。直到你return你叫多少次。

因此,当您调用print()时,n的值会下降,因为每次您调用print()并将n - 1设置为新参数n时,这些值都会被存储,直到您最终到达return;并且这些值开始以与它们放置在那里相反的顺序调用堆栈中弹出,直到您返回与您调用的次数一样多。