堆棧指針總是指向棧頂位置。一般堆棧的棧底不能動,所以數據入棧前要先修改堆棧指針,使它指向新的空余空間然后再把數據存進去,出棧的時候相反。堆棧指針,隨時跟蹤棧頂地址,按“先進后出”的原則存取數據。
堆棧指針是什么
棧是一種特殊的線性表,是一種只允許在表的一端進行插入或刪除操作的線性表。表中允許進行插入、刪除操作的一端稱為棧頂。表的另一端稱為棧底。棧頂的當前位置是動態的,對棧頂當前位置的標記稱為棧頂指針。當棧中沒有數據元素時,稱之為空棧。棧的插入操作通常稱為進棧或入棧,棧的刪除操作通常稱為退棧或出棧。
計算機中的堆棧主要用來保存臨時數據,局部變量和中斷/調用子程序程序的返回地址。
堆棧指針是在棧操作過程中,有一個專門的棧指針(習慣上稱它為TOP),指出棧頂元素所在的位置。
堆棧指針總是指向棧頂元素。
堆棧可以使向下生長的(向低地址),也可以是向上生長的。
如果堆棧是向上生長的,數據入棧的時候,堆棧指針先加1,再壓棧。出棧的時候先彈出數據,堆棧指針再減1。如果堆棧是向下生長的,數據入棧時指針將減1,數據出棧時指針將加1。
堆棧指針有什么作用?
堆棧指針SP在片內RAM128B中開辟棧區,并隨時跟蹤棧頂地址。它是按“先進后出”的原則存取數據。開機復位后,單片機棧底地址為07H。
主要用來保存臨時數據,局部變量和中斷/ 自程序的返回地址。堆棧指針總是指向棧頂元素。所以數據入棧的時候,堆棧指針先加1,再壓棧。向上增長方式與計算機的方式一樣。
出棧的時候先彈出數據,堆棧指針再減1。
如果堆棧的實現是往上長的(就是說往頂的方向長,其實質是棧底是定死的不能動,入棧的東西只能不斷往上疊,這就像在書桌上放書一樣; 桌底是定死的,所以書只能一本一本地往上堆,往上長),計算機內部的堆棧的實現采取的就是這種模式,所以就得像你說的那樣,“先修改指針,然后插入數據,出棧時剛好相反“,因為堆棧指針指向的總是棧頂元素,棧底不能動,所以數據入棧前要先修改指針使它指向新的空余空間然后再把數據存進去,出棧的時候自然相反。
然而,如果堆棧的實現是往下長的(就是說每壓一個元素入棧,棧底就自動下移一個元素的位置,其實質就是這種堆棧模型是一個“無底洞”型),這個時候,棧頂就變成了定死的,就可以先壓入元素,然后再修改指針。因為棧底是無限的,壓入一個元素,新的元素就取代先前的棧頂元素占據棧頂的位置,那么先前的指向棧頂元素的指針這個時候就該修改讓它指向這個新的棧頂元素了。
下面的就是對“無底洞“型堆棧的一種實現的描述:
壓棧(入棧) :將對象或者數據壓入棧中,更新棧頂指針,使其指向最后入棧的對象或數據。
彈棧(出棧) :返回棧頂指向的對象或數據,并從棧中刪除該對象或數據,更新棧頂。
話說回來,計算機內部肯定選第一種模型,不會選第二種,因為第二種模型,每壓入一個新的元素,都需要把之前堆棧里的所有元素整體下移動一個元素的位置,騰出棧頂元素的位置讓新的元素進來,這種平移可是一筆不小的開銷啊! 但是 并不是說“無底洞”模型就沒辦法實現了,其實它可以通 過第一種模型來模擬的,每需要壓入一個新的元素的時候,就先開辟一個空間,數據存入這個空間,然后再修改棧頂元素指針使其指向這個新的棧頂元素。
這就意味著,如果使用的是鏈表的話,只要有足夠的空間可開辟出來作為一個節點,那么兩種堆棧模型都能實現(當然“無底洞“型還是如我上面說的那樣用第一種模擬出來的,否則平移的工作量相當可觀),如果用數組,由于數組在內存中是連續分配出來的空間,用第一種模型更自然一些。
評論
查看更多