跳轉到內容

程式設計基礎:棧幀

來自華夏公益教科書,開放的書籍,面向開放的世界

試卷 1 - ⇑ 程式設計基礎 ⇑

← 全域性變數和區域性變數 棧幀 遞迴 →


我們之前討論過 使用函式和子程式在程式設計中的好處,但由於每個函式都獨立儲存,計算機需要能夠儲存它當前正在處理的內容(包括其變數和引數)並將其放在一邊,以便它可以轉到新函式,然後能夠返回到它所在的位置。這就是棧幀的用途。

考慮以下程式

Sub Main
    openFile("birthday_picture.png")
    Console.WriteLine("Finished opening file... goodbye!")
End Sub

Sub openFile(fileName as String)
    If fileExists(fileName) Then
        ' code to open file goes here!
    Else
        Console.WriteLine("The file called {0} doesn't exist!", fileName)
    End If
End Sub

Function fileExists(fileNameToCheck as String) as Boolean
    Dim filePath as String
    filePath = "C:\\Users\\My Pictures\\" + fileNameToCheck
    ' code to check if filePath exists and return True if it does, or False if it doesn't
End Sub

該程式嘗試透過呼叫 openFile 子程式來開啟一個檔案(名為 birthday_picture.png)。該子程式呼叫一個函式來確保檔案存在,並根據其返回的布林值(True 或 False),子程式將繼續開啟檔案或列印錯誤訊息。當檔案被開啟(或者在檔案不存在的情況下,列印錯誤訊息)時,程式會在結束前寫入一條訊息。

要理解為什麼需要棧幀,請考慮程式開始執行的第一個子程式:Main。程式開始執行後,它會檢視第一行指令並轉到 openFile 子程式。但是,計算機需要記住在完成 openFile 後返回到 Main,否則它永遠無法列印告別訊息!類似地,如果我們檢視 openFile,它有一個對 fileExists 的呼叫,但是計算機也需要知道返回到 openFile,並且在 openFile 內的正確位置,否則它可能會嘗試開啟一個不存在的檔案!

計算機跟蹤所有這些資訊的方式是每次它被呼叫到另一個子程式或函式時建立一個棧幀。在這個棧幀中,它儲存

  • 返回地址;這是它在完成呼叫後應該返回的點
  • 區域性變數;這些是當前子程式/函式中應該恢復的變數
  • 引數;傳遞給函式/子程式的資料

一個圖表可以幫助你形象地理解這個過程

棧幀文章中程式執行期間棧幀的描述。

當計算機遇到函式或子程式呼叫時,它會將區域性變數、引數和當前地址儲存在記憶體中,並將其新增到棧中。完成呼叫後,它會從棧中刪除該幀,並檢視下一幀的返回地址(該地址將屬於呼叫它的函式),然後從該點繼續執行。這個過程一直持續到棧為空(即它返回到程式中的第一個子程式)並且程式結束。

華夏公益教科書