簡體   English   中英

簡單的遞歸函數未提供預期的輸出

[英]Simple recursive function not giving expected output

抱歉,如果我做錯了,我對C真的很陌生,之前沒有使用過堆棧溢出。 我試圖用手跟蹤此簡單的遞歸函數,但從編譯的代碼中得到了不同的答案。

我的思考過程是

打印2 | n = 2-1 = 1 | 1> = 0 | 倒數(1)

打印1 | n = 1-1 = 0 | 0> = 0 | 倒計時(0)

打印0 | n = 0-1 = -1 | -1不是> = 0 |

打印-1 | 結束

void countdown(int n)
{
    printf ("n = %d\t", n);
    n--;
    if (n >= 0)
    {
        countdown(n);
    }
    printf ("n = %d\t", n);
}

int main ( )
{
    countdown(2);
    return 0;
}

我期望得到:n = 2 n = 1 n = 0 n = -1

但是編譯后的代碼給了我:n = 2 n = 1 n = 0 n = -1 n = 0 n = 1

我不確定-1之后的0和1來自何處

您的代碼執行以下操作(省略if):

countdown(n):
     print(n)
       countdown(n-1)
     print(n-1)

對於n = 2:

countdown(2):
     print(2)
       countdown(1)
     print(1)

-> next recursion step
     print(2)
       print(1)
         countdown(0)
       print(0)
     print(1)

-> next recursion step
     print(2)
       print(1)
         print(0)
         print(-1)
       print(0)
     print(1)

您的代碼沒有問題。 只需刪除第二個printf代碼。

void countdown(int n)
{
    printf("n = %d\t", n);
    n--;
    if (n >= 0)
        countdown(n);
}

int main()
{
    countdown(2);
    return 0;
}

結果是:

n = 2 n = 1 n = 0

這是我在2nd printf捕獲時的調用堆棧。

StudyCpp.exe!countdown(int n) line 16   C++  // It is 2nd printf of countdown(0). Now, n is -1. 
StudyCpp.exe!countdown(int n) line 14   C++  // It called countdown(0)
StudyCpp.exe!countdown(int n) line 14   C++  // It called countdown(1)
StudyCpp.exe!main() line 21 C++   // It called countdown(2)

如果再進行一次調試,則可以看到如下所示的調用棧:

StudyCpp.exe!countdown(int n) line 16   C++  // It is 2nd printf of countdown(1) after executed countdown(0).
StudyCpp.exe!countdown(int n) line 14   C++  // It called countdown(1)
StudyCpp.exe!main() line 21 C++   // It called countdown(2)

並且,如果您進一步進行調試,則可以看到如下所示的調用棧:

StudyCpp.exe!countdown(int n) line 16   C++  // It is 2nd printf of countdown(2) after executed countdown(1).
StudyCpp.exe!main() line 21 C++   // It called countdown(2)

最后,程序將退出。

在這里,您遞歸調用countdown(),被稱為三次。
實際上,每個遞歸調用都會將countdown()推入堆棧。

SF1(Bottom of stack) ---> SF2 ---> SF3 (Top of stack). 

現在將執行頂部的框架。
從函數返回期間,將彈出特定的堆棧框架。
現在,堆棧幀指針指向SF2,然后指向SF1。

考慮您的程序,以下是流程。
推送操作:
SF1將首先被推入堆棧

n = 2 printed.  
Again n updated to 1

SF2推送:

n = 1 got printed.  
Again n updated to 0

SF3推送:

n = 0 got printed.  
Again n updated to -1.  
But n <= 0, So if check fails.  

彈出操作:
現在,SF3首先從堆棧中彈出。

n = -1 printed  

然后SF2彈出

prints n = 0.

最后SF1

n = 1 printed

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM