編譯器

對上方函式最後的遞迴呼叫進行尾端呼叫最佳化,會有什麼效果?

int fact(int n, int acc) {
    if (n <= 1) return acc;
    return fact(n - 1, acc * n);
}
  1. A遞迴的次數減半,計算結果也快2倍求得
  2. B函式被行內展開,遞迴本身被替換成常數
  3. C呼叫被替換成分支(跳躍),即使遞迴很深堆疊也不會增加
查看答案與解析

正確答案:C. 呼叫被替換成分支(跳躍),即使遞迴很深堆疊也不會增加

這個函式的遞迴呼叫是函式的最後一項處理,並且直接回傳其結果(尾端呼叫)。由於呼叫之後沒有剩餘的處理,因此可以轉換成重複使用目前函式的堆疊框,改寫引數後跳躍到函式開頭的形式。這樣就與迴圈有相同的作用,無論遞迴多深堆疊都不會增加,也不必擔心溢位。遞迴的次數不會改變,而且 n 是在執行時才決定的,所以不能替換成常數。

  • A. 重複的次數不會改變。
  • B. n 是在執行時才決定的,所以不能替換成常數。
  • C. 正確。被替換成跳躍,堆疊不會增加。
練習這個領域 前往領域頁面

編譯器的其他題目

  1. 關於編譯器與直譯器的差異,下列何者正確?
  2. 關於使用JIT編譯的執行環境之特徵,下列何者正確?
  3. 關於LLVM的基本架構,下列何者正確?
  4. 在指定編譯器最佳化等級的選項中,不進行最佳化的設定(-O0等)經常用於下列哪種情況?
  5. 關於使用剖析資料的最佳化(PGO)的說明,下列何者正確?

這個領域的比較