[英]How does the return keyword really work?
一個簡單的代碼片段計算下面的數字的階乘:
public class Main{
static int factorial(int number){
System.out.println("At factorial("+number+")");
if (number == 1){
return 1;
}
return number * factorial(number-1);
}
public static void main(String[] args){
System.out.println("factorial(4) = "+ factorial(4));
}
}
在這里,我認為當數字的值變為1(由於遞歸)時,它每次都返回1並退出方法並打印1。但是,它確實返回了正確的階乘值? 按照這個: Java - 返回值是否會破壞循環? ,不應該每次都返回1嗎? 這兩個代碼片段在返回值方面有何不同?
謝謝你
我試圖解釋整個過程; 參考這個來源。
在此之前,您應該對調用堆棧、遞歸和堆棧幀有基本的了解。
調用堆棧是程序用來存儲有關活動子例程的信息的數據結構。 使用調用堆棧的主要原因是程序可以跟蹤子例程在完成執行后應將控制返回到何處。
堆棧幀是調用堆棧的一部分,每次調用子程序時都會創建一個新的堆棧幀。 因此,在我們上面的遞歸factorial()
方法中,每次調用該方法時都會創建一個新的堆棧幀。 堆棧幀用於存儲一次例程調用的所有變量。 因此,請記住,調用堆棧基本上是堆棧幀的堆棧。
讓我們將過程分為 4 部分,因為選擇的數字是 4。
static int factorial(4){
if (4 == 1){
return 1;
}
return 4 * factorial(3);
}
static int factorial(3){
if (3 == 1){
return 1;
}
return 3 * factorial(2);
}
static int factorial(2){
if (2 == 1){
return 1;
}
return 2 * factorial(1);
}
static int factorial(1){
if (1 == 1){
return 1;
}
return 2 * factorial(number-1);
}
您可以看到第一個堆棧幀創建的數字等於 4。
然后調用factorial(3)
- 所以對factorial(4)
的第一次調用不會運行完成,因為在對factorial
第一次調用可以運行完成之前進行了另一個調用 ( factorial(3)
)。
其他人也是如此。
堆棧幀用於保存第一次調用factorial()
。 它存儲當前調用factorial()
的局部函數變量(和它們的值),它還存儲調用它的方法的返回地址(因為我們討論的是第一個非遞歸調用factorial()
,首先調用factorial()
任何例程都是 Factorial 在完成所有操作后將返回的地方)。
因為堆棧幀也存儲了返回地址,所以factorial()
函數在運行完成時知道返回到哪里
最后,在第4 個堆棧幀中,我們遇到了我們的基本情況,這意味着遞歸調用完成,然后控制權返回到第3 個堆棧幀,其中factorial(1) * 2
計算為2
,然后控制權為返回到第二個堆棧幀,其中factorial(2) * 3
計算為6
,然后控制返回到第一個堆棧幀,其中factorial(3) * 4
計算為24
。 最后,我們返回了24
的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.