1. 程式人生 > >Java開發筆記(十)一元運算子的技巧

Java開發筆記(十)一元運算子的技巧

前面講到賦值運算子的時候,提到“x = x+7”可以被“x += 7”所取代,當然Java程式設計中給某個變數自加7並不常見,常見的是給某變數自加1,就像走臺階,一般都是一級一級臺階地走,犯不著一下子跳上七級臺階。那麼對於變數自加1的情況,既可以寫成“x = x+1”,也可以寫成“x += 1”,但是早期的Java設計師嫌前面的語句不夠簡潔,故而創造了新的運算子“++”,該運算子表示給變數自加1,於是“x += 1”可再簡化為“x++”。同理,運算子“–”表示給變數自減1,語句“x–”等價於“x -= 1”和“x = x-1”。為深入理解“++”與“–”這兩個運算子的作用,不妨執行下面的演示程式碼觀察結果:

int x = 3;
System.out.println("初始 x="+x);
x++; // 等同於x=x+1或者x+=1
System.out.println("自增1 x="+x);
x--; // 等同於x=x-1或者x-=1
System.out.println("自減1 x="+x);

既然有了自增1運算“++”和自減1運算“–”,那末有沒有自乘運算“**”和自除運算“//”呢?很遺憾Java不存在所謂的自乘與自除,倘若自乘運算指的是求某整型變數的平方,還是老老實實地寫以下程式碼“x = x*x”或者“x *= x”;倘若自除運算指的是求某整型變數的倒數,也要老老實實地寫以下程式碼“double y = 1.0/x”。求平方與求倒數的程式碼如下所示:

// 沒有“**”這個運算子,求平方還是按照常規寫法
x *= x; // 也可以寫成x = x*x
System.out.println("求平方 x="+x);
// “//”已經被用作註釋標記了,求倒數也得按照常規寫法,而且整數的倒數只能是小數
double y = 1.0/x; // 注意這裡的1.0/x,由於x是整型數,因此1/x無法求得小數
System.out.println("求倒數 y="+y);

由於“++”和“–”從頭到尾只有變數自身參與運算,並無其它的運算元,因此又被稱作一元運算子。類似的一元運算子還有負號運算子“-”和正號運算子“+”,這兩個符號其實也來源於數學,都放在數字前面,比如“-1”表示負一,“+1”表示正一。但在Java程式設計當中,變數前面的正負號概念有所不同,例如“-x”指的是對x做負號運算,“x = -x”等價於“x = 0-x”。倘若整型變數x原來是正值,則負號運算的結果為負值;但若x原來是負值,則負號運算的結果變為正值,也就是所謂的負負得正。至於“x = +x”等價於“x = 0+x”,顯然正號運算的結果與原值相同,正值的正號運算結果仍為正值,負值的正號運算結果仍為負值,而非數學上的正號意義。要想驗證上述的正負運算子,可執行下列程式碼觀察測試結果。

x = -x; // 等同於x=0-x
System.out.println("負數 x="+x);
x = +x; // 等同於x=0+x
System.out.println("正數 x="+x);

注意到上面的正負運算子直接放在變數之前,實際上“++”和“–”也允許放在變數前面,單獨的“++x”等價於“x++”,單獨的“–x”等價於“x–”。之所以特別強調“單獨”二字,是因為一旦它們放到了其他語句之中,運算結果就將大不相同。譬如下述程式碼演示了二者之間的區別:

int y1 = 7;
int z1 = y1++; // 後加加操作的優先順序較低
System.out.println("z1="+z1);
int y2 = 7;
int z2 = ++y2; // 前加加操作的優先順序較高
System.out.println("z2="+z2);

執行上面的演示程式碼,會得到下面的日誌資訊。

z1=7
z2=8

可見此時z1的數值不等於z2,究其原因,乃是前加加與後加加的執行機制差異所致。對於“int z1 = y1++;”,該語句在執行時會分解成下列兩個步驟:先執行對z1的賦值操作,再執行對y1的自增操作。此時最終的執行步驟如同以下程式碼:

int z1 = y1;
y1 = y1+1;

對於“int z2 = ++y2;”,該語句在執行時也會分解成下列兩個步驟:先執行對y1的自增操作,再執行對z1的賦值操作。此時最終的執行步驟如同以下程式碼:

y2 = y2+1;
int z2 = y2;

其實這種情況很好理解,計算機語言跟人類文字的書寫順序一樣,都是從上到下、從左往右。定睛一看“x++”,果然先看到變數x,接著才看到自增運算++;回頭再瞅“++x”,這下先看到自增運算,然後才看到變數x。同是書面文字,計算機語言和人類語言的語法邏輯大抵相同。
最後來個腦筋急轉彎,現有變數z1值為7,變數z2值為8,那麼且看下面程式碼的運算結果,變數z3的數值又該為何?有興趣的朋友不妨一試。

int z3 = ++z1+z2++;