C++ 運算子與運算式的深入探索

在程式設計的世界中,電腦得以展現其卓越的計算能力,主要是透過「運算式 (expression)」與「運算子 (operator)」的組合來達成。我們可以將「運算式」視為數學式在程式語言中的對應實體,而「運算子」則可視為數學中的加減乘除符號、比較符號、以及邏輯符號等。透過各式各樣的運算子與運算式,程式可對變數與常數進行各種計算、比較、判斷,以產生決策條件或進行資料轉換。C++語言提供了豐富且多元的運算子,協助程式設計師靈活地撰寫程式碼,加強程式的可讀性與可維護性。


3-1 運算式與優先權

運算式 (Expression)
運算式是由運算子(operator)和運算元(operand)所構成的一個組合。運算元可以是常數、變數、函數呼叫或甚至是另一個運算式的結果,而運算子則是用來對運算元進行各種運算的符號。舉例來說,假設有一個運算式:

 
cpp
x = 100*2+y - a + 0.7*3*c

在這個運算式中,*+-等符號皆屬於運算子,而 1002ya0.73c 則屬於運算元。透過這個運算式,程式可以計算出右側複雜運算的最終結果,並將其指定給左側的變數 x

C++語言中,我們慣用「中序法 (Infix)」來表示運算式,即運算子放在兩個運算元的中間,如同傳統的數學表達方式。除中序法外,尚有「前序法 (Prefix)」及「後序法 (Postfix)」,但這兩者在C++中並不是一般直觀的寫法。C++的所有運算式皆透過中序表示法,再配合適當的括號或優先權規則來決定運算的執行順序。

運算子優先權 (Operator Precedence)與結合性(Associativity)
當一個運算式包含多個不同優先等級的運算子時,C++編譯器將依據運算子的優先權來決定何者先行計算。以我們常見的數學規則為例,「先乘除,後加減」即是優先權的一種基本體現。在C++中,除了基本的加減乘除外,還有許多其他運算子,都有其各自的優先順序。當兩個運算子具有相同的優先權時,則透過「結合性」(通常為由左至右)來決定先後執行順序。此外,我們也可使用小括號()來強制改變原有的優先順序。


3-2 各類運算子介紹

C++中運算子可分類成多種類型:

  1. 指定運算子 (Assignment Operator)
  2. 算術運算子 (Arithmetic Operator)
  3. 關係運算子 (Relational Operator)
  4. 邏輯運算子 (Logical Operator)
  5. 位元運算子 (Bitwise Operator)
  6. 遞增/遞減運算子 (Increment/Decrement Operator)
  7. 條件運算子 (Conditional/Ternary Operator)
  8. 複合指定運算子 (Compound Assignment Operator)

以下逐一說明:


3-2-1 指定運算子

指定運算子 = 作用是將右側運算式的結果指定給左側的變數。例如:

 
cpp
int sum; sum = 5; // 將5指定給sum sum = sum+1; // 將sum的值加1後,再指定回sum

在程式中,「=」不代表數學意義的「相等」,而是「指定」的概念。特別留意,指定運算子左側必須是能存放值的變數,而右側則可以是常數、變數或運算式。一個巧妙特性是,我們可以一次對多個變數指定相同數值:

 
cpp
int a, b, c; a = b = c = 100; // a、b、c都會變成100

3-2-2 算術運算子

算術運算子包括最常用的「+、-、*、/」以及「%」(餘數)運算子,還有表示正負數的符號。範例:

 
cpp
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)。包括 ><>=<===!=。範例:

 
cpp
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++中唯一的三元運算子。其用法如下:

 
cpp
判斷式 ? 運算式1 : 運算式2

若判斷式為真,則回傳運算式1的結果;若為假,則回傳運算式2的結果。這相當於一個簡化的if-else敘述。範例:

 
cpp
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;

及其它對位元操作的複合運算子,如 &=, |=, ^=, <<=, >>=

使用複合指定運算子可使程式更為簡潔、直觀。


課後評量

  1. 下列運算子中,優先權排序為何?
    運算子包含:+<<!+=&
    按優先權由高到低約為:! > + > & > << > +=

  2. 下列程式碼的輸出結果為何?

     
    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

  3. 下列程式碼輸出結果為何?

     
    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。

  4. a=15a & 10 的結果為何?

    • 15的二進位:1111
    • 10的二進位:1010
      AND後:1010 (十進位10)

    故結果為10。

  5. 已知 a=b=5, x=10, y=20, z=30,請計算 x *= a += y %= b -= z /= 3 的最終值。
    運算順序:

    • z /= 3 → z = 30/3 = 10
    • b -= z → b = 5 - 10 = -5
    • y %= b → y = 20 % (-5) = 0 (注意負數取餘仍為0)
    • a += y → a = 5 + 0 = 5
    • x *= a → x = 10 * 5 = 50

    最終x的值為50。

  6. 何謂二元運算子?
    二元運算子是指有兩個運算元的運算子。例如加法運算+,若寫為 A+B,此處AB即為兩個運算元,+為二元運算子。


APCS 檢定考古題解析

  1. 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))

    ※此處原題可能有誤植,請以題目給定解答為準。

  2. 若判斷式 !(X₁ || X₂) 要為真,則 X₁與X₂都必須為false。

  3. 若 a,b,c,d,e為整數,a+b*c-e(a+(b*c))-e 計算結果相同。


透過上述詳盡的敘述與範例,我們已對C++的運算子及運算式有了更加深入的認識。掌握運算子的使用方法、優先權與結合性,是撰寫正確且高效率程式碼的基礎。透過實際的程式碼練習與思考運算結果的過程,程式設計師可更有效率地完成複雜的計算任務,為接下來的流程控制、函數呼叫、物件導向設計等更進階的主題打下穩健基礎。

創作者介紹
創作者 AI革命家 REVOLUTIONARY 的頭像
AI革命家

AI革命家 REVOLUTIONARY

AI革命家 發表在 痞客邦 留言(0) 人氣( 0 )