[英]difficulty in understanding successive recursive calls
我試圖理解以下程序,其中存在連續的遞歸函數調用,但在跟蹤如何加載大頭針時感到困惑。
void func(char*); // function prototype
int main(){
func("123");
return 0;
}
void func(char a[]){
if(a[1]=='\0')
return;
func(a+1);
func(a+1);
printf("%c",a[1]);
}
輸出為 3 3 2
如果有人可以就此提出建議,將不勝感激...
這種多次遞歸調用是否以任何方式有益或在特定問題領域找到應用..?
只需將自己置於 CPU 的位置並逐行執行(或使用調試器來幫助完成該任務)。
第一個電話是
func("123")
此調用不滿足終止條件a[1] == '\\0'
,因此它調用
func("23");
對 func("23") 的調用依次調用
func("3")
滿足返回條件。 因此,該調用返回到前一個調用方 func("23")。
由於這些行,func("23") 繼續對 func("3") 進行另一個調用
func(a+1);
func(a+1);
在你的腦海中繼續這個執行程序的過程,並寫下每次調用printf
會發生什么。 這將解釋您的輸出。
更新
請注意,對 printf() 的調用發生在遞歸調用之后,例如調用
功能(“123”)
會像
發布的代碼是一個設計相當糟糕的遞歸實例。
以下代碼具有正確的遞歸“尾部”形式。
通過將反轉的字符串傳回 main 並讓 main 打印它,它可以做得更好。
它顛倒了 main() 傳遞給 func() 的字符串的順序
請在詢問運行時問題時,發布編譯代碼,包括頭文件所需的 #includes,這樣我們就不會猜測要包含哪些頭文件
#include <stdio.h>
void func(char*); // function prototype
int main(){
func("123");
return 0;
}
void func(char a[])
{
if(a[1]=='\0') // check for end of recursive sequence
{
printf( "%c", a[0] ); // last tail action
return;
}
func(a+1); // step+next recursion
printf( "%c", a[0] ); // tail action
return;
}
使用斷點調試是理解遞歸的一種方式。 另一種方法是繪制遞歸調用樹。
從圖中可以看出,在level0之后的每一層中,由於這兩行代碼,printf語句出現在每兩個節點之后:
func(a+1);
func(a+1);
一般來說,對於任何長度大於 0 的輸入字符串,這都會變成一個完美的二叉樹。 節點總數由以下公式給出:
2^(k+1) - 1 // k is the depth; here k = 2
執行的printf語句總數可以通過這個公式得到:
2^k - 1 // For k=2, there will be 3 printf statements each printing 3,3,2 respectively
遞歸可以簡單理解如下。
例如:
Func(int a){
while(a>1)
return a * func(a-1);
}
假設a = 5
。
發生的情況是它返回5 * func(4)
。
現在func(4)
返回4 * func(3)
並且它繼續這樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.