在JVM的運行時數(shù)據(jù)區(qū)包括:方法區(qū)、虛擬機(jī)棧螺垢、本地方法棧止剖、堆霞玄、程序計數(shù)器。而虛擬機(jī)棧描述的是JAVA方法執(zhí)行的內(nèi)存模型:每個方法在執(zhí)行的同時都會創(chuàng)建一個棧幀(Stack Frame),用于存儲局部變量表寒跳、操作數(shù)棧、動態(tài)鏈接、方法出口等信息拘领。
對于開頭提到的信息相信每個對JVM有了解的人都明白,但是剛看到棧幀中的操作數(shù)棧樱调,并不知道是做什么的约素?我不知道大家有沒有這樣的經(jīng)歷届良,知道有這么一個操作數(shù)棧,但是具體是做什么的圣猎,運行過程是什么樣兒的士葫,并不是很清楚
下面我們看兩個表達(dá)式
波蘭表達(dá)式法:標(biāo)準(zhǔn)四則運算表達(dá)式, 也稱 中綴表達(dá)式
就是我們從小學(xué)習(xí)的四則運算的表達(dá)式送悔。
例1:9+(3-1)*3+10/2 = ?
逆波蘭表達(dá)式法 - 后綴表達(dá)式
上述例1慢显,轉(zhuǎn)為后綴表達(dá)式為:9 3 1 - 3 * + 10 2 / +
我們在計算例1的中綴表達(dá)式時,我們可以計算出結(jié)果是20欠啤,但是這樣的描述荚藻,計算機(jī)無法實別,而計算機(jī)通過棧結(jié)構(gòu)+后綴表達(dá)式洁段,可以壓棧出棧应狱,得出表達(dá)式的結(jié)果。
操作數(shù)棧的執(zhí)行過程
數(shù)字入棧祠丝,操作符侦香,從棧中彈出操作數(shù),計算結(jié)果纽疟,結(jié)果入棧
第一步: 將后綴表達(dá)式從頭開始依次壓入棧
第二步:當(dāng)遇到操作符“-”時罐韩,從棧中彈出兩個操作數(shù),第一個彈出的作為減數(shù)污朽,第二個作為被減數(shù)散吵,進(jìn)行運算,計算出結(jié)果為2
第三步:將計算出的結(jié)果入棧:
第四步:將3壓入棧中
第五步:處理"*"
從棧中彈出3 作為乘數(shù) 彈出2作為被乘數(shù)蟆肆,并將結(jié)果6壓入棧中矾睦,結(jié)果如下圖
第六步:處理"+"
從棧中彈出6作為加數(shù)彈出9作為被加數(shù),計算 9+6=15炎功,將結(jié)果15入棧
第七步:10入棧枚冗,2 入棧
第八步:處理 "/"
彈出操作數(shù)2作為除數(shù),10作為被除數(shù)蛇损,10/2=5,將結(jié)果5入棧
第九步:處理"+"
彈出操作數(shù)5作為加數(shù)赁温,操作數(shù)15作為被加數(shù),15+5=20淤齐,20即為結(jié)果
上述是整個操作數(shù)棧的執(zhí)行過程股囊。
講到這里,大家應(yīng)該能明白JVM棧中的操作數(shù)棧的具體作用和執(zhí)行過程了更啄,但是有一個問題還沒有解決稚疹,中綴表達(dá)式是怎么轉(zhuǎn)換后后綴表達(dá)式?接下來我們看一下轉(zhuǎn)換過程祭务,其實在中綴轉(zhuǎn)后綴的過程中内狗,使用到的數(shù)據(jù)結(jié)構(gòu)也是棧怪嫌。
轉(zhuǎn)換規(guī)則
- 1、數(shù)字輸出
- 2柳沙、運算符進(jìn)棧
- 3喇勋、括號匹配出棧
- 4、如棧頂優(yōu)先級高偎行,則輸出后一位數(shù)字,再出棧操作符
轉(zhuǎn)換過程
為了方便讀者觀看贰拿,我們把要轉(zhuǎn)換的中綴表達(dá)式蛤袒,在這里再顯示一次,中綴表達(dá)式:9+(3-1)3+10/2
第1步:根據(jù)上面的規(guī)則膨更,數(shù)字9妙真、3、1荚守、輸出珍德,操作符+(-依次進(jìn)棧,可以得到矗漾,棧中的內(nèi)容如下圖:
第2步:這里需要注意一下锈候,因為規(guī)則中,擴(kuò)號匹配出棧敞贡,怎么理解呢泵琳,就是把左號到當(dāng)前棧頂?shù)姆栆来螐棾鰲#拥捷敵鼋Y(jié)果中誊役,
第3步:處理"",這里要注意一個获列,這個符合規(guī)則 的第4條,“”優(yōu)先級要比現(xiàn)棧頂符號優(yōu)先級高蛔垢,所以先輸出后面的數(shù)字3击孩,然后將*入棧,再依次將操作符出棧鹏漆。
第4步: "+ "入棧巩梢,輸出10
第5步:這時候和第三步情況一下,"/"優(yōu)先級高于棧頂操作符“+”艺玲,所以先輸出“/”后面的數(shù)字“2”且改,將"/"入棧, 依次將棧中操作符出棧板驳,并輸出