編譯器
對上方函式最後的遞迴呼叫進行尾端呼叫最佳化,會有什麼效果?
int fact(int n, int acc) {
if (n <= 1) return acc;
return fact(n - 1, acc * n);
}
- A遞迴的次數減半,計算結果也快2倍求得
- B函式被行內展開,遞迴本身被替換成常數
- C呼叫被替換成分支(跳躍),即使遞迴很深堆疊也不會增加
查看答案與解析
正確答案:C. 呼叫被替換成分支(跳躍),即使遞迴很深堆疊也不會增加
這個函式的遞迴呼叫是函式的最後一項處理,並且直接回傳其結果(尾端呼叫)。由於呼叫之後沒有剩餘的處理,因此可以轉換成重複使用目前函式的堆疊框,改寫引數後跳躍到函式開頭的形式。這樣就與迴圈有相同的作用,無論遞迴多深堆疊都不會增加,也不必擔心溢位。遞迴的次數不會改變,而且 n 是在執行時才決定的,所以不能替換成常數。
- A. 重複的次數不會改變。
- B. n 是在執行時才決定的,所以不能替換成常數。
- C. 正確。被替換成跳躍,堆疊不會增加。