在JVM的运行时数据区包括:方法区、虚拟机栈、本地方法栈、堆、程序计数器。而虚拟机栈描述的是JAVA方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
对于开头提到的信息相信每个对JVM有了解的人都明白,但是刚看到栈帧中的操作数栈,并不知道是做什么的?我不知道大家有没有这样的经历,知道有这么一个操作数栈,但是具体是做什么的,运行过程是什么样儿的,并不是很清楚
下面我们看两个表达式
波兰表达式法:标准四则运算表达式, 也称 中缀表达式
就是我们从小学习的四则运算的表达式。
例1:9+(3-1)*3+10/2 = ?
逆波兰表达式法 - 后缀表达式
上述例1,转为后缀表达式为:9 3 1 - 3 * + 10 2 / +
我们在计算例1的中缀表达式时,我们可以计算出结果是20,但是这样的描述,计算机无法实别,而计算机通过栈结构+后缀表达式,可以压栈出栈,得出表达式的结果。
操作数栈的执行过程
数字入栈,操作符,从栈中弹出操作数,计算结果,结果入栈
第一步: 将后缀表达式从头开始依次压入栈
第二步:当遇到操作符“-”时,从栈中弹出两个操作数,第一个弹出的作为减数,第二个作为被减数,进行运算,计算出结果为2
第三步:将计算出的结果入栈:
第四步:将3压入栈中
第五步:处理”*”
从栈中弹出3 作为乘数 弹出2作为被乘数,并将结果6压入栈中,结果如下图
第六步:处理”+”
从栈中弹出6作为加数弹出9作为被加数,计算 9+6=15,将结果15入栈
第七步:10入栈,2 入栈
第八步:处理 “/“
弹出操作数2作为除数,10作为被除数,10/2=5,将结果5入栈
第九步:处理”+”
弹出操作数5作为加数,操作数15作为被加数,15+5=20,20即为结果
上述是整个操作数栈的执行过程。
讲到这里,大家应该能明白JVM栈中的操作数栈的具体作用和执行过程了,但是有一个问题还没有解决,中缀表达式是怎么转换后后缀表达式?接下来我们看一下转换过程,其实在中缀转后缀的过程中,使用到的数据结构也是栈。
转换规则
- 1、数字输出
- 2、运算符进栈
- 3、括号匹配出栈
- 4、如栈顶优先级高,则输出后一位数字,再出栈操作符
转换过程
为了方便读者观看,我们把要转换的中缀表达式,在这里再显示一次,中缀表达式:9+(3-1)3+10/2
第1步:根据上面的规则,数字9、3、1、输出,操作符+(-依次进栈,可以得到,栈中的内容如下图:
第2步:这里需要注意一下,因为规则中,扩号匹配出栈,怎么理解呢,就是把左号到当前栈顶的符号依次弹出栈,加到输出结果中,
第3步:处理”“,这里要注意一个,这个符合规则 的第4条,“”优先级要比现栈顶符号优先级高,所以先输出后面的数字3,然后将*入栈,再依次将操作符出栈。
第4步: “+ “入栈,输出10
第5步:这时候和第三步情况一下,”/“优先级高于栈顶操作符“+”,所以先输出“/”后面的数字“2”,将”/“入栈, 依次将栈中操作符出栈,并输出
最终结果就是我们所需要的后缀表达式: