00:00
嗯,那咱们讲到这个算术运算符这块啊,咱们就讲两个有意思的这个题目,嗯,大家在学习Java语言的时候呢,肯定接触过这个叫前加加后加加,对吧,这个我们通常称为呢叫自增一,那这块呢,主要区别呢,就是关于我们到底是先加加跟后加加,这个区别到底在哪儿,那从我们自检码角度呢,该如何去理解,乃至于说呢,有一个这样的一个问题。不知道是不是所有同学都写过这样的代码,但是呢,并不是所有人都能把这个事儿呢解释清楚,那我们来看一下这个关于加加的这个问题,佳佳呢,说清楚之后呢,减减也类似,好,首先呢,我们看一下这个METHOD6。来咱们把这个MAC6这个资金码呢,咱们打开现在的话呢,咱们基于讲的这个指令,咱们就能看得懂了。行,那我们来分析一下,这里边这个指令的一个情况,还是咱们画这个简图,这呢是这个局部变量表,这个呢是咱们说的操作数站,嗯,我就这块呢,为了方便起见,提前呢就画几个索引了啊,当然了,这个到底能到三能到四,那看你具体有问题有几个,嗯。
01:03
就变量了对吧,首先呢,第一个位置呢,这个是个Z次,毫无疑问,这我就写这了,这块放在那个这次的一个地址值嘛,对吧。然后的话呢,我们上来就有一个BI push10,把这个十呢放到这个操作数站当中,下边的S到一,把这个十呢放到我们这个位置,就写到这儿了,这其实就是我们这个变量I对应的这个值,这个就没有了,对吧?再接下来的话呢,我们叫I increase increase1BY1,这个一的话呢,就是我们这个角标一,然后拜一呢,就通过一,那十加个一,那就变成11了呗。这就变成11了。好,这个变成11之后呢,这个就return就返回了,那返回的话呢,这个咱们这个操作return啊,这个呃,这块有return,其实这块呢,是一个word的一个表示,那就结束了,所以这时候呢,就是11对吧,这时候咱们用的是这个叫前加加,我现在把这个做一个。截图盯一下,现在呢,我把它呢打开,把这个呢给它关掉,我们把它重新再做一个编译。
02:02
编译完以后呢,我直接在这做个刷新就行。好,大家会发现我们现在这两个是不是完全一样啊。你看没有任何变化对吧,也就是说呢,我们如果不涉及到其他的运算,比如说像下边呢,我们把这个结果呢,又重新复制给一个新的变量了,如果不涉及到这样的运算的话呢,我们说这个先加加呀,后加加呀,从次解码的角度来讲,是没有任何变化的。以前呢,有的同学纠结过这样的问题,说一下老师为什么我们写int一个呃,勾等于零,然后呢,这个勾小于比如说十。然后这块呢,我们写一个这个勾加加是吧,那为什么我这块写勾加加,写加加勾行不行呢?那我说行,但是当时呢,有同学说老师你说行这就行吗?怎么去理解呀,那现在呢,大家是不是就清楚了,我们这块呢,写先加加还是后加加,从效率上来讲没有任何区别,因为它俩的最解码指令呢,也是完全一样的。啊,这个清楚好,那下边呢,咱们来看一下这个不一样的,那就涉及到呢,跟这个其他的这个运算符呢,合在一起做运算的时候的这个场景,咱们看下这个METHOD7这个code。
03:08
行开始了,首先呢,我们也是画一个,这是局部变量表,这呢是操作数占方便,期间呢,还是把这个提前一些索引呢,咱们给它先列一列。行,那我们来分析。首先呢,这个零的位置呢,还是这个Z,这不多说了,然后接下来我们上来,呃,咱看这啊,这个BF是十那块整个十,然后S到一,那把这个十呢就存到这儿,这其实就是我们这个变量I。没问题,然后这个呢就没有了,再接着呢,叫I load1,把我们这个十呢再放回来,放到这儿行,放到这了I load一行,然后I increase啊increase或者REMENT1BY1,从这个角标一前面这一呢是这个角标一,让它的这个值呢加个一,那就变成11了呗。好变成11,接下来呢,再从我们这个操作数站当中,嗯,你把这个数据呢,叫S到二,把这个数据呢,再保存到我们这个二的位置,那这个是十嘛,这个位置谁呢?这个位置不就我们这个变量A吧,所以呢,你看这时候我们看到I呢是11了,A呢是不是还是十啊。
04:13
这个就是我们通常所说的叫后加加嘛,后加加的话呢,是先赋值叫十,然后这个I呢,再次增一,其实从自解码角度来讲是这样的一个效果。OK,再看下边啊,BF是20啊,当然这个你到过来之后呢,这就没有了,这个BF就是BF是20,那这块有个20。S到三,那把这20呢,就放到这块。那这个对应的是我们这个叫勾是吧,口角肌啊,把这个就删掉了。在接下来的话呢,我们叫I increase310,把这个角标三的这个位置呢,我们从20呢变成加个一,那就变成21了。变二一了,再接着呢,I load的三,把我们这个局部变量表里边索引为三的这个数据呢,再给咱们加载到这个操作站当中,那就是21 21过来了,到这儿了,然后S到四,把这21呢再写回去,那就放到这个角标四的位置,21这个呢,对应的是这个B。
05:09
完了对吧,这个也就没有了,然后这时候我们再看这个接啊,这个接的话呢,因为加加过先加加的,所以变成21了,而这B呢,也是21。行,那从字节码的角度是不是就分析的很清楚了。OK对吧,行,那这个理解以后呢,咱们下边看一个比较有意思的问题。这个刚学习的时候呢,有的同学可能写过这样的代码,然后写完以后呢,觉得不可思议,为什么是这样的情况呢,对吧?这个呢,你看我们定一个I是十,I加加呢,咱都知道这个结果一定是11,但是现在呢,我们把I加加前面又写了个I的一个负值情况,这个结果呢。这个应该都知道,这个结果是十。你看我这加一个这个单元测试方法,我们在这呢跑一下。对吧,这个结果是实没有问题,行,那下边呢,就咱们来解释一下,就很多同学呢,嗯,我在讲课的时候呢,有同学问我这个问题,由于呢,咱们没怎么讲过这个资金码文件,就是在一开始讲课的时候,所以呢,就很多同学这块呢,呃,不太好给大家解释,只能说呢有个临时变量,那其实所谓的临时变量就是我们这里边提到这个操作数占的这个概念。
06:17
那现在呢,大家你看这个结果就应该非常清楚了,你也可以拿着这个呢,是不是可以去虐别人了,就那我们看看怎么去虐他啊。首先还是局部变量表。操作时候占。这个BI还是咱们这个老一套啊。这个零位置是个Z对吧,那BI push10,然后这个位置放个十,然后S到一存到这个位置,这就是十,这个是定义变量叫I,没问题,然后这个十就干掉了。接下来呢,就挨的一把这个十呢又拿过来放到这儿。说I increase一带一,然后这个位置就变成11了嘛。注意这个位置已经变成11了,相当于我们这个I加加操作,它是变过这个11的,注意这是写成11了,那这个就完事了,接下来呢叫S到一,注意这块操作非常的关键,S到一是我们把操作时站当中这个数据啊给它在保存,在角标为一的位置,那个十相当于拿过来角V1的位置,注意又把这个11改成十了。
07:19
又改成十了,这就是我们最核心的这个问题,相当于呢,我们这个I加加过之后,又把这个所谓的这个叫临时的这个数据是吧,把它呢,又覆盖了我们原有I位置上这个值,所以又变成十了,下边呢,就是get在sta获取我们这个静态的这个结构这个属性了,对吧,I这个这个上面保存到这不就没了吗?然后又L漏的一,那就把这个十呢,是不是又拿到这儿。这块因为我们要调这个print方法,他呢是不是要放到一个新的战争当中去操作了。因为一个新的战争对吧。好这个呢就拿走了,然后就才结束,哎,那我们核心呢,来看这个I是几的话呢,你看因为你是从这块把这个取到这儿,然后做一个打印,这个值不就是十吗。
08:01
说完了,所以比较核心的这个事儿呢,就是这块关注一下。这块关注一下行,那这个呢,我们就说清楚了,关于这个加加的问题,那减减呢也类似。
我来说两句