Minghsin University of Science and Technology
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try a Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

1

Local AI

--

Uedu Code

--

明新科大 AQI 70 24°C PM2.5 19
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 03

運算子與運算式

算術、比較、邏輯、指派運算子與運算順序
Interaction實作 20 minute(s)

Learning Objectives

  • 預測整數除法與 % 的結果(含負數),知道什麼時候要先轉成 double
  • 分辨前置與後置的遞增遞減,會用複合指定運算子
  • 用比較與邏輯運算子寫出 boolean 運算式,說明 && 與 || 的短路求值
  • 預測字串串接由左到右的結果,會用三元運算子依條件選值
  • 依優先順序判斷運算式的計算順序,會用 Math 的常用方法,並留意整數溢位

運算子與運算式

運算式(expression)是一段會算出一個值的程式碼,例如 price * qty、age >= 18、"你好," + name。 裡面的 *、>=、+ 叫運算子(operator),參與運算的值叫運算元(operand)。

Java 的運算子大多和數學課學的一樣,但有幾個地方和直覺不同,也是寫程式最常出錯的地方:

  • 7 / 2 的結果是 3,不是 3.5
  • x++ 和 ++x 都會讓 x 加 1,但運算式的值不一樣
  • 1 + 2 + "3" 是 "33","1" + 2 + 3 卻是 "123"
  • 兩個 int 相乘可能溢位,Java 不會提醒你

本課每個範例都用 println 把運算式的值印出來,先猜答案,再按「下一步」對照。

算術運算子

運算子 意思 範例 結果
+ 加 7 + 2 9
- 減 7 - 2 5
* 乘 7 * 2 14
/ 除 7 / 2 3(整數除法)
% 取餘數 7 % 2 1

整數除法:兩個運算元都是整數時,/ 的結果也是整數,小數部分直接捨去(往 0 的方向)。只要其中一個是 double,就會算出小數:

7 / 2            // 3
7.0 / 2          // 3.5
(double) 7 / 2   // 3.5:先把 7 轉成 7.0 再除
(double) (7 / 2) // 3.0:括號裡先做整數除法得到 3,再轉成 3.0,太晚了

取餘數 %:常用來判斷奇偶(n % 2 == 0)、取個位數(n % 10)、把秒數換成「幾分幾秒」。 結果的正負號跟著被除數(左邊):-7 % 3 是 -1,7 % -3 是 1。所以判斷奇數要寫 n % 2 != 0,寫成 n % 2 == 1 遇到負數會出錯。

除以零:整數除以 0 會拋出 ArithmeticException: / by zero;浮點數除以 0 不會拋出例外,而是得到 Infinity(或 NaN)。

整數除法與餘數

每一行都先猜答案再按「下一步」。特別注意第 9 行和第 10 行:括號的位置不同,結果就不同。

遞增、遞減與複合指定

x++ 與 ++x 都讓 x 加 1,差別在這個運算式本身的值:

寫法 名稱 運算式的值 之後 x 的值
x++ 後置遞增 加 1 之前的舊值 加 1
++x 前置遞增 加 1 之後的新值 加 1
x--、--x 遞減 同上,改成減 1 減 1

單獨寫成一行 x++; 時兩者沒有差別;只有把它放進更大的運算式(例如 int b = a++;)時才不一樣。 在同一個運算式裡對同一個變數做好幾次 ++,程式會很難讀,實際寫程式時請避免。

複合指定運算子把「運算後再存回去」合成一個:

寫法 等於
x += 5 x = x + 5
x -= 3 x = x - 3
x *= 2 x = x * 2
x /= 5 x = x / 5
x %= 3 x = x % 3

複合指定會自動強制轉型回左邊的型別:int count = 10; count += 2.7; 可以編譯,結果是 12(等於 count = (int) (count + 2.7)); 但寫成 count = count + 2.7; 會編譯錯誤。

前置與後置

第 5 行 b = a++ 和第 8 行 c = ++a 都讓 a 加 1,看框架裡 b 和 c 分別拿到舊值還是新值。第 15~20 行是一連串的複合指定,追蹤 total 每一步的值。

想一想:算術與遞增

1.

下面的程式會印出什麼?

public class Main {
    public static void main(String[] args) {
        System.out.println(17 / 5 + " " + 17 % 5 + " " + -17 % 5);
    }
}
2.

下面的程式會印出什麼?

public class Main {
    public static void main(String[] args) {
        int a = 5;
        int b = a++ + ++a;
        System.out.println(a + " " + b);
    }
}
3.

下面的程式執行結果是?

public class Main {
    public static void main(String[] args) {
        int a = 10, b = 0;
        System.out.println(a / b);
    }
}
第 1 次作答

比較與邏輯運算子

比較運算子的結果一定是 boolean(true 或 false):

運算子 意思 運算子 意思
== 等於 != 不等於
< 小於 <= 小於或等於
> 大於 >= 大於或等於

注意 = 是指派、== 才是比較。字串比較內容要用 s1.equals(s2),不要用 ==(第 04 課)。

邏輯運算子把 boolean 組合起來:

運算子 意思 什麼時候是 true
&& 而且(AND) 兩邊都是 true
|| 或者(OR) 至少一邊是 true
! 不是(NOT) 原本是 false

數學的 13 ≤ age ≤ 19 在 Java 要寫成 age >= 13 && age <= 19,寫成 13 <= age <= 19 會編譯錯誤。

短路求值(short-circuit evaluation):&& 的左邊是 false,結果一定是 false,右邊就不計算;|| 的左邊是 true,右邊也不計算。這可以拿來保護右邊:

boolean safe = n != 0 && 10 / n > 1;   // n 是 0 時,右邊的除法根本不會執行

& 與 | 用在 boolean 上時也是 AND、OR,但兩邊一定都會計算,不會短路。一般寫條件時請用 &&、||。

比較、邏輯與短路

第 14 行 n 是 0,如果右邊的 10 / n 被計算就會拋出例外,但程式安然通過。第 18 行和第 20 行都有 ++calls,看 calls 到底被加了幾次。

字串串接與三元運算子

+ 兩邊只要有一邊是字串,就是字串串接,另一邊會被轉成字串。+ 由左到右計算,所以位置很重要:

1 + 2 + "3"      // (1 + 2) + "3" → 3 + "3" → "33"
"1" + 2 + 3      // ("1" + 2) + 3 → "12" + 3 → "123"
"1" + (2 + 3)    // 括號先算 → "1" + 5 → "15"
'a' + 'b' + "c"  // 兩個 char 先相加成 int 195 → "195c"

印出計算結果時,記得把算式加上括號:"總分:" + (80 + 5) 才會印出 總分:85,沒有括號會變成 總分:805。

三元運算子(ternary operator)條件 ? 值1 : 值2:條件是 true 就得到值1,否則得到值2。它是一個運算式,可以直接放在指派或串接裡:

String result = score >= 60 ? "及格" : "不及格";
int bigger = x > y ? x : y;

兩個值的型別要相容。邏輯比較複雜時,改用第 04 課的 if-else 會比較好讀。

串接的順序與三元運算子

前五行只差在數字和字串的位置,輸出卻各不相同。後半段用三元運算子依條件選出一個值。

優先順序與 Math

一個運算式裡有好幾個運算子時,依優先順序決定先算哪個;優先順序相同時,依結合方向決定(大多由左到右)。由高到低(省略本課沒有介紹的位元運算子):

優先順序 運算子 結合方向
1 後置 x++、x-- 由左到右
2 前置 ++x、--x、正負號 +x、-x、!、強制轉型 (型別) 由右到左
3 *、/、% 由左到右
4 +、-(含字串串接) 由左到右
5 <、>、<=、>= 由左到右
6 ==、!= 由左到右
7 && 由左到右
8 || 由左到右
9 ? : 由右到左
10 =、+=、-= 等指派 由右到左

所以 2 + 3 * 4 是 14、10 - 4 - 3 是 3(由左到右)、a > 0 && b > 0 || c > 0 是 (a > 0 && b > 0) || c > 0。 記不得的時候就加括號,括號也讓別人更容易看懂。

Math 類別提供常用的數學方法,直接用 Math.方法名() 呼叫,不需要 import:

方法 說明 範例 結果
Math.abs(x) 絕對值 Math.abs(-8) 8
Math.pow(a, b) a 的 b 次方,回傳 double Math.pow(2, 10) 1024.0
Math.sqrt(x) 平方根,回傳 double Math.sqrt(9) 3.0
Math.max(a, b)、Math.min(a, b) 較大、較小的值 Math.max(3, 9) 9
Math.round(x) 四捨五入,double 回傳 long Math.round(2.5) 3
Math.floor(x)、Math.ceil(x) 無條件捨去、無條件進位,回傳 double Math.ceil(2.1) 3.0

Math.round 的規則是「加 0.5 再無條件捨去」,所以 Math.round(-2.5) 是 -2。Java 沒有 ** 次方運算子,要用 Math.pow。

優先順序、Math 與溢位

最後兩行計算 30 天有幾毫秒。第 16 行全部是 int 相乘,結果超過 21 億而溢位;第 17 行只是把第一個數字寫成 30L,整串乘法就改用 long 計算。

想一想:串接、短路與 Math

1.

下面的程式會印出什麼?

public class Main {
    public static void main(String[] args) {
        System.out.println(1 + 2 + "3" + 4 + 5);
    }
}
2.

下面的程式會印出什麼?

public class Main {
    public static void main(String[] args) {
        int x = 3;
        boolean r = x > 5 && ++x > 0;
        System.out.println(r + " " + x);
    }
}
3.

下面的程式會印出什麼?

public class Main {
    public static void main(String[] args) {
        System.out.println(Math.round(3.5) + " " + (int) 3.5 + " " + Math.ceil(3.1));
    }
}
第 1 次作答

動手寫:秒數換算

讀入一個總秒數,換算成「幾小時幾分幾秒」,再用三元運算子判斷有沒有超過一小時。這次的輸入是 3725。

你的輸出
預期輸出

重點回顧

  • 兩個整數相除是整數除法,小數往 0 捨去;要得到小數,先把其中一個轉成 double:(double) a / b
  • % 取餘數,正負號跟著被除數;整數除以 0 拋出 ArithmeticException,浮點數除以 0 得到 Infinity
  • x++ 的值是舊值、++x 的值是新值;複合指定 += 等會自動轉型回左邊的型別
  • 比較運算的結果是 boolean;&&、|| 會短路,左邊決定結果時右邊不計算
  • + 有一邊是字串就是串接,由左到右計算;印出算式結果要加括號
  • 三元運算子 條件 ? 值1 : 值2 依條件選值
  • 優先順序:一元 → * / % → + - → 比較 → && → || → ?: → 指派;不確定就加括號
  • Math.pow、Math.sqrt 回傳 double,Math.round 回傳 long;int 相乘可能溢位,數字大時改用 long
這一課完成了!
Next lesson:條件判斷
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。