天天看點

《21天學通Java(第7版)》—— 2.5 表達式和運算符

本節書摘來異步社群《21天學通java(第7版)》一書中的第2章,第2.5節,作者: 【美】rogers cadenhead(羅格斯 卡登海德),更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

表達式是一條能夠提供值的語句。最常見的是數學表達式,如下面的例子所示:

這3條語句都是表達式——它們提供了可被賦給變量的值。第1條語句将字面量3賦給變量x。第2條語句将變量x的值賦給變量y。在第3條語句中,乘法運算符*用來将x和y相乘,結果存儲在變量z中。

表達式可以是變量、字面量和運算符的任何組合,也可以是方法調用,因為方法能夠将一個值傳回給調用它的類或對象。

您知道,表達式所提供的值稱為傳回值。在java程式中,可将這個值賦給變量或以其他方式使用。

大多數java中的表達式使用了運算符,如*。運算符是一些特殊符号,用于數學函數、指派語句和邏輯比較。

在java中,有5種用來完成基本算術運算的運算符,如表2.3所示。

《21天學通Java(第7版)》—— 2.5 表達式和運算符

每個運算符都有兩個操作數,一邊一個。減法運算符也可以用來對單個操作數求反,即将操作數與−1相乘。

使用除法時,要注意操作數的類型。如果将除法運算的結果存儲在整型變量中,結果将向下取整,因為int類型不能處理浮點數。

例如,如果将結果存儲在int變量中,則表達式31/9的結果為3。

使用運算符%的求模運算得到的是除法運算的餘數。例如,31%9的結果是4,因為31被9除的餘數是4。

很多針對整數的算術運算的結果為int值,而不管操作數是什麼類型。處理其他數值類型,如浮點數或長整型時,應確定操作數的類型與所需結果的類型相同。

要建立的下一個項目是個java類,它示範了如何使用java執行簡單的算術運算。為此,在<code>netbeans</code>中建立一個空java檔案,将其命名為weather并放在<code>com.java21days</code>包中,再在源代碼編輯器中輸入程式清單2.2所示的代碼。輸入完畢後選擇菜單“檔案”&gt;“儲存”将這個檔案存盤。

程式清單2.2 源代碼檔案weather.java

選擇菜單“運作”&gt;“運作檔案”運作該程式,它将生成如圖2.2所示的輸出。

《21天學通Java(第7版)》—— 2.5 表達式和運算符

該java應用程式的第5~14行使用算數運算符将華氏溫度轉換為攝氏溫度。

第5行:聲明浮點變量fah,并将其初始化為86。

第6行:顯示fah的目前值。

第7行:第一個注釋,解釋了該程式的功能。這些注釋将被java編譯器忽略。

第9行:将fah的值減去32。

第11行:将fah的值除以9。

第13行:将fah的值乘以5。

第14行:将fah的值轉換為攝氏溫度後,再次顯示它。

第16~25行與此類似,但執行相反的轉換——将攝氏溫度轉換為華氏溫度。

給變量指派的語句是一個表達式,因為它生成一個值。是以,可以下面這種不同尋常的方式将指派語句連在一起:

<code>x = y = z = 7;</code>

在這條語句中,所有3個變量(x、y和z)的值最後都為7。

在指派之前,将首先計算指派表達式的右邊。是以,可以這樣使用表達式語句:

在表達式x = x + 2中,首先計算x+2;然後将結果(7)賦給變量x。

在程式設計中,使用表達式來修改變量的值是一項常見的任務。有幾個專門用于這方面的運算符。

表2.4列出了這些指派運算符及等效的表達式。

《21天學通Java(第7版)》—— 2.5 表達式和運算符

這些簡化的指派運算符與它們所代表的更長的指派語句等效。然而,如果指派語句的一邊是複雜的表達式,将出現不再等效的情況。例如,如果x等于20,y等于5,下面兩條語句的結果将不同:

其中第一條語句導緻x的值為9,而第二條語句導緻x的值為2。有疑問時,應使用多條指派語句來簡化表達式,而不要使用簡化的運算符。

2.5.3 遞增和遞減運算符

另一種常見的程式設計任務将整型變量加1或減1。有專門用于完成這種運算的運算符:遞增和遞減運算符。對變量做遞增運算意味着将它的值加1,做遞減運算意味着将它的值減1。

遞增運算符是++,遞減運算符是−−。這些運算符位于變量名的前面或後面,如下所示:

其中語句x++将變量x的值從7增加到8。

遞增和遞減運算符可放在變量名的前面或後面,這将影響表達式的結果。

如果遞增和遞減運算符位于變量名前面,則被稱為字首運算符;如果位于變量名後面,則被稱為字尾運算符。

在簡單表達式(如counts--;)中,無論使用字首還是字尾運算符,結果都相同,是以它們可以互換。然而,當遞增和遞減運算符被用于更複雜的表達式中時,選擇字首還是字尾運算符就至關重要。

請看下面的代碼:

上述3個表達式由于字首和字尾運算符的差别而産生完全不同的結果。

使用字尾運算符時,先使用變量的值,再将變量遞增或遞減。是以,在y = x++中,先将x的值賦給y,再将x的值加1。

使用字首運算符時,先将變量遞增或遞減,再使用變量的值。例如,在z = ++x中,先将x的值加1,再将x的值賦給z。

上述代碼的最終結果是,y等于42,z等于44,x等于44。

如果對此還不清楚,下面的例子再次通過注釋描述了每一步的情況:

在特别複雜的表達式中使用遞增和遞減運算符時,很可能得到意外的結果。“在x自增之前将x的值賦給y”這一概念不再完全正确,因為java總是先計算表達式右邊的内容,然後再把結果賦給表達式左邊的變量。java在處理表達式之前會存儲一些值,以便字尾運算符能夠像本節介紹的那樣工作。當包含字首和字尾運算符的複雜表達式的結果不同于您的期望時,請将該表達式拆成多個語句,以簡化它。

java有幾種可用于對變量之間、變量和字面量(或其他類型的資訊)之間進行比較的運算符。

這些運算符用于傳回布爾值(true或false)的表達式,表達式的傳回值取決于比較的結果是真還是假。表2.5列出了這些比較運算符。

《21天學通Java(第7版)》—— 2.5 表達式和運算符

下面的例子示範了比較運算符的用法:

表達式age&lt;25的結果為true還是false取決于age的值。由于這裡的age為37(比25大),是以iship為布爾值false。

結果為布爾值的表達式(如比較運算)可以被組合成更加複雜的表達式。這是通過邏輯運算符來實作的,邏輯運算符用于邏輯組合:and、or、xor和邏輯not。

對于and組合,可使用邏輯運算符&amp;或&amp;&amp;。當兩個布爾表達式通過&amp;或&amp;&amp;組合在一起後,僅當兩個布爾表達式都為真時,整個表達式的結果才為true。

請看下面的例子:

<code>boolean extralife = (score &gt; 75000) &amp; (playerlives &lt; 10);</code>

這個表達式将兩個比較表達式(score &gt; 75000和playerlives &lt;10)組合在一起。如果這兩個表達式都為真,則true被賦給變量extralife;在其他情況下,false被賦給extralife。

&amp;和&amp;&amp;之間的差别在于java對組合表達式所做的工作量。如果使用&amp;,則不管什麼情況下,&amp;兩邊的表達式都将被計算;如果使用&amp;&amp;,則當左邊的表達式為false時,将不計算右邊的表達式。

是以,&amp;&amp;的效率更高,因為它不做不必要的工作。在前面的示例中,如果score不比75000大,就根本不需要考慮playlives是否小于10。

對于or組合,可使用邏輯運算符|或||。如果運算符兩邊的任何一個布爾表達式為真,則組合表達式的結果為true。

請看下述示例:

<code>boolean extralife = (score &gt; 75000) || (playerlevel == 0);</code>

該表達式合并了兩個比較表達式:score &gt; 75000和playerlevel = = 0。隻要這兩個表達式中的任何一個為真,則true被賦給變量extralife;僅當這兩個表達式都是false時,false才被賦給extralife。

注意,這裡使用的是||,而不是|。是以,如果score &gt; 75000為true,則extralife将被設定成true,而根本不會計算第二個表達式。

用于xor合并的邏輯運算符隻有一個:^。僅當被合并的兩個布爾表達式的值相反時,整個表達式的結果才為true;如果兩個表達式都是true或都是false,則^運算符的結果為false。

not組合使用邏輯運算符!,後面跟一個表達式。它對布爾表達式的值求反,這與用負号來改變數字的符号相同。例如,如果age&lt;25的結果為true,則!(age&lt;25)的結果将為false。

首次見到這些邏輯運算符時,可能覺得它們完全不符合邏輯。在本周餘下的課程中,您将大量地使用它們,尤其是在第5章。

當表達式中有多個運算符時,java有一套優先級用來判斷運算符的執行順序。在許多情況下,優先級決定了整個表達式的最終值。

例如,請看下面的表達式:

<code>y = 6 + 4 / 2;</code>

變量y的值為5還是8取決于哪個算術運算先被處理。如果先計算表達式6+4,則y的值為5;否則為8。

通常,從先到後的順序如下:

1.遞增和遞減運算;

2.算術運算;

3.比較運算;

4.邏輯運算;

5.指派運算。

如果兩個運算的優先級相同,則左邊的比右邊的先被處理。表2.6列出了java中衆多運算符的優先級。排在越前面的運算符的優先級越高。

《21天學通Java(第7版)》—— 2.5 表達式和運算符
《21天學通Java(第7版)》—— 2.5 表達式和運算符

表2.6中的多個運算符都将在本周後面的課程中介紹。

回過頭來看表達式y =6 + 4 / 2。表2.6表明,除法先于加法計算,是以y的值為8。

要改變表達式求值的順序,可以用圓括号将需要先計算的表達式括起。可以嵌套圓括号以確定按所需的順序對表達式進行求值——最裡邊的圓括号内的表達式最先被計算。

下述表達式的結果為5:

<code>y = (6 + 4) / 2</code>

因為先計算6 + 4,得到10,然後再除以2,最後的結果為5。

圓括号還可以提高表達式的可讀性。如果不能一眼看出表達式的優先級,可以添加圓括号來強制轉換為希望的優先級,使語句更容易了解。