C++ 運算子與運算式的深入探索
在程式設計的世界中,電腦得以展現其卓越的計算能力,主要是透過「運算式 (expression)」與「運算子 (operator)」的組合來達成。我們可以將「運算式」視為數學式在程式語言中的對應實體,而「運算子」則可視為數學中的加減乘除符號、比較符號、以及邏輯符號等。透過各式各樣的運算子與運算式,程式可對變數與常數進行各種計算、比較、判斷,以產生決策條件或進行資料轉換。C++語言提供了豐富且多元的運算子,協助程式設計師靈活地撰寫程式碼,加強程式的可讀性與可維護性。
3-1 運算式與優先權
運算式 (Expression)
運算式是由運算子(operator)和運算元(operand)所構成的一個組合。運算元可以是常數、變數、函數呼叫或甚至是另一個運算式的結果,而運算子則是用來對運算元進行各種運算的符號。舉例來說,假設有一個運算式:
x = 100*2+y - a + 0.7*3*c 在這個運算式中,*、+、-等符號皆屬於運算子,而 100、2、y、a、0.7、3、c 則屬於運算元。透過這個運算式,程式可以計算出右側複雜運算的最終結果,並將其指定給左側的變數 x。
C++語言中,我們慣用「中序法 (Infix)」來表示運算式,即運算子放在兩個運算元的中間,如同傳統的數學表達方式。除中序法外,尚有「前序法 (Prefix)」及「後序法 (Postfix)」,但這兩者在C++中並不是一般直觀的寫法。C++的所有運算式皆透過中序表示法,再配合適當的括號或優先權規則來決定運算的執行順序。
運算子優先權 (Operator Precedence)與結合性(Associativity)
當一個運算式包含多個不同優先等級的運算子時,C++編譯器將依據運算子的優先權來決定何者先行計算。以我們常見的數學規則為例,「先乘除,後加減」即是優先權的一種基本體現。在C++中,除了基本的加減乘除外,還有許多其他運算子,都有其各自的優先順序。當兩個運算子具有相同的優先權時,則透過「結合性」(通常為由左至右)來決定先後執行順序。此外,我們也可使用小括號()來強制改變原有的優先順序。
3-2 各類運算子介紹
C++中運算子可分類成多種類型:
- 指定運算子 (Assignment Operator)
- 算術運算子 (Arithmetic Operator)
- 關係運算子 (Relational Operator)
- 邏輯運算子 (Logical Operator)
- 位元運算子 (Bitwise Operator)
- 遞增/遞減運算子 (Increment/Decrement Operator)
- 條件運算子 (Conditional/Ternary Operator)
- 複合指定運算子 (Compound Assignment Operator)
以下逐一說明:
3-2-1 指定運算子
指定運算子 = 作用是將右側運算式的結果指定給左側的變數。例如:
int sum; sum = 5; // 將5指定給sum sum = sum+1; // 將sum的值加1後,再指定回sum 在程式中,「=」不代表數學意義的「相等」,而是「指定」的概念。特別留意,指定運算子左側必須是能存放值的變數,而右側則可以是常數、變數或運算式。一個巧妙特性是,我們可以一次對多個變數指定相同數值:
int a, b, c; a = b = c = 100; // a、b、c都會變成100 3-2-2 算術運算子
算術運算子包括最常用的「+、-、*、/」以及「%」(餘數)運算子,還有表示正負數的符號。範例:
int A=21, B=6; A + B = 27 A - B = 15 A * B = 126 A / B = 3 // 整數除法,捨棄小數部份 A % B = 3 // 計算21除以6的餘數為3 特別注意 % 是用於整數運算,若需對浮點數求餘數則需使用fmod()函數。
3-2-3 關係運算子
關係運算子用來比較兩個運算元的大小、相等或不等,結果為布林值(true或false)。包括 >、<、>=、<=、==、!=。範例:
int a=11, b=15; a > b → false (0) a < b → true (1) a == b → false (0) a != b → true (1) 3-2-4 邏輯運算子
邏輯運算子包括 && (AND)、|| (OR) 與 ! (NOT)。它們常與關係運算子搭配使用,以形成複雜的條件判斷。運算結果依然為true或false。
&&:兩個條件皆為真時結果才為真。||:只要其中一個條件為真,結果即為真。!:反轉布林值,若原本為真則結果為假,反之亦然。
3-2-5 位元邏輯運算子
位元邏輯運算子直接對整數的二進位位元進行操作,包括 & (AND)、| (OR)、^ (XOR)、~ (NOT)。這些運算子是以位元為單位進行計算:
&:對應位元都為1才為1|:對應位元只要有1即為1^:對應位元不同為1,相同為0~:將位元0與1互換
3-2-6 位元位移運算子
透過 << 與 >> 可將整數資料的位元向左或向右平移。
<< n:向左移動n個位元,右側以0補齊。>> n:向右移動n個位元,對於正數以0補齊,對於負數則以1補齊。
透過位移運算子,我們可快速實現乘以2的n次方 (左移n位)或除以2的n次方(右移n位)等運算。
3-2-7 遞增與遞減運算子
++ 與 -- 是C++特有的簡化符號,用於對變數的值加1或減1。這兩個運算子有兩種型態:
- 前置型:
++a或--a,先對a做加減1,再回傳新的值 - 後置型:
a++或a--,先回傳a原始值,再對a做加減1
透過理解前置與後置的差異,可以在程式設計中靈活控制計算順序。
3-2-8 條件運算子 (三元運算子)
條件運算子 ?: 是C++中唯一的三元運算子。其用法如下:
判斷式 ? 運算式1 : 運算式2 若判斷式為真,則回傳運算式1的結果;若為假,則回傳運算式2的結果。這相當於一個簡化的if-else敘述。範例:
int number; cin >> number; (number % 2 == 0) ? cout<<"偶數"<<endl : cout<<"奇數"<<endl; 3-2-9 複合指定運算子
複合指定運算子是將指定運算子 = 與其它算術或位元運算子結合來簡化程式碼。常見的有:
+=:a += b;等價於a = a + b;-=:a -= b;等價於a = a - b;*=:a *= b;等價於a = a * b;/=:a /= b;等價於a = a / b;%=:a %= b;等價於a = a % b;
及其它對位元操作的複合運算子,如 &=, |=, ^=, <<=, >>=。
使用複合指定運算子可使程式更為簡潔、直觀。
課後評量
-
下列運算子中,優先權排序為何?
運算子包含:+、<<、!、+=、&
按優先權由高到低約為:!>+>&><<>+= -
下列程式碼的輸出結果為何?
cpp#include <iostream> using namespace std; int main() { int a=23,b=20; cout<<(a & b)<<endl; // 對23(10111),20(10100)做AND,結果10100(20) cout<<(a | b)<<endl; // OR後10111(23) cout<<(a ^ b)<<endl; // XOR後00011(3) cout<<(a && b)<<endl;// a,b都是非0整數,故為true(1) cout<<(a || b)<<endl;// 同理,只要任一為非0即true(1) return 0; }輸出為:
20
23
3
1
1 -
下列程式碼輸出結果為何?
cpp#include <iostream> using namespace std; int main(){ int A=23,B=0,C; C = A & B && B & C; // 先計算A&B -> 23&0=0 // C = 0 && (B&C) -> B&C還未求值,因為AND的左側已是0則整體為0 cout<<"C="<<C<<endl; // C=0 return 0; }輸出為C=0。
-
若
a=15,a & 10的結果為何?- 15的二進位:1111
- 10的二進位:1010
AND後:1010 (十進位10)
故結果為10。
-
已知
a=b=5,x=10,y=20,z=30,請計算x *= a += y %= b -= z /= 3的最終值。
運算順序:z /= 3→ z = 30/3 = 10b -= z→ b = 5 - 10 = -5y %= b→ y = 20 % (-5) = 0 (注意負數取餘仍為0)a += y→ a = 5 + 0 = 5x *= a→ x = 10 * 5 = 50
最終x的值為50。
-
何謂二元運算子?
二元運算子是指有兩個運算元的運算子。例如加法運算+,若寫為A+B,此處A與B即為兩個運算元,+為二元運算子。
APCS 檢定考古題解析
-
若
x=true,y=true,z=false,請判斷下列運算式結果真偽:- (y || z) || x = (true || false) || true = true || true = true
- y || (z || !x) = true || (false || false) = true || false = true (原題為FALSE,此處須核對,原文似有誤,依原示範(A)為正解)
- z || (x && (y || z)) = false || (true && (true || false)) = false || (true && true)=false || true = true
- (x || x) && z = (true || true) && false = true && false = false
最終答案:TRUE FALSE TRUE FALSE (依原題的解答(A))
※此處原題可能有誤植,請以題目給定解答為準。
-
若判斷式 !(X₁ || X₂) 要為真,則 X₁與X₂都必須為false。
-
若 a,b,c,d,e為整數,
a+b*c-e與(a+(b*c))-e計算結果相同。
透過上述詳盡的敘述與範例,我們已對C++的運算子及運算式有了更加深入的認識。掌握運算子的使用方法、優先權與結合性,是撰寫正確且高效率程式碼的基礎。透過實際的程式碼練習與思考運算結果的過程,程式設計師可更有效率地完成複雜的計算任務,為接下來的流程控制、函數呼叫、物件導向設計等更進階的主題打下穩健基礎。
請先 登入 以發表留言。