文字解码完后,你能够想象有一条纸带,上面写着代码。从左侧向左拉动纸带,用剪刀将程序数据结构
纸带剪成纸片,在内存中依次摆放这些纸片,而后才能够执行内存中的这些纸片。函数
执行内存中代码的时侯,会用到一种名为堆栈(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。