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