文字解碼完後,你能夠想象有一條紙帶,上面寫着代碼。從左側向左拉動紙帶,用剪刀將程序數據結構
紙帶剪成紙片,在內存中依次擺放這些紙片,而後才能夠執行內存中的這些紙片。函數
執行內存中代碼的時侯,會用到一種名爲堆棧(stack)的數據結構(也就是數據的組織處理.net
方式)。堆棧像個容器,放東西與取東西都在同一端,越晚放進去的東西,越早被取出來(後blog
進先出)。用通俗一點的比喻:堆棧就像是停車場,越早停進去的車,會停在越裏面的位置,內存
要等到比它晚進的車都開走以後,才能開走。容器
爲何須要堆棧?由於程序在執行的過程當中,有時候須要把某些事暫時保留不作(由於條件不原理
成熟),等到後面的事作完才能回頭去作以前保留的事,這時候用堆棧是最適合的。程序
從下一頁開始連續有好幾個範例,你會看到這些範例在執行的過程當中堆棧如何變化,並且屏幕im
上的輸出如何變化。經過這些範例,你應該能夠理解解釋器的運行原理。
d3
對於abs -1 這段代碼來講,會被剪成兩個值:abs 與-1,而後開始執行。
在狀態A,堆棧與屏幕都是空的。而後把abs 放進堆棧中,abs 是求絕對值的函數,它後面
須要跟着一個數字,但堆棧中目前只有abs 本身,因此執行不了,這是狀態B。
到了狀態C,-1 也被放進堆棧。有了這一個參數,abs 終於能夠計算了,計算方式是把這兩
個值都從堆棧中取出,計算以後獲得的值是1,再把1 放回堆棧,如今是狀態D。
內存中的代碼已經執行完畢,堆棧中也沒有任何進一步的計算要進行,這表示程序要結束了。
結束時,堆棧中剩下的1 就是返回值。因此在狀態E 中,咱們看到堆棧被清空,但屏幕上出
現== 1。
對於power 2 6 這段代碼來講,會被剪成power、二、6 這三個值,而後開始執行。
在狀態A,堆棧與屏幕都是空的。而後把power 放進堆棧中,成爲狀態B。power 是求冪的
函數,它後面須要跟着兩個數字,分別是底數與指數,因此目前計算不了。狀態C,把2 放進
堆棧,依然沒法執行。
狀態D,把6 放進堆棧,如今power 的兩個參數都到齊了,能夠計算了。方式是把三個值都
取出來計算,結果獲得64,再把結果放回堆棧,進入狀態E。
內存中的代碼已經執行完畢,堆棧中也沒有任何進一步的計算要進行。這表示程序要結束了。
結束時,堆棧中剩下的64 就是返回值。因此在狀態F 中,咱們看到堆棧被清空,但屏幕上出
現== 64。
對於print add 3 -4 這段代碼來講,會被剪成print、add、三、-4 這四個值,而後
解釋其原理
開始執行。
先把print 放進堆棧,進入狀態A。print 須要一個參數,因此此時沒法計算。再把add 放
進堆棧,進入狀態B。add 如今沒法當作print 的參數,由於add 本身就是一個函數,必須
等add 計算完畢的值才能當print 參數。add 須要兩個參數。
3 與-4 被依次放進堆棧,進入狀態C。這個時候,add 的兩個參數已經到齊,能夠計算了。
把這三個值取出來,計算以後獲得結果-1,把-1 放回堆棧,如今是狀態D。
這個時候,print 須要的參數(-1)已經出現了,取出這兩個值,計算(執行)的結果是屏
幕上出現-1。print 是沒有返回值的。沒有返回值也就是說返回值是一個特殊值unset(未
設)。把unset 放進堆棧中。如今狀態是E。
內存中的代碼已經執行完畢,堆棧中也沒有任何進一步的計算要進行。這表示程序要結束了。
結束時,堆棧中剩下的特殊值unset 就是返回值,返回值爲特殊值unset 至關於沒有返回值。
因此在狀態F 中,咱們看到堆棧被清空,屏幕中沒有出現==。
對於power 2 6 abs add 3 -4 這段代碼來講,會被剪成power、二、六、abs、add、三、
-4 這7 個值,而後開始執行。
把power、二、6 依次放進堆棧,進入狀態A。終於能夠計算了,計算以後進入狀態B。堆棧
中已經沒有任何進一步的計算要進行,但內存中還有後續的代碼,因此還沒有結束。
把內存中的abs、add、三、-4 依次放進堆棧,進入狀態C。終於能夠計算了,取出最上面的
三個值,計算以後把結果-1 放回堆棧,進入狀態D。狀態D 也能夠計算,取出兩個值,計算
結果1 放回堆棧,進入狀態E。
內存中的代碼已經執行完畢,堆棧中也沒有任何進一步的計算要進行。這表示程序要結束了。
結束時,堆棧中如有多個值,最上層的值就是返回值。因此在狀態F 中,咱們看到堆棧被清空,
屏幕中出現== 1,而64 直接被扔了。
這個例子其實有兩個段落,因此最後堆棧會有兩個值。段落之間彼此獨立,所以寫代碼時,我
們喜歡讓段落之間換行,能夠幫助閱讀理解。
每次發生計算,其實就是找到一個段落。堆棧最後的值分別由power 與abs 產生,因此它們
兩個就是段落的起點。
既然每次發生計算就是一個段落,那麼add 應該也是段落的起點。但由於add 只是abs 的一
部分(也就是說它是abs 段落的子段落),並且add 沒有兄弟段落(power 與abs 在這裏就
是兄弟關係,是平級的),再說abs 太簡單,讓abs 和add 擺一塊兒比較好。把add 段落拆出
去沒有太大必要。
最後一個例子。對於power 26 print add 3 -4 這段代碼來講,這個例子和前一個例子
差很少,只是abs 換成了print。這致使狀態E 的堆棧中有兩個值,而最上面的值是特殊值
unset。