?? chapter3.htm
字號:
<br>
2. 轉型<br>
大家會發現假若對主數據類型執行任何算術或按位運算,只要它們“比int小”(即char,byte或者short),那么在正式執行運算之前,那些值會自動轉換成int。這樣一來,最終生成的值就是int類型。所以只要把一個值賦回較小的類型,就必須使用“造型”。此外,由于是將值賦回給較小的類型,所以可能出現信息丟失的情況)。通常,表達式中最大的數據類型是決定了表達式最終結果大小的那個類型。若將一個float值與一個double值相乘,結果就是double;如將一個int和一個long值相加,則結果為long。<br>
<br>
3.1.14 Java沒有“sizeof”<br>
在C和C++中,sizeof()運算符能滿足我們的一項特殊需要:獲知為數據項目分配的字符數量。在C和C++中,size()最常見的一種應用就是“移植”。不同的數據在不同的機器上可能有不同的大小,所以在進行一些對大小敏感的運算時,程序員必須對那些類型有多大做到心中有數。例如,一臺計算機可用32位來保存整數,而另一臺只用16位保存。顯然,在第一臺機器中,程序可保存更大的值。正如您可能已經想到的那樣,移植是令C和C++程序員頗為頭痛的一個問題。<br>
Java不需要sizeof()運算符來滿足這方面的需要,因為所有數據類型在所有機器的大小都是相同的。我們不必考慮移植問題——Java本身就是一種“與平臺無關”的語言。<br>
<br>
3.1.15 復習計算順序<br>
在我舉辦的一次培訓班中,有人抱怨運算符的優先順序太難記了。一名學生推薦用一句話來幫助記憶:“Ulcer
Addicts Really Like C A lot”,即“潰瘍患者特別喜歡(維生素)C”。<br>
<br>
助記詞 運算符類型 運算符<br>
<br>
Ulcer(潰瘍) Unary:一元 + - + + - [[ 其余的 ]]<br>
Addicts(患者) Arithmetic(shift);算術(和移位) * / % + - << >><br>
Really(特別) Relational:關系 > < >= <= == !=<br>
Like(喜歡) Logical(bitwise):邏輯(和按位) && || & | ^<br>
C Conditional(ternary):條件(三元) A>B ? X:Y<br>
A Lot Assignment:賦值 =(以及復合賦值,如*=)<br>
<br>
當然,對于移位和按位運算符,上表并不是完美的助記方法;但對于其他運算來說,它確實很管用。<br>
<br>
3.1.16 運算符總結<br>
下面這個例子向大家展示了如何隨同特定的運算符使用主數據類型。從根本上說,它是同一個例子反反復復地執行,只是使用了不同的主數據類型。文件編譯時不會報錯,因為那些會導致錯誤的行已用//!變成了注釋內容。<br>
<br>
120-129頁程序<br>
<br>
注意布爾值(boolean)的能力非常有限。我們只能為其賦予true和false值。而且可測試它為真還是為假,但不可為它們再添加布爾值,或進行其他其他任何類型運算。<br>
在char,byte和short中,我們可看到算術運算符的“轉型”效果。對這些類型的任何一個進行算術運算,都會獲得一個int結果。必須將其明確“造型”回原來的類型(縮小轉換會造成信息的丟失),以便將值賦回那個類型。但對于int值,卻不必進行造型處理,因為所有數據都已經屬于int類型。然而,不要放松警惕,認為一切事情都是安全的。如果對兩個足夠大的int值執行乘法運算,結果值就會溢出。下面這個例子向大家展示了這一點:<br>
<br>
129頁下程序<br>
<br>
輸出結果如下:<br>
big = 2147483647<br>
bigger = -4<br>
<br>
而且不會從編譯器那里收到出錯提示,運行時也不會出現異常反應。爪哇咖啡(Java)確實是很好的東西,但卻沒有“那么”好!<br>
對于char,byte或者short,混合賦值并不需要造型。即使它們執行轉型操作,也會獲得與直接算術運算相同的結果。而在另一方面,將造型略去可使代碼顯得更加簡練。<br>
大家可以看到,除boolean以外,任何一種主類型都可通過造型變為其他主類型。同樣地,當造型成一種較小的類型時,必須留意“縮小轉換”的后果。否則會在造型過程中不知不覺地丟失信息。<br>
<br>
3.2 執行控制<br>
Java使用了C的全部控制語句,所以假期您以前用C或C++編程,其中大多數都應是非常熟悉的。大多數程序化的編程語言都提供了某種形式的控制語句,這在語言間通常是共通的。在Java里,涉及的關鍵字包括if-else、while、do-while、for以及一個名為switch的選擇語句。然而,Java并不支持非常有害的goto(它仍是解決某些特殊問題的權宜之計)。仍然可以進行象goto那樣的跳轉,但比典型的goto要局限多了。<br>
<br>
3.2.1 真和假<br>
所有條件語句都利用條件表達式的真或假來決定執行流程。條件表達式的一個例子是A==B。它用條件運算符“==”來判斷A值是否等于B值。該表達式返回true或false。本章早些時候接觸到的所有關系運算符都可拿來構造一個條件語句。注意Java不允許我們將一個數字作為布爾值使用,即使它在C和C++里是允許的(真是非零,而假是零)。若想在一次布爾測試中使用一個非布爾值——比如在if(a)里,那么首先必須用一個條件表達式將其轉換成一個布爾值,例如if(a!=0)。<br>
<br>
3.2.2 if-else<br>
if-else語句或許是控制程序流程最基本的形式。其中的else是可選的,所以可按下述兩種形式來使用if:<br>
<br>
if(布爾表達式)<br>
語句<br>
<br>
或者<br>
<br>
if(布爾表達式)<br>
語句<br>
else<br>
語句<br>
<br>
條件必須產生一個布爾結果。“語句”要么是用分號結尾的一個簡單語句,要么是一個復合語句——封閉在括號內的一組簡單語句。在本書任何地方,只要提及“語句”這個詞,就有可能包括簡單或復合語句。<br>
作為if-else的一個例子,下面這個test()方法可告訴我們猜測的一個數字位于目標數字之上、之下還是相等:<br>
<br>
131頁程序<br>
<br>
最好將流程控制語句縮進排列,使讀者能方便地看出起點與終點。<br>
<br>
1. return<br>
return關鍵字有兩方面的用途:指定一個方法返回什么值(假設它沒有void返回值),并立即返回那個值。可據此改寫上面的test()方法,使其利用這些特點:<br>
<br>
131-132頁程序<br>
<br>
不必加上else,因為方法在遇到return后便不再繼續。<br>
<br>
3.2.3 反復<br>
while,do-while和for控制著循環,有時將其劃分為“反復語句”。除非用于控制反復的布爾表達式得到“假”的結果,否則語句會重復執行下去。while循環的格式如下:<br>
<br>
while(布爾表達式)<br>
語句<br>
<br>
在循環剛開始時,會計算一次“布爾表達式”的值。而對于后來每一次額外的循環,都會在開始前重新計算一次。<br>
下面這個簡單的例子可產生隨機數,直到符合特定的條件為止:<br>
<br>
132下程序<br>
<br>
它用到了Math庫里的static(靜態)方法random()。該方法的作用是產生0和1之間(包括0,但不包括1)的一個double值。while的條件表達式意思是說:“一直循環下去,直到數字等于或大于0.99”。由于它的隨機性,每運行一次這個程序,都會獲得大小不同的數字列表。<br>
<br>
3.2.4 do-while<br>
do-while的格式如下:<br>
<br>
do<br>
語句<br>
while(布爾表達式)<br>
<br>
while和do-while唯一的區別就是do-while肯定會至少執行一次;也就是說,至少會將其中的語句“過一遍”——即便表達式第一次便計算為false。而在while循環結構中,若條件第一次就為false,那么其中的語句根本不會執行。在實際應用中,while比do-while更常用一些。<br>
<br>
3.2.5 for<br>
for循環在第一次反復之前要進行初始化。隨后,它會進行條件測試,而且在每一次反復的時候,進行某種形式的“步進”(Stepping)。for循環的形式如下:<br>
<br>
for(初始表達式; 布爾表達式; 步進)<br>
語句<br>
<br>
無論初始表達式,布爾表達式,還是步進,都可以置空。每次反復前,都要測試一下布爾表達式。若獲得的結果是false,就會繼續執行緊跟在for語句后面的那行代碼。在每次循環的末尾,會計算一次步進。<br>
for循環通常用于執行“計數”任務:<br>
<br>
133頁下程序<br>
<br>
注意變量c是在需要用到它的時候定義的——在for循環的控制表達式內部,而非在由起始花括號標記的代碼塊的最開頭。c的作用域是由for控制的表達式。<br>
以于象C這樣傳統的程序化語言,要求所有變量都在一個塊的開頭定義。所以在編譯器創建一個塊的時候,它可以為那些變量分配空間。而在Java和C++中,則可在整個塊的范圍內分散變量聲明,在真正需要的地方才加以定義。這樣便可形成更自然的編碼風格,也更易理解。<br>
可在for語句里定義多個變量,但它們必須具有同樣的類型:<br>
<br>
134頁上程序<br>
<br>
其中,for語句內的int定義同時覆蓋了i和j。只有for循環才具備在控制表達式里定義變量的能力。對于其他任何條件或循環語句,都不可采用這種方法。<br>
<br>
1. 逗號運算符<br>
早在第1章,我們已提到了逗號運算符——注意不是逗號分隔符;后者用于分隔函數的不同自變量。Java里唯一用到逗號運算符的地方就是for循環的控制表達式。在控制表達式的初始化和步進控制部分,我們可使用一系列由逗號分隔的語句。而且那些語句均會獨立執行。前面的例子已運用了這種能力,下面則是另一個例子:<br>
<br>
134頁下程序<br>
<br>
輸出如下:<br>
<br>
135頁上程序<br>
<br>
大家可以看到,無論在初始化還是在步進部分,語句都是順序執行的。此外,盡管初始化部分可設置任意數量的定義,但都屬于同一類型。<br>
<br>
3.2.6 中斷和繼續<br>
在任何循環語句的主體部分,亦可用break和continue控制循環的流程。其中,break用于強行退出循環,不執行循環中剩余的語句。而continue則停止執行當前的反復,然后退回循環起始和,開始新的反復。<br>
下面這個程序向大家展示了break和continue在for和while循環中的例子:<br>
<br>
135頁下程序<br>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -