您好,登錄后才能下訂單哦!
這篇文章主要為大家分享Java自增自減運算符的使用方法。文中還介紹了自增自減運算符的基本運算規(guī)則和運算符的賦值方法,希望大家通過這篇文章能有所收獲。
自增(++)和自減(--)運算符是對變量在原始值的基礎(chǔ)上進行加1或減1的操作。它們都有前綴和后綴兩種形式。前綴形式的運算規(guī)則可以概括為:”先自增(減),后引用”,而后綴形式的運算規(guī)則可以概括為:”先引用,后自增(減)”。這里所說的”引用”,指的是使用變量的值。另外,我們還要強調(diào)一個細(xì)節(jié):無論是前綴形式還是后綴形式,自增自減運算符的優(yōu)先級要高于賦值運算符。大家要記清楚這個細(xì)節(jié),后文還會針對這個細(xì)節(jié)進行論述。下面我們就分為幾種情況來研究++和--在不同場合下的運算效果。
請看代碼:
我們可以看到,這段代碼中總共有3條語句,其中第2條語句中僅有一個后綴形式++操作,程序的輸出結(jié)果是3。那么我們再來看另外一段代碼:
這段代碼與之前的那段代碼基本一樣,只是第2條語句中,后綴形式的++操作被換成了前綴形式,程序的輸出結(jié)果還是3。這說明:當(dāng)一條語句中僅有++或--操作時,前綴形式與后綴形式的運算符沒有任何區(qū)別。請注意:這句話的前半句是一個很重要的前提,那就是” 一條語句中僅有++或--操作”,如果脫離了這個前提,后半句所說的結(jié)論并不成立。
可能有些小伙伴沒看明白這個標(biāo)題是什么意思,我們來看一段代碼:
這段代碼的第2條語句對變量a進行了自增操作,并且把這個操作結(jié)果賦值給另一個變量b。語句中的變量b就是標(biāo)題中所說的”其他變量”,是指沒有進行自增自減操作的其他變量。為什么要強調(diào)”賦值給其他變量”這個前提呢?就是因為如果把運算結(jié)果賦值給變量a自身,又會產(chǎn)生不同的效果,我們后面再去講解賦值給自身的情況?,F(xiàn)在先來分析程序,重點看第2條語句:變量a所進行的是前綴形式的自增操作,那么按照”先自增后引用”的運算規(guī)則,a的值首先變成3,然后賦值b。因此,給變量b賦值的是3,那么輸出結(jié)果當(dāng)然就是3和3。
如果代碼變成下面的樣子:
這一次,代碼的第2行發(fā)生了變化,a的自增操作變成了后綴形式。此時的程序輸出結(jié)果是3和2。為什么會是這樣的運行結(jié)果呢?網(wǎng)上有很多資料對此的解釋是:因為表達式中出現(xiàn)的是后綴形式的自增操作,因此,運算的規(guī)則就變成了”先引用后自增”。計算機會先使用a的值給b賦值,a的值是2,所以b被賦值為2,a在完成給b賦值的操作之后,才會完成自增變?yōu)?,所以程序的輸出結(jié)果為3和2。這種解釋看似非常合理,但其實是錯誤的!
按照這種解釋,后綴形式的自增是在賦值之后才完成的,由此可以推出后綴形式的自增自減運算的優(yōu)先級比賦值運算的優(yōu)先級更低。而我們之前已經(jīng)特意強調(diào)過:無論是前綴形式還是后綴形式,自增自減運算符的優(yōu)先級都比賦值運算符要高。接下來問題來了:既然++和--的運算優(yōu)先級高于賦值運算符,那么為什么賦值之前a的值沒有自增為3呢?
其實這是個錯覺!a在賦值給變量b之前,就已經(jīng)完成了自增!為了講解清楚真實情況,我們必須科普一個小常識,那就是:當(dāng)程序中,如果變量參與了算術(shù)運算、或者以變量的值進行賦值,或者打印了某個變量的值,總之只要程序中用到這個變量的值,都會先把這個變量存入一個臨時的空間,專業(yè)上把這個臨時的空間稱之為”操作數(shù)?!?。我們之前所說的”先引用后自增”中所說的這個”引用”操作,其實就是指”把變量的值存入操作數(shù)?!边@個動作。當(dāng)程序中需要用到變量的值,計算機是從”操作數(shù)?!敝腥〕鲋颠M行運算,并不是我們想象的直接從變量所在的內(nèi)存單元中取出數(shù)值。但是,如果語句中僅有++或--,并不會把變量的值存入操作數(shù)棧,而是直接對變量進行自增或自減的操作,這也是為什么我們把語句中僅有++或--單獨作為一種情況講解的原因。
科普完這個小常識之后,我們來解釋剛才的代碼為什么會輸出3和2。代碼中出現(xiàn)用a的值給變量b賦值的語句,并且a的后面出現(xiàn)了++,說明要對a進行后綴形式的自增操作。按照我們剛才科普的小常識,a參與了賦值運算,那么就會把a的值存入操作數(shù)棧。因為a的自增是后綴形式的,所以要遵循”先引用后自增”的運算規(guī)則,因此,計算機會首先取出a的值2存入操作數(shù)棧,然后再把a的值增加到3。做完自增操作之后,接下來會對變量b進行賦值操作。那么,是用哪個值給變量b賦值呢?就是用剛才存到操作數(shù)棧中的那個2對變量b進行賦值,所以b最終得到的值是2,因此輸出結(jié)果是3和2。
在這里,請大家注意一個細(xì)節(jié),那就是:代碼中的自增操作雖然是后綴形式的,但這個自增動作卻是在賦值之前完成的,這也解釋了后綴形式的自增運算優(yōu)先級高于賦值運算,而網(wǎng)上很多資料中所說的”先完成賦值再去做自增操作”是完全錯誤的。
那么,之前例題中第2條語句是”b=++a;”,會不會也把a的值存入操作數(shù)棧呢?答案是肯定的,只要是變量參了算術(shù)運算、賦值、被打印這些操作,都會取出變量的值存入操作數(shù)棧。因為語句中出現(xiàn)的是前綴形式的自增,所以在把值存入操作數(shù)棧之前就已經(jīng)完成了自增操作。
好,現(xiàn)在我們來加大一點難度,請看代碼:
這段代碼的第2條語句,出現(xiàn)了2次++a,那么運算結(jié)果會是多少呢?”=”右邊的表達式為”++a + ++a”,按照運算優(yōu)先級,計算機首先對a進行自增操作,經(jīng)過這一步操作之后,變量a的值變成了3,緊接著,計算機會把這個3存入操作數(shù)棧中,為了方便講述,我們把這個操作數(shù)棧叫做”棧1”,接下來,表達式中又出現(xiàn)了++a,此時計算機再次對a進行自增,a的值變成了4,為了完成加法操作,計算機又把這個4存入到另一個操作數(shù)棧中。我們把這個操作數(shù)棧稱為”棧2”。按照運算優(yōu)先級,接下來要做的事情就是完成加法運算,計算機把”棧1”中的3和”棧2”中的4分別取出并且進行相加,得到的結(jié)果是7,最后把這個7賦值給”=”左邊的變量b。所以上面代碼運行所輸出的結(jié)果分別是4和7。
下面我們再來研究一個關(guān)于運算順序問題,請看下面的代碼:
我們還是重點來分析第2行代碼。”=”右邊首先是++a,所以對先a進行自增操作,此時a變成了3,緊接著把自增之后的值存入”棧1”,接下來遇到了a++,因為是后綴形式的自增操作,遵循”先引用后自增”的運算規(guī)則,計算機先取出a的值3,并且存入”棧2”,然后對a進行自增的操作,a的值變成了4?,F(xiàn)在,”棧1”和”棧2”中都已經(jīng)存入了值,那么,此時計算機是先把”棧1”和”棧2”中的值做個相加操作呢,還是先去做變量a的第3次自增操作呢?很多同學(xué)肯定都會認(rèn)為計算機肯定是先去完成a的第3次自增操作,理由是自增自減運算優(yōu)先級高于加法運算。其實不然,當(dāng)運算進行到這一步的時候,計算機會先把”棧1”和”棧2”中的兩個值相加,然后才去完成a的第3次自增操作。很多人都不理解為什么會這樣,難道不是++a的優(yōu)先級更高嗎?
這里需要澄清一個大家對”優(yōu)先級”概念的誤解。當(dāng)計算機有AB兩個操作可以做的時候,如果選擇先完成A得到的結(jié)果是X,而選擇先完成B得到結(jié)果是Y,此時計算機必須按照運算的優(yōu)先級做出選擇。而如果先完成A和先完成B對運算結(jié)果沒有影響,那么計算機就會先完成左邊(先出現(xiàn)的)的操作。此時,如果把”棧1”和”棧2”中的值相加,并不會影響到最終的運算結(jié)果,并且這個操作是先于”a的第3次自增”出現(xiàn)的,所以計算機會先把”棧1”和”棧2”中的值加起來,然后才完成”a的第3次自增”。
很多小伙伴可能不理解,那么自增操作優(yōu)先級高于加法操作,是如何體現(xiàn)出來的呢?大家仔細(xì)看,在代碼的第2條語句中,a的自增出現(xiàn)了3次,加法運算出現(xiàn)了2次?!盿的第2次自增”后于”第1次加法運算”出現(xiàn),但卻先于”第1次加法運算”執(zhí)行,同理,”a的第3次自增”后于”第2次加法運算”出現(xiàn),卻先于”第2次加法運算”執(zhí)行。這些都體現(xiàn)出自增運算的優(yōu)先級是高于加法運算的。
講清楚”優(yōu)先級”這個問題之后,我們再回到例題本身。第1次加法運算是3和3相加,結(jié)果是6,計算機會把這個6存入”棧3”。緊接著計算機看到表達式中第2次出現(xiàn)了++a,于是再次對a進行自增操作,a的值變成了5,并且存入”棧4”。之后就是完成”棧3”和”棧4”中數(shù)值的相加操作,也就是把6和5相加,最終得到的結(jié)果是11。因此程序最終的輸出結(jié)果是5和11。
標(biāo)題中所說的”自身”,就是指進行了自增或自減運算操作的變量。我們來看下面的代碼:
以上代碼的第2條語句,對a進行了前綴形式的自增,然后又賦值給a自身,那么a的值是多少呢?因為a進行的是前綴形式的自增,所以運算規(guī)則是”先自增后引用”,自增之后a的值變成了3,把3存入操作數(shù)棧,之后以3賦值給a,所以a的值還是3。
但是,如果我們把代碼變成如下形式:
這一次,我們把第2條語句中的++a改成了a++。這種情況下,程序輸出a的值為竟然為2,而不是3。說的直白一點,a并沒有按我們的想象實現(xiàn)自增。這是為什么呢?我們來分析一下整個運算的過程:計算機看到”=”右邊是后綴形式的自增,因此以”先引用后自增”的規(guī)則進行運算,先把a的值存入操作數(shù)棧,緊接著對a進行自增操作,a的值變成了3,最后又用操作數(shù)棧中的那個2對a進行賦值,a的值又變成了2。這樣給我們造成了一種”a沒有進行自增”的錯覺。之前說過,網(wǎng)上很多資料都誤傳“后綴形式自增操作優(yōu)先級低于賦值運算”。如果按照這種錯誤說法,無法解釋以上代碼最終的輸出結(jié)果為2的原因。這也是為什么本文一開始就強調(diào)”無論是前綴形式還是后綴形式,自增自減運算符的優(yōu)先級要高于賦值運算符”的原因,就是因為這個細(xì)節(jié)是破解此類問題的關(guān)鍵點。類似的情況還可以衍生出很多版本,例如以下這段代碼::
這段代碼中,第2條語句對a進行了兩次自增操作,最終輸出a的值是6。而如果按照”后綴形式的自增自減優(yōu)先級低于賦值運算”的錯誤說法,則會認(rèn)為最終輸出a的值是7,理由是”=”右邊的運算結(jié)果是6,賦值給”=”左邊的a之后,又進行一次自增,最終的結(jié)果是7,當(dāng)然,事實可以證明這種理解是錯誤的。
接下來,我們再來研究一種更特殊的情況,請看以下代碼:
這一次,語句中出現(xiàn)了復(fù)合賦值運算符。如果程序運行,輸出a的值會是多少呢?我們首先可以推導(dǎo)出”+=”右邊的運算結(jié)果是7(具體推導(dǎo)過程不再贅述)。我們還知道,復(fù)合賦值運算符在完成運算的時候,要把右邊當(dāng)作整體。那么現(xiàn)在關(guān)鍵的問題就只剩一個了,那就是:”+=”左邊的a到底是多少?很多人認(rèn)為”+=”左邊a的值應(yīng)該是4,原因是++的運算優(yōu)先級高于+=,所以要先完成2次自增,完成了2次自增以后,a的值已經(jīng)變成了4,由此推得”+=”左邊a的值應(yīng)該是4,而最終的運算結(jié)果是11(4+7的和)。但實際運行程序的話,可以看到輸出a的值為9而非11。這是為什么呢?就是因為+=的優(yōu)先級雖然低于++,但是計算機在實際完成+=運算的時候會分為好幾個步驟進行。我們可以大致把+=運算分解為四大步驟:
A、把+=左邊的變量值存入操作數(shù)棧1
B、計算+=右邊的表達式,并把計算結(jié)果存入操作數(shù)棧2(此步驟其實是由多個具體步驟組成的)
C、把操作數(shù)棧1和操作數(shù)棧2中的數(shù)值相加得到運算結(jié)果
D、把運算結(jié)果存入變量a當(dāng)中
現(xiàn)在最關(guān)鍵的問題是步驟A和B哪一個先被執(zhí)行。如果先執(zhí)行步驟A,那么存入操作數(shù)棧1的是變量a自增之前的值,也就是2;反之,如果先執(zhí)行B,那么存入操作數(shù)棧1的是變量a自增之后的值,也就是4。真實的情況是先執(zhí)行步驟A,也就是把變量a自增之前的值存入操作數(shù)棧1。這是一個普遍適用的規(guī)律,所以大家一定要記住:當(dāng)語句中以復(fù)合賦值運算符給變量賦值的時候,計算機會先把復(fù)合賦值運算符左邊變量的值存入操作數(shù)棧。因此,這段程序運行的結(jié)果是9。
看完上述內(nèi)容,你們對自增自減運算符的使用方法有進一步的了解嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。