概念:乙個函式裡的最後乙個動作是乙個函式呼叫的情形
lua例:
function
func1
(x)do
return
func2
(x)end
也就是說,是這個呼叫的返回值直接被當前函式返回的情形。
為什麼這種情況要單獨拿出來定義,首先要明確函式呼叫棧的概念。
呼叫棧在程式的記憶體空間中,有一塊專門的區域被用來記錄正在呼叫的函式的情況,這塊區域就是函式呼叫棧。
每次呼叫乙個新的函式時,就會在呼叫棧頂進行乙個壓棧操作;函式執行完畢時,會執行彈棧操作,清除被呼叫函式的資源。
尾遞迴尾呼叫的函式是當前函式自身,這種情況被成為尾遞迴。
如果在函式內呼叫函式的話,就會導致不斷壓棧而沒有彈棧的情況,其結果是消耗大量記憶體並且有撐爆函式呼叫棧空間的風險,尤其是遞迴的情況下。
但尾呼叫有所不同,普通函式內呼叫函式,因為後續還有要執行的語句,所以無法優化。而尾呼叫由於是函式的最後一條語句,優化是可以實現的,尤其是尾遞迴的情況下,優化可以提高不少效率。
主要目的:使程式設計師可以使用遞迴代替迴圈且不損失效能。
呼叫棧執行機制:呼叫棧在將乙個函式壓棧時,會記住他的返回位置,當乙個函式呼叫結束時,他的返回值會被放到棧中所記錄的返回位置上。舉例來說,函式a在第三條語句時呼叫函式b,那麼函式b被壓棧,它的返回位置就是函式a呼叫它的地方,當函式b執行結束,它的返回值就會被放到a呼叫函式b的位置,之後再執行下面的語句。
消除實現:對於尾呼叫而言,被調函式的位置可以不用記錄在呼叫棧中。用上述例子模擬,如果a在return
語句呼叫函式b,那麼b的呼叫和返回位置就是a的返回位置。所以尾呼叫消除就是在不改變當前呼叫棧的呼叫情況下,直接跳轉進入另乙個函式的呼叫,並且該函式的返回位置就是呼叫該函式函式的返回位置。這樣一來,就省下了一次壓棧和一次彈棧的消耗。
尾呼叫尾遞迴及其優化(筆記)
尾呼叫 尾呼叫 tail call 是函式式程式設計的乙個重要概念,本身非常簡單,即指某個函式的最後一步呼叫另乙個函式。function f x 上述 中,函式的最後一步是呼叫函式g,這就叫尾呼叫。以下三種情況,都不屬於尾呼叫。function f x function f x function f...
尾呼叫 尾遞迴
首先什麼是尾呼叫呢?我的理解是在,函式的最後呼叫乙個函式,並不包含該函式的任何變數。如 def f n return g n 複製 這個就是尾呼叫,尾呼叫的乙個好處就是,不用生成呼叫棧,因為假設是個尾呼叫,那麼當我執行到函式末尾的時候,這個函式相關的資訊我都可以不用保留了,因此不會出現棧溢位的問題。...
尾呼叫和尾遞迴
造成這樣的結果是因為每個函式在呼叫另乙個函式的時候,沒有return該呼叫,所以執行引擎會認為你還沒有呼叫完畢,會保留呼叫幀。而如果使用尾呼叫優化,呼叫幀就永遠只有一條,這個時候就會節省很大一部分的記憶體空間,維護了 執行的流暢性。以上 就叫做尾呼叫優化,這個時候呼叫幀就永遠只有一條,節省了部分記憶...