官术网_书友最值得收藏!

2.4 運算符與表達式

2.4.1 賦值運算符與賦值表達式

賦值運算符(=)用于為變量指定數值。用賦值運算符可以構造賦值表達式,其基本形式如下:

例如:

這樣的賦值表達式稱為賦值語句。賦值運算符的左邊只能是一個變量,右邊則是一個表達式。右邊的表達式,可以是一個簡單的常量或變量,也可以是由變量、常量、運算符構成的更復雜的運算式。

賦值表達式的處理過程是,首先計算賦值運算符右邊表達式的值,然后將該值賦予左邊的變量。該值既作為左邊變量的值,又作為賦值表達式的值。

若有定義:

是一個正確的賦值語句(或賦值表達式)。賦值運算規則是從右到左,處理過程如下:

(1)先將0賦給y,這樣y的值為0,同時表達式y = 0的值同為0。

(2)將表達式y = 0的值賦值給x,x的值為0,同時x = y = 0的值為0。

有兩個問題需要注意,一是“=”在Java語言中不再表達數學上的相等關系,而作為賦值運算符,表達了一種數據傳遞的關系,把右邊表達式的值傳遞給左邊的變量。二是賦值表達式用于給變量賦值,其左邊只能是變量。下面的兩條語句都是錯誤的。

一般來說,左邊的變量和右邊的表達式應具有相同的數據類型,如果不同,則要通過數據類型轉換,相關規則將在后面進行介紹。

2.4.2 算術運算符與算術表達式

Java語言提供了9種算術運算符,如表2-9所示,一般分為雙目運算符和單目運算符兩大類。雙目運算符有兩個數據參與運算,單目運算的對象則只有一個數據。

表2-9 算術運算符

雙目運算符包括:+(加)、?(減)、*(乘)、/(除)、和%(取余),使用算術運算符時需要注意以下問題。

(1)如果除法運算的除數和被除數都是整數,則按整除的規則進行;如果有一個數為浮點數,則按浮點數除法的規則進行。

例如,表達式189/10的值為18,而189.0/10的值為18.9。

(2)參與取余運算的數據一般是兩個整型數據。如果a和b是兩個整數,則表達式a%b運算的方式是將a作為被除數,b作為除數,進行整除運算,運算結果不是商,而是余數。若k為整數,則k%10可以計算k的個位數,k%2是否為0可用于判定k是否為偶數。

單目運算符包括:+(正)、?(負)、++(自增)、??(自減)。

自增運算符將變量的值加1后再存入這個變量;自減運算符將變量的值減1后再存入這個變量。自增和自減運算符可以在變量左側,也可以在變量右側,例如,++a,a++。如果僅作為獨立的語句,兩者的執行結果并沒有區別。

假如定義兩個變量:int a = 0, b = 0,執行下面兩條語句以后,a和b的值都是1。

類似的情況,假如定義兩個變量:int a = 0, b = 0,執行下面兩條語句以后,a和b的值都是?1。

如果自增和自減運算符與其他運算符組合使用,運算符放在左側與放在右側,執行結果會明顯不同。兩者之間的區別可以通過下面例子加以說明。

設有定義:int a = 0, b = 0,執行語句:

那么,a和b的值分別為0和1,執行過程是,先將b的值(0)與2相乘并把乘積(0)賦值給a,這樣a的值即為0,最后再執行b自增的操作,b的值變成1。

如果換成執行語句:

那么,a和b的值分別為2和1,執行過程是,先將b的值加1,b的值即為1,然后將b的值(1)與2的乘積(2)賦值給a,這樣a的值即為a。

類似的情況,執行語句序列之后,a、b、c的值分別為0,?2,?2。

需要注意的是,自增運算和自減運算的運算對象都只能變量,不能是常量或其他表達式,形如6++或(a+b)++的表達式是非法的。

參與算術運算的數據一般是整型(long/int/short/byte)和浮點型數據(double/float)。字符型數據也可以參與算術運算,但實際上其參與運算的也是一個整型數據,也就是該字符對應的編碼值。

例如,字符'a'的編碼值為97,因此表達式'a'+2的值為99。

2.4.3 關系運算符與關系表達式

在許多情況下,程序要對某些條件進行判斷,根據條件成立與否,決定程序的執行流程。例如,以下if語句可以計算a的絕對值:

其中,b=?b是否執行,取決于條件(b<0)成立與否。這個條件就是用關系表達式來描述的,“<”就是一個關系運算符。關系運算的值是一個布爾型數據(true或false)。例如,若b為3,則表達式b <0的值為false;若b為?3,則表達式b<0的值為true。

Java提供了6種關系運算符,如表2-10所示。

表2-10 關系運算符

使用關系運算符時,需要注意以下問題:

(1)不要將關系運算符“==”誤寫成“=”。在Java語言中,“=”是賦值運算符,判斷相等關系的運算符是“==”。

(2)在Java語言中,數學表達式“3 < x < 5”,不能直接描述為“3 < x < 5”,而需要借助邏輯表達式“x > 3 && x<5”。

2.4.4 邏輯運算符與邏輯表達式

邏輯運算的運算對象是布爾型數據,運算結果也是布爾型數據。常用的邏輯運算符有&&(邏輯與)、||(邏輯或)和!(邏輯非)。運算規則如表2-11所示。

表2-11 邏輯運算的運算規則

(1)當兩個運算對象都為true時,邏輯與的運算結果為true,否則運算結果為false。

(2)當兩個運算對象都為false時,邏輯或的運算結果為false,否則運算結果為true。

(3)邏輯非是單目運算符,只有一個運算對象。運算對象為true,運算結果為false;運算對象為false,運算結果為true。

邏輯運算符可用于描述比較復雜的條件,例如,一組條件及其對應的邏輯表達式如下:

(1)m、n都能被k整除的邏輯表達式:m%k==0&&n%k==0;

(2)x的絕對值大于8的邏輯表達式:x > 8 || x < ?8;

(3)閏年判別的一般條件:能被4整除而不能被100整除,或者能被400整除。判別某一年(year)是為閏年的邏輯表達式如下:

判別某一年(year)是為平年的邏輯表達式如下:

在Java語言中,&&和||的運算會遵循“短路”規則,邏輯表達式中的部分運算在某些情況下,并不執行。例2-5中程序的運行反映了這一特征。

【例2-5】&&和||的運算規則。

【程序】

【運行結果】

我們來分析一下第1次運行的情況,輸入的數據為0和0。

語句“flag1=a>0&&++b>0”的執行流程是,首先判斷a>0,結果為false。此時已經可以確定“a>0&&++b>0”的值是false,因而直接將false賦值給flag1,而&&右側的表達式“++b>0”不被處理,變量b自增的操作沒有被執行。

語句“flag2=a>0||++b>0”的執行流程是,首先判斷a>0,結果為false。此時還無法確定“a>0||++b>0”的值,需要進一步計算||右側的表達式“++b>0”,也就是說,b先自增為1,于是“++b>0”的值為true,因此“a>0||++b>0”的值為true。

第2次運行的結果,請讀者自行分析。

短路規則在一定程度上可以提高程序執行的效率。

2.4.5 其他運算符與表達式

1.條件運算符與條件表達式

條件運算符將3個表達式組合在一起,組成條件表達式,條件表達式的一般形式是:

條件表達式的運算過程是,先計算表達式1的值,如果它的值為true,將表達式2的值作為條件表達式的值;否則,將表達式3的值作為條件表達式的值。例如:

可以看出,表達式1是一個值為true和false的關系表達式或邏輯表達式,表達式2和表達式3的類型一般是相同的。

2.位運算符

位運算符適用于整型的運算對象,運算特點是以二進制位為單位進行,如表2-12所示。

表2-12 位運算符

假設byte a = 106, flag= 0x0f,則a的二進制數形式為01101010,flag的二進制數形式為00001111。a & flag與a | flag的運算過程如圖2-1所示。

圖2-1 按位與和按位或運算

可以看出,a & flag結果的二進制數形式為00001010,可以將a的左邊4位置為0。a | flag結果的二進制數形式為01101111,可以將a的右邊4位置為1。

3.復合賦值運算符

復合賦值運算符是一種基本運算與賦值運算合并的簡化書寫形式。例如:

2.4.6 表達式的處理規則

一個表達式中可能包含多個不同的運算符和具有不同數據類型的運算對象,優先級規定了不同運算符的先后次序,結合性規定了同一優先級運算符的運算次序。不同數據類型的運算對象也會按確定的規則轉換為同一類型后再進行運算。

1.運算符優先級

優先級規定同一表達式中不同運算符被執行的次序。在表達式求值時,按運算符的優先級別由高到低的次序執行。例如,算術運算符中采用“先乘除后加減”,在表達式“8+5*6”中,由于“*”的優先級及高于“+”,所以先進行“5*6”,其結果再進行“+”運算。

常見的運算符中,優先級由高到低分別是單目運算、算術運算、關系運算、邏輯運算和賦值運算。級別為1的優先級最高,級別為14的優先級最低。

2.運算符結合性

運算符的結合性規定了優先級相同情況下的計算順序。+,?,*,/等大多數運算符的結合性是左結合,即從左到右。對于表達式x?y+z, y應先與“?”號結合,執行x?y運算,然后再執行+z的運算。

右結合性運算符包括單目運算符、賦值運算符及條件運算符。例如,賦值表達式x=y=z執行的次序:先執行y=z,再執行x=(y=z)。

表2-13給出了全部運算符的優先級與結合性。

表2-13 運算符的優先級與結合性

3.數據類型轉換

如果參與運算的對象具有相同的數據類型,那么可以直接進行運算;否則需要進行類型轉換。有些轉換可以自動完成,有些轉換必須采用強制方式。

例如,以下聲明:

對于語句y = x,賦值運算兩邊的數據類型不同,x的int型值會自動轉換為double型值,再賦值給y。執行以后,y的值為double型值6.0。

而語句x = y是非法的,因為double型值y要轉換為int型值,可能會產生精度損失。如果我們不介意損失,而希望把y的整數部分賦值給x,那么可以采用強制類型轉換:

需要注意的是,強制類型轉換并沒有改變y的數據類型,y的數據類型仍然是double。只是指定表達式(int)y的數據類型為int,這里,表達式(int)y的值為8。

如圖2-2所示,如果轉換是沿箭頭方向進行的,就不會造成運算精度的降低,可以自動完成;否則,必須采用強制轉換的方式。

圖2-2 基本類型轉換圖

設f和c均為double型變量,分別表示華氏溫度和攝氏溫度。如果要實現溫度轉換,下面的兩個賦值語句,前者是錯誤的,后者是正確的。

前者的執行過程,是先計算9/5,兩個整數的除法運算按整除規則,結果是1,而不是1.8,顯然不能正確地進行溫度轉換;后者的執行過程是,先計算c*9,會自動將9轉換為double,以便與c類型相同,乘法結果的類型為double,接下來的除法和加法會分別把5和32自動轉換為double類型,再進行運算。

注意,強制類型轉換運算的優先級高于+、?、*、/、%等運算,類型轉換在運算之前處理。例如,若有:

那么(int)x+y的值為1.6,而不是2,其計算過程是,先將1.5強制轉換為int類型的1,再將1轉換為double類型的1.0,最好將1.0與y進行加法運算。

主站蜘蛛池模板: 五台县| 茌平县| 奉新县| 泗阳县| 武定县| 永昌县| 桃园市| 吴桥县| 洮南市| 龙口市| 侯马市| 屏边| 乌苏市| 刚察县| 沿河| 碌曲县| 云龙县| 汤阴县| 宜春市| 北安市| 江阴市| 页游| 中西区| 色达县| 自贡市| 茂名市| 三都| 中牟县| 栾川县| 渭源县| 洛阳市| 鄯善县| 沂南县| 崇信县| 新乡市| 儋州市| 广灵县| 团风县| 博湖县| 昌吉市| 嘉义县|