Home
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

4

Local AI

--

Uedu Code

--

Taipei AQI 57 · Taichung AQI 74 · Tainan AQI 63 · Kaohsiung AQI 64
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 04

運算子

算術、比較、邏輯與指定運算子,整數除法與優先順序
Interaction實作 20 minute(s)

Learning Objectives

  • 使用 + - * / % 做算術運算,說明整數除法與餘數的規則
  • 分辨 ++、-- 的前置與後置,使用 +=、-= 等複合指定運算子
  • 用比較運算子產生 bool,用 &&、||、! 組合條件
  • 說明短路求值,並用它避免除以 0 這類錯誤
  • 依優先順序判讀運算式,避開 = 與 ==、連續比較、小數相等這些常見錯誤

為什麼要學運算子

程式裡的計算與判斷都靠運算子(operator)完成:算總價用 *、判斷及格用 >=、檢查兩個條件用 &&。 運算子和它的運算元組成運算式(expression),每個運算式都會算出一個值。

int total = price * qty;          // 算術運算式,結果是數字
bool ok = total >= 100 && member; // 比較與邏輯運算式,結果是 bool

大部分運算子的意思和數學一樣,但 C++ 有幾個地方和數學課不同:整數相除會捨去小數、= 是指定而不是相等、 1 < x < 5 的意思也不是你想的那樣。這一課逐一看清楚。

算術運算子

運算子 意思 例子 結果
+ - * 加、減、乘 17 * 5 85
/ 除;兩邊都是整數時做整數除法 17 / 5 3
% 餘數,只能用在整數 17 % 5 2

整數除法的結果往 0 的方向捨去:17 / 5 是 3,-17 / 5 是 -3(不是 -4)。 餘數的正負號跟著被除數:-17 % 5 是 -2。兩者滿足 (a / b) * b + a % b == a。

只要有一邊是 double,就做小數除法:17 / 5.0 是 3.4。運算前,較小的型態會先轉成較大的型態(int 轉 double)。

% 很常用:n % 2 == 0 判斷偶數、n % 10 取個位數、秒數 % 60 換算時間。整數除以 0 或對 0 取餘數是未定義行為,程式通常會當掉。

整數除法與餘數

第 8~10 行對照整數除法與餘數;第 12~16 行用 / 和 % 把 3725 秒換算成時、分、秒,這是 % 最典型的用法。

遞增、遞減與複合指定

++ 讓變數加 1、-- 減 1,各有兩種寫法:

寫法 名稱 運算式的值
++i 前置 先加 1,取加完的值
i++ 後置 先取原本的值,再加 1

單獨寫成一句(i++;)時兩者效果相同;差別只在它放在更大的運算式裡(例如 x = i++;)。 不要在同一個運算式裡對同一個變數做好幾次 ++,例如 i++ + i++,結果沒有保證。

複合指定運算子是「運算後存回去」的簡寫:

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

前置、後置與複合指定

看第 7 行和第 10 行執行後的變數區:x 拿到的是加 1 之前的 5,y 拿到的是加 1 之後的 6,而 i、j 最後都是 6。第 17~22 行連續用複合指定改 score,每一步的值都看得到。

想一想:算術與遞增

1.

下面的程式會印出什麼?

cout << 19 / 4 << " " << 19 % 4;
2.

下面的程式會印出什麼?

int a = 3;
int b = a++ + 10;
cout << a << " " << b;
3.

下面的程式會印出什麼?

int n = 10;
n -= 3;
n *= 2;
n %= 4;
cout << n;
第 1 次作答

比較與邏輯運算子

比較運算子的結果是 bool:

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

邏輯運算子把條件組合起來:

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

cout 印 bool 預設是 1、0;先送出 boolalpha,之後就會印 true、false。 印比較或邏輯運算的結果時要加括號,例如 cout << (a < b);,原因在後面的優先順序。

比較與邏輯運算

第 9 行印出的是 1 0 1,第 10 行送出 boolalpha 之後,同樣的值改印成 true false。最後的閏年判斷把三個條件組合起來:能被 4 整除但不能被 100 整除,或者能被 400 整除。

短路求值

&& 和 || 由左而右計算,而且一知道答案就停:

  • A && B:A 是 false,整體一定是 false,B 不會執行
  • A || B:A 是 true,整體一定是 true,B 不會執行

這叫做短路求值(short-circuit evaluation)。它常用來保護後面的運算,例如先確認除數不是 0 再做除法:

if (count != 0 && total / count > 50)   // count 是 0 時,不會執行除法

如果把兩個條件的順序對調,count 是 0 時就會先做除法,造成錯誤。

右邊什麼時候會被跳過

isPositive 被呼叫時會印出「檢查 n」,並在右邊出現它的框架。注意第 12、14 行都沒有進入 isPositive,只有第 16 行進去了。最後的 if 因為 count 是 0,total / count 根本沒有執行。

優先順序與常見錯誤

一個運算式裡有好幾個運算子時,依優先順序決定先算哪個(由高到低,常用的部分):

順序 運算子
1 !、前置 ++ --、正負號 -x
2 * / %
3 + -
4 << >>(也是 cout、cin 用的符號)
5 < <= > >=
6 == !=
7 &&
8 ||
9 = += -= 等指定運算子

同一層的運算子大多由左而右計算(指定運算子例外,由右而左),所以 20 - 6 - 4 是 10。 不確定時就加括號,括號也讓別人更容易讀懂。

因為 << 的優先順序比比較運算子高,cout << a < b; 會變成 (cout << a) < b,無法編譯;要寫 cout << (a < b);。

三個常見錯誤:

  1. 把 == 寫成 =:if (x = 0) 是把 0 指定給 x,運算式的值是 0(false),而且 x 被改掉了。 g++ 加上 -Wall 時會對這種寫法提出警告,建議你加括號;不要忽略它
  2. 連續比較:1 < t < 5 會先算 1 < t 得到 true(1)或 false(0),再拿它和 5 比,結果幾乎永遠是 true。 要寫成 1 < t && t < 5
  3. 用 == 比較小數:0.1 + 0.2 == 0.3 是 false,因為小數在電腦裡有微小誤差。改成比較兩者的差距: fabs(a - b) < 1e-9(fabs 在 <cmath>)

優先順序與三個常見錯誤

注意第 10 行:if 的條件把 x 改成 0,條件是 false,所以第 11 行沒有執行,但 x 已經被改掉了。第 18 行的 sum 在變數區看起來是 0.3(只顯示 6 位有效數字),和 0.3 比較卻不相等。

想一想:條件與優先順序

1.

下面的程式會印出什麼?

int x = 5;
cout << (x > 3 && x < 5) << (x > 3 || x < 0) << !(x == 5);
2.

下面的程式會印出什麼?

int k = 0;
bool r = (k > 0) && (++k > 0);
cout << k << r;
3.

下面的程式會印出什麼?

int x = 5;
if (x = 0) cout << "A";
else cout << "B";
cout << x;
4.

下面的程式會印出什麼?

cout << 2 + 6 / 2 * 3;
第 1 次作答

動手寫:找零

商品 630 元,顧客付 1000 元。用 / 算出每種面額要找幾張(個),用 % 算出剩下還要找的錢,面額由大到小:100 元、50 元、10 元。預期輸出:

找零 370 元
100 元:3
50 元:1
10 元:2
你的輸出
預期輸出

重點回顧

  • 兩個整數相除是整數除法,往 0 捨去;% 取餘數,正負號跟著被除數;有 double 參與就做小數除法
  • i++ 先取值再加 1,++i 先加 1 再取值;單獨一句時相同;x += 5 是 x = x + 5 的簡寫
  • 比較運算子產生 bool;&& 兩邊都要成立、|| 一邊成立即可、! 取反;boolalpha 讓 bool 印成 true/false
  • 短路求值:&& 左邊 false、|| 左邊 true 時,右邊不會執行,可以用來避免除以 0
  • 先乘除、後加減、再比較、再邏輯,最後指定;不確定就加括號
  • 比較用 == 不是 =;範圍判斷寫成 a < x && x < b;小數不要用 == 比較,改看差距
這一課完成了!
Next lesson:流程控制
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。