Java programing Java programing

Java 程式設計上課教材

Java 程式設計上課教材 > 課程內容 > 第 4 堂課 - 運算子與資料型態的應用

第 4 堂課 - 運算子與資料型態的應用

上次更新日期 2018/08/06

前一章節我們談到了變數以及與程式互動的功能,並且加入了一些計算的方式與題目在裡面。不過前一章的計算還是太簡單了, 許多的運算子、運算式的先後次序、布林值 (真/假) 的變數宣告等,都還沒有提到,在這個章節裡面,我們會慢慢的來介紹這些東西。 當然,簡單的邏輯判斷也是布林值的功能之一,因此,這個章節裡面我們也會簡單的介紹 if 的語法,不過,只是先理解而已, 未來在『選擇』的介紹會再詳細說明。

  • 4.0: 英打練習與上週作業執行
  • 4.1: 變數型別強調與四則運算
  • 4.2: 增強指定運算子及遞增、遞減運算
  • 4.3: 布林值的宣告與運算及選擇
  • 4.4: 變數的型態轉換
  • 4.5: 運算子的運算優先順序
  • 4.6: 參考資料
  • 4.7: 課後練習

4.0: 英打練習與上週作業執行

資訊科技的技術,如果不是老闆,生產力人員 (就是你我) 通常不會只使用手持式裝置,至少會使用到各式鍵盤。因此,打字就非常重要, 好的打字速度帶你上天堂,差的打字速度讓你呆成糖 (蟲的台語,慢吞吞之意)!關於打字練習的重要注意事項請參考第 0 堂課的說明, 同時,請花 10 分鐘完成第 0 堂課的英文打字練習。完成之後,請打開你的 notepad++ 軟體,輸入底下的字串喔!

float a2 = 3.14159F ↵
int i = input.nextInt(); ↵
int j = i ; ↵
System.out.println ( i ); ↵
System.out.println (j+=i); ↵
import java.util.Scanner; ↵
public class unit04_odd_or_even { ↵
	public static void main (String args[]) { ↵
boolean on_off = false; ↵
String vbmesg = "" ; ↵
if ( selecting == 0 ) { on_off = true; } ↵
if ( on_off == true  ) { vbmesg = "你選擇了開啟電源拉!"; } ↵

int vbnu = input.nextInt(); ↵
char vbstring; ↵
System.out.println ("數值: " + vbnu + ", 英文: " + (vbstring = (char)vbnu)); ↵
System.out.println ("數值: " + (++vbnu) + ", 英文: " + (vbstring = (char)vbnu)); ↵
....

你不需要複製貼上,這單純是要讓你的打字速度變快!所以不要太緊張!練習就對了!沒練習完畢?沒關係,有空繼續練習即可!

  • 上週作業的執行

請從 class.vbird.tw 上面下載你上週的作業 java 文字檔,然後先行編譯成功後,等待老師過來查閱是否編譯成功與執行成功! 若執行成功,在你的作業成績會打 v !

4.1: 變數型別強調與四則運算

前一章我們談到了變數型別,例如浮點數就包含了 float 與 double,而預設的小數點數值都是 double 這玩意兒,那,如果要使用的是 float 怎辦?

  • float 與 long 等數值型態設定

如果你曾經想要使用 float 或其者是 long 等型別來宣告你的數值型態時,可能會有一些奇怪的錯誤訊息,例如底下的程式:

public class unit04_1_1 {
	public static void main ( String args[] ) {
		long  a1 = 15;
		float a2 = 3.14159;
		System.out.println ("測試長整數與浮點數: " + a1 + "," + a2);
	}
}

編譯過程會出現如下的錯誤:

C:\Users\dic\java>javac -encoding utf8 unit04_1_1.java
unit04_1_1.java:4: error: possible loss of precision
                float a2 = 3.14159;
                           ^
  required: float
  found:    double
1 error

錯誤訊息大意是說,你要求的是 float 這個型別,但是系統發現到 3.14159 是 double 的型別,所以無法符合你的宣告!所以就停下來了... 真是怪事!那怎辦呢?沒關係,你可以在 3.14159 後面加上一個 F 即可,就是:

  • float a2 = 3.14159F

如上的格式,這樣就能通過了!此外,如果萬一你的長整數 (long) 無法編譯過關的話,那就使用『 long a1 = 15L 』加上一個大寫的 L 在數字後,這樣就能夠改變類型了!沒辦法,因為預設 java 的整數型態與浮點數型態分別是 int 與 double 的緣故!

請透過上述的說明,將 unit04_1_1.java 的變數宣告設定調整成正確,然後持續編譯到成功!並且執行 『 java unit04_1_1 』直到成功顯示數值為止。
  • 四則運算

上一章節談到一些運算,其實基本運算符號就是這些啊!

+ (加)a1 + a2
- (減)a1 - a2
* (乘)a1 * a2
/ (除)a1 / a2
% (餘數)a1 % a2 (只用在整數上)

四則運算有夠好簡單!這裡就直接來以對談式輸入的方式,來讓使用者了解除數、被除數、商數及餘數吧!

  1. 分析問題:透過讓使用者輸入兩個整數數值,來介紹被除數、除數、商數與餘數的特性。
  2. 解決步驟:需要透過讓使用者在 MSDOS 環境輸入兩個整數數值才行!
    1. 為了互動,先載入 java.util.Scanner 套件才行
    2. 宣告類別名稱為 unit04_1_2 (就是檔名)
    3. 開啟方法為 main 的程式
    4. 建立名稱為 input 的 Scanner 物件(忘記的話,前去第 3 章查詢程式碼)
    5. 分別取得兩個數值,記得讓使用者輸入前,先用 System.out.print 加入提示字元較佳!
    6. 開始透過四則運算取得商數與餘數 (A/B 及 A%B)
    7. 透過 System.out.println 開始輸出運算結果
    8. 關閉 main
    9. 關閉類別
  3. 程式設計:比較重要的僅有宣告兩個整數的變數,同時該變數是由使用者輸入而來!
    	int A1 = input.nextInt();
    	int A2 = input.nextInt();
    
  4. 編譯、執行與測試:執行的結果會有點像這樣:
    C:\Users\dic\java>java unit04_1_2
    我將帶你了解被除數與除數的關係
    請輸入被除數: 100↵
    請輸入除數: 33↵
    
    
    輸入資料的回傳值如下:
    被除數 (分子): 100
    除數   (分母): 33
    商數: 3
    餘數: 1
    

因為 100 除以 33 後,得到 100=3*33+1 ,因此商數為 3 而餘數為 1 喔!注意,這是用在整數環境中而已!不要用在小數點的浮點運算喔!

實做題,透過讓使用者輸入一個 4 位數的數值 (1000 ~ 9999),然後以『餘數』的角度來思考,讓該數值變成反轉,例如 1234 會變成 4321 這樣! 程式檔名就設定為 unit04_1_3.java 好了。
  1. 先宣告一個變數,且該變數為讓使用者輸入而取得的一個數值;
  2. 輸入數值以除數為 10 取得一個餘數 (就是個位數)
  3. 輸入數值先除以 10 之後,以除數為 10 取得餘數 (就是十位數)
  4. 輸入數值先除以 100 之後,以除數為 10 取得餘數 (就是百位數)
  5. 輸入數值先除以 1000 之後,以除數為 10 取得餘數 (就是千位數)
  6. 最終反過來,個位數*1000+十位數*100+百位數*10+千位數,這樣就搞定了!
最終執行的結果會有點像這樣:
C:\Users\dic\java>java unit04_1_3
請輸入一個 4 位數的整數,但尾數不要是 0 才好: 1005↵
數值反轉的結果為: 5001

4.2: 增強指定運算子及遞增、遞減運算

工程師有的時候懶的打太多的字,那就會使用一些特別的方式來處理運算的流程,例如底下的說明:

  • 增強指定運算子

有時候我們會設定遞迴的方式,讓數值資料增加,這時通常會使用到類似『 i = i + 1 』這樣的方式。 但有時並不是加上 1 喔!例如 i = i + 5 之類的。那可以簡化撰寫的文句嘛?可以喔!透過底下的方式來處理:

運算子名稱範例完整寫法
+=加法指定i += 5i = i + 5
-=減法指定i -= 5i = i - 5
*=乘法指定i *= 5i = i * 5
/=除法指定i /= 5i = i / 5
%=餘數指定i %= 5i = i % 5

所謂的九九乘法表,其實就是一個 1 ~ 9 的數值,重複加上自己 9 次就對了!那麼我們請使用者輸入一個 1~9 的數值, 之後透過同一個程式碼進行 9 次,讓程式碼列出九九乘法的功能,該如何處理?

  1. 分析問題:其實重點是『同一個程式碼要執行 9 次來列印 9x9 乘法的結果』,所以得要注意到使用的公式為何。 其實,基本上就是類似 j+=i 這樣的設定方式,其中 i 就是使用者輸入的數值, j 就是九九乘法的結果。
  2. 解決步驟:我們需要讓使用者輸入,因此還是得要 Scanner 才行!之後就是這樣實驗看看:
    1. 事先匯入 Scanner 的套件才行
    2. 宣告類別名稱為 unit04_2_1 (就是檔名)
    3. 開啟方法為 main 的程式
    4. 宣告 Scanner 物件的名稱為 input 即可
    5. 顯示字樣『請使用者輸入 1~9 的數值: 』模樣即可
    6. 取得輸入的資料後,直接輸入一次 i 值 (假設用戶輸入的值就是 i)
    7. 設定 j 值等於 i 值。
    8. 反覆印出執行 8 次 j+=i 這樣的語法
    9. 關閉 main
    10. 關閉類別
  3. 程式設計:實在很簡單的語法:
    int i = input.nextInt();
    int j = i ;
    System.out.println ( i );
    System.out.println (j+=i);
    ....
    
  4. 編譯、執行與測試:執行的結果有點像這樣:
    C:\Users\dic\java>java unit04_2_1
    請輸入 1~9 的數值: 7 ↵
    7
    14
    21
    28
    35
    42
    49
    56
    63
    

你當然也能夠直接透過 *1, *2, *3... 之類的方法直接來處理九九乘法表,不過,我們希望的是,不要修改任何程式碼,只要給予與一個初始值, 系統就會自動的算出結果!這樣在設計上比較好一些。不過你應該還是要不滿意才是!因為,我們不知道是多少乘以多少~例如不知道是 7 x 1 = 7 這樣, 沒頭沒尾啊~如果是這樣的話,那就用底下的遞增、遞減運算子來處理看看。

  • 遞增、遞減運算子

上面的例子當中可能有包含兩個變數,那如果只有單一變數呢?例如 i = i + 1 的使用 1 為一個步階的運算結果,有沒有簡單的方式可以撰寫呢? 可以!就用 i++ 即可,也就是說『 i = i + 1 』可以直接寫成『 i++ 』的意思!不過,還有個 ++i 這樣的寫法耶~有什麼差別嘛?有的!請參考下表:

如下所示,假設 i 一開始的值是 2 喔!

運算子名稱範例說明
++var前置遞增int j = ++i
i=3, j=3
你可以看到, ++var 的 ++ 是在變數前面,可以假裝說成, var 需要 "先增加完畢之後" 才用到程式中
var++後繼遞增int j = i++
i=3, j=2
你可以看到, var++ 的 ++ 是在變數後面,可以假裝說成, var 在程式中用原本的數值處理完畢後,才累加 1
--var前置遞減int j = --i
i=1, j=1
你可以看到, --var 的 -- 是在變數前面,可以假裝說成, var 需要 "先減少完畢之後" 才用到程式中
var--後繼遞減int j = i--
i=1, j=2
你可以看到, var-- 的 -- 是在變數後面,可以假裝說成, var 在程式中用原本的數值處理完畢後,才減少 1

舉例來說,如果我們想要讓使用者輸入一個數值,例如 7 好了,假設變數 i 為 7 這個輸入的變數, 那麼透過 j 的初始值為 1 的時候,要印出九九乘法表會變這樣:

System.out.println ( i + " x " + j + " = " + i * j );
j++;
System.out.println ( i + " x " + j + " = " + i * j );
j++;
....

上面兩段程式碼要重複 9 次才行!有點蠢...其實可以將兩行改寫成為:

System.out.println ( i + " x " + j + " = " + i * j++ );
System.out.println ( i + " x " + j + " = " + i * j++ );
....

j 每次運算完畢會主動加上 1 ,這樣就簡單多了!

請將 unit04_2_1.java 另存新檔為 unit04_2_2.java,並且將主要的程式碼輸出部份改成上述的模樣,讓程式碼執行的結果會有點像底下這樣:
C:\Users\dic\java>java unit04_2_2
請輸入 1~9 的數值: 7 ↵
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63

4.3: 布林值的宣告與運算及選擇

布林值 (boolean value) 講的好像很難,其實最簡單的想法就是,這東西就是二選一,是對的還是錯的是非題! 舉例來說,我提出『 2 > 1 』這件事,你覺得是對的還是錯的?咦!是對的啊!所以,這時布林值就是『對的 (true, 真的意思)』, 那如果是『 2 < 1 』呢?廢話!當然就是錯的!此時布林值就是『錯的 (false, 假的意思)』!這樣理解否?

  • 比較運算子

要經過比較才知道真的還是假的 (對的還是錯的,true or false),所以,先來了解一下所謂的數值方面的比較運算子:

運算子兩數值的關係
N1 > N2N1 大於 N2 為 true,否則為 false
N1 >= N2N1 大於或等於 N2 皆為 true,否則為 false
N1 < N2N1 小於 N2 為 true,否則為 false
N1 <= N2N1 小於或等於 N2 皆為 true,否則為 false
N1 == N2N1 等於 N2 為 true,否則為 false
N1 != N2N1 不等於 N2 為 true,否則為 false

當中比較需要注意的是,當用來比較兩者的數值時,必須要使用兩個等號 (==),這是屬於邏輯判斷。 使用一個等號 (=) 是變數設定,不是邏輯判斷!新手在這裡經常搞錯!要注意!要注意!

至於兩數值透過這個比較運算子的運作後,會得到一個布林值 (就是 true 或 false 囉!),亦即不是對的就是錯的啊! 所以,如果透過 System.out.println 輸出,它就會輸出『 true 或 false 』這樣的字樣!讓我們來測試一下,當讓使用者輸入兩數值, 讓程式去判斷是大於、小於或等於呢?

  1. 分析問題:主要是讓使用者輸入兩個數值之後透過 (j>i) 或 (j<i) 這樣的語法來處理即可!
  2. 解決步驟:要先載入 Scanner ,然後讓使用者輸入兩個整數數值,之後來判斷囉!
    1. 匯入 Scanner 的套件 (java.util.Scanner)
    2. 宣告類別名稱為 unit04_3_1 (就是檔名)
    3. 開啟方法為 main 的程式
    4. 建立 Scanner 的物件,物件名稱就設定為 input 好了!
    5. 提示使用者輸入兩個整數數值,因此需要 input.nextInt() 兩次才行!
    6. 透過 System.out.println 的方式,將 (j>i) 或 (j<i) 或 (j==i) 共三行加入列印中!
    7. 關閉 main
    8. 關閉類別
  3. 程式設計:主要是透過類似下列的語法來處理 (共需要設計三條喔!)
    System.out.println(j + " > " + i + " : " + (j>i));
    ...
    System.out.println(j + " = " + i + " : " + (j==i));  // 左邊的一個 = 只是為了展示,右邊才是比較運算!
    
  4. 編譯、執行與測試:執行的結果會有點像這樣:
    C:\Users\dic\java>java unit04_3_1
    輸入兩個整數值,我來判斷一下誰大誰小啊!
    第一個數值: 50 ↵
    第二個數值: 29 ↵
    50 > 29 : true
    50 < 29 : false
    50 = 29 : false
    

如上所示,出現 true 的就代表答對了!出現 false 就代表錯誤啦!所以最終的答案就是 true,亦即 50 大於 29 囉! 但是回傳 true 或 false 也太蠢了!同時錯誤的也不用輸出吧!?那麼可以『判斷』或者說是『選擇』所需要的資料而已, 不需要的資料不用給予嘛?可以的!那就是使用『如果 (if)』的用法!

  • 初探選擇 if 的用法

你天天在做選擇!舉例來說,中午只剩下 100 塊錢,你想要吃什麼?吃賣噹噹?吃大雅?吃鍋燒意麵?當然要選個你的錢夠支出的餐點吧! 這就是選擇!選擇當然伴隨著很多的『意見』或『條件』,這些意見或者是條件就構成你會做出的選擇啊!

以 unit04_3_1.java 來說,目的是在『判斷』那一個數值比較大,給予的條件就是兩個數值而已,接下來就是透過 >, < == 來判斷, 並且選擇對的那個即可!那麼如何透過程式碼達成呢?就得要透過 if (如果) 來達成了。 if 的語法如下:

if (條件判斷) {
	條件判斷是『對的』情況下,就執行這一串程式碼的地方
}

如上所示,當條件判斷成功 (就是對的,就是真的,就是 true) 時,就執行大括號 { } 區塊當中的程式碼,若條件判斷不成功 (就是錯的,就是假的,就是 false) 時,就不執行任何程式碼而離開。非常簡單對吧!如果將上述的程式碼轉成中文,那就是:

如果 (這個條件底下是對的) 那就
	做這幾件事情
結束這個選擇

那麼如果將 unit04_3_1.java 修改成為只有印出正確的那個比較值,該如何處理呢?

  1. 分析問題:同樣是分析兩個數值,不過要加入選擇 (if) 的功能,所以原本的 true, false 會變成是條件判斷!
  2. 解決步驟:要先載入 Scanner ,然後讓使用者輸入兩個整數數值,之後來判斷囉!
    1. 匯入 Scanner 的套件 (java.util.Scanner)
    2. 宣告類別名稱為 unit04_3_2 (就是檔名)
    3. 開啟方法為 main 的程式
    4. 建立 Scanner 的物件,物件名稱就設定為 input 好了!
    5. 提示使用者輸入兩個整數數值,因此需要 input.nextInt() 兩次才行!
    6. 開始第一個 if 判斷 (j>i) ,如果成立,就開始選擇程式碼:
      • 顯示 j > i 即可。
    7. 結束此次選擇
    8. 同理,透過上述的功能持續判斷 j<i, j==i
    9. 關閉 main
    10. 關閉類別
  3. 程式設計:主要是透過類似下列的語法來處理 (共需要設計三條喔!)
    if ( j > i ) {
    	System.out.println(j + " > " + i );
    }
    ...
    
  4. 編譯、執行與測試:執行的結果會有點像這樣:
    C:\Users\dic\java>java unit04_3_2
    輸入兩個整數值,我來判斷一下誰大誰小啊!
    第一個數值: 50 ↵
    第二個數值: 230 ↵
    50 < 230
    

選擇 (if) 是個很重要的項目,未來我們會持續不斷的用到這個玩意兒。另外,除了直接判斷 true, false 之外,我們也能夠透過宣告變數來處置! 例如宣告一個名為結果 (result) 的變數,看看這個變數是真還是假這樣。

  • 布林值的宣告與使用

現在 Arduino 小設備很紅,鳥哥也曾經用這個小設備來控制小風扇的啟動與關閉。事實上就只是一個 true, false 的判斷而已。 現在假設讓您輸入一個 on 或 off 的開關,然後讓系統來判斷並顯示有沒有啟動電源這樣。我們可以透過 JOptionPane 的 showConfirmDialog 畫面來處理選擇! 基本選擇的方式為:

int selecting = JOptionPane.showConfirmDialog ( null, "訊息資料",
	"標題資料", JOptionPane.YES_NO_OPTION);
boolean on_off

有趣的是,當點選 YES 時,JOptionPane 會回傳 0 這個數值,而點選 NO 時,就會回傳 1 這個數值喔!好了,那讓我們來玩一玩啟動電源的程式碼吧!

  1. 分析問題:先顯示一個彈出式視窗,請使用者按下 YES 或 NO 的字樣,並根據回傳值來確認為 true 或 false,進一步顯示訊息即可。
  2. 解決步驟:透過 JOptionPane 的功能來處理的相關事宜而已,最後根據選擇來輸出訊息!
    1. 先匯入 javax.swing.JOptionPane 這個套件
    2. 宣告類別名稱為 unit04_3_3 (就是檔名)
    3. 開啟方法為 main 的程式
    4. 透過 JOptionPane.showConfirmDialog 的功能,提示使用者輸入 YES 或 NO 的按鈕
    5. 根據回傳值給予一個 on_off 的變數,若回傳 YES 則為 true 若回傳 NO 則為 false 的樣式。
    6. 根據 on_off 這個變數的結果,再以選擇來確認電源是啟動的還是關閉的。
    7. 關閉 main
    8. 關閉類別
  3. 程式設計:事實上因為我們使用的是單純從 showConfirmDialog 而來的資訊,傳來的是 0 或者是 1 而已。 不過,為了以後的程式設計功能,建議還是使用 on_off 來處置比較妥當。另外,變數使用前都需要初始化,因此, 一開始我們可能設定好了布林值與字串訊息後,先給 false 以及空字串較妥當。
    int selecting = JOptionPane.showConfirmDialog (null, "你要啟動電源嗎?", 
    	"確定啟動電源與否", JOptionPane.YES_NO_OPTION);
    boolean on_off = false;
    String vbmesg = "" ;
    if ( selecting == 0 ) { on_off = true; }
    ...
    if ( on_off == true  ) { vbmesg = "你選擇了開啟電源拉!"; }
    ...
    JOptionPane.showMessageDialog(...);
    
  4. 編譯、執行與測試:執行結果都是透過彈出式視窗來處理的喔!
    判斷電源開與關 判斷電源開與關 判斷電源開與關

上述程式碼有 ... 的地方請您自行補齊囉!最終跑出來的結果就是用滑鼠點選,不必使用鍵盤輸入囉!這樣是否還挺有趣的呢!?

  • 多重條件選擇

我們在現實生活中,總是會遇到『如果某A,以及某 B,同時成績都達 70 分,老爸就來買 switch 給你們玩』這樣的條件吧?或者是: 『如果某A,或者是某 B ,任何一個能夠幫忙做家事,那晚上我們就來吃大餐』這樣的條件吧?第一個是『兩個條件 (70分) 都得要達成』才算達到要求, 而第二個則是『只要有一個做家事就好』,就能夠達成要求!這兩個情況不同喔!那怎麼選擇判斷呢?

運算子兩條件的關係
Case1 && Case2Case1 為 true 且 Case2 同時為 true 時,最終才是 true。這是『同時成立』的情況
Case1 || Case2Case1 為 true 或 Case2 為 true 時,就會是 true,任何一個成立就算成立!

來個『開玩笑』的實驗題,假設擁有很多漫畫,加上沒有男女朋友,我們就稱呼他(她)為宅宅好了!讓使用者選擇兩次 YES 或 NO , 當兩次都是 YES 時,才會是宅宅~那該如何處理?

  1. 分析問題:因為要讓使用者有兩次挑選機會,所以需要兩次 JOptionPane.ConfirmDialog 才行!之後透過 && 的判定, 來決定是否為宅宅~
  2. 解決步驟:其實就是雙重條件都要成立!
    1. 先匯入 javax.swing.JOptionPane 這個套件
    2. 宣告類別名稱為 unit04_3_4 (就是檔名)
    3. 開啟方法為 main 的程式
    4. 透過 JOptionPane.showConfirmDialog 的功能,提示使用者輸入 YES 或 NO 的按鈕,需要兩次喔!
    5. 根據兩次回傳值,都為 0 (就是按下 YES) 時,輸出『你就是宅宅』,否則就輸出『還好!還不是宅宅!』
    6. 關閉 main
    7. 關閉類別
  3. 程式設計:其實最重要的就是雙重判別囉!
    if ( vbselect1 == 0 && vbselect2 == 0 ) {
    	vbmesg = "你果然是宅宅啊!";
    } else {
    	vbmesg = "還好!還不是宅宅!可以繼續努力脫魯!";
    }
    
  4. 編譯、執行與測試:程式運作的結果有點像這樣:
    宅宅判別器 宅宅判別器
    宅宅判別器 宅宅判別器

上面的題目單純在練習而已,沒有什麼意含喔!各位宅宅別亂想。

如果將上面的檔案重新儲存成 unit04_3_5.java,然後『當任何一個是 NO 時,就認定不是宅宅』時, 該如何更改程式碼?

4.4: 變數的型態轉換

我們知道浮點數 (有小數點的數值) 不能算餘數,但假設現在我們需要將浮點數去除小數點之後,算出該數值的餘數, 這時我們就得要進行數值型態的轉換!而常見的數值型態轉換其實還挺簡單的,將預計要使用的型態加在數值之前即可!

  • int i = (int) 10.3
  • double i = (double) 5

假設我要算出 103.5 去除小數點後,針對 33 進行餘數與商數的計算,該如何處理?

  1. 分析問題:基本上就是型態將 double 轉成整數而已~
  2. 解決步驟:透過上述的方法,將浮點數轉成整數 (int)number 即可!
    1. 宣告類別名稱為 unit04_4_1 (就是檔名)
    2. 開啟方法為 main 的程式
    3. 讓 i 宣告為 double ,且為 103.5 喔!
    4. 讓 j 宣告為 int ,且為 33 喔!
    5. 計算商數為 (int)i/j,計算餘數為 (int)i%j
    6. 透過 System.out.println 開始輸出商數與餘數
    7. 關閉 main
    8. 關閉類別
  3. 程式設計:重點確實只有 (int)i 而已!
    double i = 103.5;
    int j = 33;
    System.out.println ( "被除數 " + (int)i + " 與除數 " + j + " 運算的結果:");
    System.out.println ("商數為 " + (int)i/j + " 餘數為 " + (int)i % j);
    
  4. 編譯、執行與測試:程式執行的結果有點像這樣:
    C:\Users\dic\java>java unit04_4_1
    被除數 103 與除數 33 運算的結果:
    商數為 3 餘數為 4
    結果為: 103 = 3 x 33 ... 4
    
  • 字串轉為數值型態

將字串轉成數值之前我們就玩過了,這裡再次強調一下:

  • int i = Integer.parseInt(string)
  • long i = Long.parseLong(string)
  • float i = Float.parseFloat(string)
  • double i = Double.parseDouble(string)

現代人還挺注意健康的~因此有所謂的 BMI 值,這個 BMI 的公式是這樣的:

  • BMI = W / H2

其中 W 是體重,單位是『公斤』,H 是身高,單位是公尺。因此,當你具有 70 公斤重,且身高為 175 公分,這時你的 BMI 值就是: 70/(1.752), 大約是 22.86 左右。一般成人的 BMI 正常範圍約在 18.5 到 25 之間,亞洲人的體態比較瘦小,因此定義則為 18.5 ~ 24 之間。 現在我們讓使用者以彈出式視窗輸入身高與體重之後,計算出使用者的 BMI 值吧!

  1. 分析問題:彈出式視窗取得的資料為字串 (JOptionPane.showInputDialog),因此我們需要將這些字串資料轉成 double 的數值型態才行。
  2. 解決步驟:兩次彈出式視窗,一次輸入體重,需要定義為公斤,一次輸入身高,一般我們都使用公分為單位, 最終單位轉換我們在程式中處理!總之,就是讓使用者輸入身高體重就對了!
    1. 匯入 javax.swing.JOptionPane 的套件
    2. 宣告類別名稱為 unit04_4_2 (就是檔名)
    3. 開啟方法為 main 的程式
    4. 使用 JOptionPane.showInputDialog 的方式,輸入兩次資料,一次為身高一次為體重
    5. 將取得的字串轉為 double 的形式,並且開始計算 BMI
    6. 最後同樣以彈出式視窗告知使用者的 BMI 數值即可!
    7. 關閉 main
    8. 關閉類別
  3. 程式設計:其實重點就是要將輸入的字串變成數值而已~
    String vbw1 = JOptionPane.showInputDialog(null, "請輸入您的體重,單位為公斤:", 
    	"計算 BMI 值", JOptionPane.QUESTION_MESSAGE);
    ...
    double vbw = Double.parseDouble(vbw1);
    ...
    double bmi = vbw/vbh/vbh;
    ...
    
  4. 編譯、執行與測試:執行『 java unit04_4_2 』之後,會有這樣的情況:
    計算 BMI 值 計算 BMI 值 計算 BMI 值

這樣就設計出 BMI 的數值了。問題是,你怎麼知道這樣的 BMI 是好還是不好呢?根據我們剛剛談到的 18.5~25 之間是正常的, 因此,請完成底下的練習:

根據 unit04_4_2.java 的內容,加上一個選擇,當 BMI 計算所得低於 18.5 則顯示太瘦了, 若為 18.5 ~ 25 之間,則告知相當棒!若為大於 25 就稱呼為大胖子!加上這些訊息來處理結果, 而不是單純告知 BMI 而已!檔名就設定為 unit04_4_3.java 囉!

4.5: 運算子的運算優先順序

我們上頭提到許多的運算子,那麼若一行計算式裡面出現多個運算子的時候,到底是要先算誰呢?為什麼這麼說?舉例來說: 『 25 - 3 * 6 + 18 』答案是多少?我們當然知道是 "先乘除後加減" ,問題是,如果出現括號?如果出現 && 之類的運算子, 或者是 var++ 之類的,那誰先做?因此,就需要知道運算子的處理先後順序才行!

運算子說明 (優先序由上而下,越上面越優先)
括號優先例如 (5+3)*3 當中,括號內的加法先運算
++, --就是 var++, ++var, var--, --var 這樣的遞增遞減運算功能
(型別)進行資料型別轉換,例如 13 % (int)3.33
*, /, %這就是先乘除後加減的來由!當然是比加、減要更優先
+, -就是開始計算數值的加減
+字串的累加行為!
<< >>移位運算子
< > >= <=比較運算子
== !=比較運算子
&&邏輯運算的和 (and) 運算
||邏輯運算的或 (or) 運算

上面的運算子先有概念就好,我們會用到的大概就是加減乘除以及邏輯運算,其他的可以先不記憶。知道一堆運算子也沒啥意思, 學程式語言是為了要解決問題,所以,底下我們就來解決一些基本問題!

  • 讓使用者輸入三個木條長度,計算該三個木條能不能組成一個三角形?
  1. 分析問題:要組成三角形,一定要其中兩邊相加大於另一邊,否則就無法組成三角形。 所以,假設有 A, B, C 三個邊長,那麼 A+B > C, A+C > B, B+C > A,三個條件都要同時成立, 這時才會是三角形,否則就無法組成三角形。
  2. 解決步驟:因為有三個條件同時成立,因此 ( I && II && III ) 都要成立才行!
    1. 匯入 java.util.Scanner 套件
    2. 宣告類別名稱為 unit04_5_1 (就是檔名)
    3. 開啟方法為 main 的程式
    4. 建立名為 input 的 Scanner 物件
    5. 讓使用者輸入 3 個數值,請注意,每個數值中間用空格隔開即可!
    6. 透過三次 input.next() 的指令,直接提供『三個字串』,並以 Double.parseDouble(string) 的方法來處理, 產生三個 double 的數值。
    7. 以多重選擇的方式,判定是否為三角形的三個邊長。
      • 合乎規範就顯示『確實可以組成三角形』
      • 不合乎規範就顯示『錯誤!不能組成三角形』
    8. 關閉 main
    9. 關閉類別
  3. 程式設計:其實比較重要的只有兩個,一個是在一行輸入的資料內,只要有空白鍵,就可以使用 next() 的函數來取得個別的資料! 另一個則是使用 if 選擇的多重條件設計而已!
    String tmp1 = input.next();
    ....
    double a = Double.parseDouble(tmp1);
    ....
    if ( a+b>c && a+c>b && b+c>a ) {
    	System.out.println ("確實可以組成三角形");
    } else {
    	System.out.println ("錯誤!不能組成三角形");
    }
    
  4. 編譯、執行與測試:執行的結果有點像這樣
    C:\Users\dic\java>java unit04_5_1
    請輸入三角形的三個邊長,我來判斷是否可以組成三角形
    三個邊的長度,請用空白鍵隔開三個數值: 29 37 11↵
    確實可以組成三角形
    
    C:\Users\dic\java>java unit04_5_1
    請輸入三角形的三個邊長,我來判斷是否可以組成三角形
    三個邊的長度,請用空白鍵隔開三個數值: 1 2 3↵
    錯誤!不能組成三角形
    

重點確實就在 if 上面!如同上面的程式範例!查詢一下功能喔!

  • 體感溫度的計算

我們經常從中央氣象局的網站上面查詢到所謂的體感溫度,所謂的體感溫度與實際溫度、相對濕度及風速是有關係的。 簡單的關係有點像底下這樣:

  • e = RH/100 * 6.105 * exp ( 17.27*T/(237.7+T))
  • 體感溫度 = 1.04T + 0.2 * e - 0.65 * V -2.7
  • 其中 T 為溫度 (°C),V 為風速 (m/s),RH 為相對濕度 (%)。

上面的 e 比較難計算,因為還使用到 exp 這個奇怪的東西!沒關係!別害怕,你先記下來,可以使用『 Math.exp(計算式) 』來處理即可。 這個 Math 是 java 內建的數學函數,用他來推算此數值即可!那麼我們要輸入的參數就會有 RH, T 跟 V 三個而已~ 我們就來推算一下囉:

  1. 分析問題:體感溫度與相對濕度的關係相當高!我們得讓使用者輸入三個數值才行,分別是 RH, V 與 T。
  2. 解決步驟:讓使用者輸入三個數據後,將該數據帶入公式,如此而已。
    1. 匯入 java.util.Scanner 套件
    2. 宣告類別名稱為 unit04_5_2 (就是檔名)
    3. 開啟方法為 main 的程式
    4. 讓使用者輸入 3 個數值,請注意,每個數值中間用空格隔開即可!
    5. 透過三次 input.next() 的指令,直接提供『三個字串』,並以 Double.parseDouble(string) 的方法來處理,產生三個 double 的數值。
    6. 開始計算 e 值與體感溫度值
    7. 透過 System.out.println 開始輸出體感溫度的運算結果
    8. 關閉 main
    9. 關閉類別
  3. 程式設計:
    double vbe = vbrh / 100. * 6.105 * Math.exp(17.27*vbt/(237.7+vbt));
    double vbT = 1.04 * vbt + 0.2 * vbe - 0.65 * vbv - 2.7;
    System.out.println ("體感溫度為: " + vbT);
    
  4. 編譯、執行與測試:執行的結果有點像這樣:
    C:\Users\dic\java>java unit04_5_2
    我將開始根據你輸入的數據來計算體感溫度
    如果在台灣,請參考中央氣象局網站來取得底下的數值:
    https://www.cwb.gov.tw/V7/observe/real/NewObs.htm
    分別輸入溫度、相對濕度與風速: 27.5 73 1.6↵
    體感溫度為: 30.202948748535125
    

事實上,上面的公式使用上是有限制的!您可以查閱本章的參考文獻喔!

  • 找出 ASCII 對應的 code 數值 (char)

所有的文字基本上都是『圖形』,我們是透過某種編碼格式,透過將數值對應到『文字圖形』來取得正確的文字資料的。 那我們知道文字編碼錯誤可能會有亂碼,但是,有幾個英文字母的編碼倒是大家都會使用到!那就是所謂的 ASCII 編碼! 你可以從參考資料裡面找到 ASCII 文字圖形對應的數值~舉例來說,英文 A 對應的數值為 65,英文的 Z 對應到 90, 英文的 a 對應到 97,英文的 z 對應到 122 這樣。

讓我們撰寫一隻小程式來找出英文或數字的資料吧!

  1. 分析問題:要讓使用者輸入的數值來找出 ASCII 的文字圖形,但是要記得, ASCII 數值好像只到 250 左右, 而且英文的部份是有限制的喔!
  2. 解決步驟:
    1. 匯入 java.util.Scanner 套件
    2. 宣告類別名稱為 unit04_5_3 (就是檔名)
    3. 開啟方法為 main 的程式
    4. 讓使用者輸入一個數值,同時透過 nextInt() 函數取得整數值
    5. 宣告一個 char 型態的變數,例如 vbstring 這樣
    6. 讓 vbstring = (char)vbnu 之類的方式,將該 char 類型資料以數值模式輸出!
    7. 透過 System.out.println 開始輸出資料!
    8. 關閉 main
    9. 關閉類別
  3. 程式設計:
    int vbnu = input.nextInt();
    char vbstring;
    System.out.println ("數值: " + vbnu + ", 英文: " + (vbstring = (char)vbnu));
    System.out.println ("數值: " + (++vbnu) + ", 英文: " + (vbstring = (char)vbnu));
    ....
    
  4. 編譯、執行與測試:開始測試執行流程。過程可能會出現中文字型編碼錯誤的問題,請依據 javac 的可帶入的選項與參數處理編碼!
  5. C:\Users\dic\java>java unit04_5_3
    我將依據你輸入的數值來找出後續 10 個字元資料
    請輸入 65~75 及 97~107 之間的數字: 65↵
    數值: 65, 英文: A
    數值: 66, 英文: B
    數值: 67, 英文: C
    數值: 68, 英文: D
    數值: 69, 英文: E
    數值: 70, 英文: F
    

4.6: 參考資料

4.7: 課後練習

先查閱 1.3 小節的介紹,了解雲端系統的登入、繳交資料檔名等等的設計,然後再繼續底下的習題。 最終要上傳的檔案有:

  • unit04-4070CXXX-你的名字.docx
  • unit04_reverse.java (純文字檔)
  • unit04_ascii.java (純文字檔)
  • unit04_2point.java (純文字檔)
  • unit04_odd_or_even.java (純文字檔)
  • unit04_weight.java (純文字檔)
  1. 完成上課的習題內容回答:
    1. 當我在程式碼裡面寫入這行『 float mynumber = 3.14159; 』在編譯時會出現錯誤,請問,該如何修改才能避免錯誤?
    2. 『 i = i - 10 』的簡化寫法為何?
    3. 『 i = i + 1 』的簡化寫法為何?
    4. 有一個數值為 i ,另外一個數值為 j ,寫下來『當 i 大於 j 時,就顯示 "數值 i 比 j 大" 』的程式碼。
    5. 如何宣告一個布林值型態的變數名稱為 myturn ,且內容為『真』的語法
    6. 寫下以下的程式碼『當 i 大於等於 10 且 i 小於等於 20 的時候,就顯示 "數值確實在 10~20 之內" 的訊息』。
    7. 如何讓以下的程式碼變成可以取得小數點的雙精倍數數值 (亦即結果應該是 3.333 而不是 3 的意思)
      int i = 10;
      int j = 3;
      System.out.println ( i / j );
      
  2. 請模仿 unit04_2_2.java 的程式碼結果,一定要使用 --var 的語法 (不是 var++) 。當使用『 java unit04_reverse 』的指令時, 會輸出如下的結果:(hint: 設計 j 的初始值應該是多少呢?)
    C:\Users\dic\java>java unit04_reverse
    請輸入一個 1~9 的數值,我幫您計算逆轉 99 乘法表: 6 ↵
    6 x 9 = 54
    6 x 8 = 48
    6 x 7 = 42
    6 x 6 = 36
    6 x 5 = 30
    6 x 4 = 24
    6 x 3 = 18
    6 x 2 = 12
    6 x 1 = 6
    
  3. 請模仿 unit04_5_3.java 的程式碼,不過輸入與輸出變成彈出式視窗,且讓使用者輸入的數值為 65 到 90 之間,同時會輸出大小的英文。 重點在於,大寫從 65 開始,小寫從 97 開始,兩者相差 32 。執行『 java unit04_ascii 』時,會出現類似如下的資訊:
    找出 ASCII 文字圖形 找出 ASCII 文字圖形
  4. 直角三角形的斜邊長度為: (A2+B2)0.5,若換算為兩個座標 (x1, y1), (x2, y2) 的話,那麼斜邊的計算方式就會是: ( (x1-x2)2 + (y1-y2)2 )0.5 這樣的程式碼。計算平方根可以使用『 Math.pow(數值, 0.5) 』來處理。 現在,讓使用者輸入兩個座標,然後你幫他算出兩點之間的距離長度為多少!當執行『 java unit04_2point 』時,會出現類似這樣的文字:
    請輸入兩個座標,X1 與 Y1 之間以空格隔開即可。
    第 1 個座標: 1 5↵
    第 2 個座標: 27 10↵
    兩點長度為: 26.476404589747453
    
  5. 讓使用者輸入一個整數數值,該數值若為偶數則輸出『是偶數』,否則就顯示『是奇數』的文字。(注意:你可以使用 % 來判斷餘數是否為 0 即可。) 當執行『 java unit04_odd_or_even 』時,就會出現類似下列的動作:
    C:\Users\dic\java>java unit04_odd_or_even
    請輸入一個整數,我會判定他是奇數還是偶數: 3↵
    3是奇數
    
    C:\Users\dic\java>java unit04_odd_or_even
    請輸入一個整數,我會判定他是奇數還是偶數: 2↵
    2是偶數
    
  6. 讓使用者輸入 (1)性別與 (2)身高,並根據底下的公式來計算標準體重的範圍:
    • 男性 (公斤) = [ (身高-80) * 0.7 ] ± 10%
    • 女性 (公斤) = [ (身高-70) * 0.6 ] ± 10%
    請使用彈出式視窗的方式來讓使用者輸入資料,然後再以彈出式視窗來輸出標準體重的範圍!當使用『 java unit04_weight 』時, 會出現類似如下的圖示:
    計算標準體重的範圍 計算標準體重的範圍 計算標準體重的範圍 計算標準體重的範圍