Turbo C 2.0 運算子三大類 + 特殊運算子
運算子優先序決定「誰先結合運算元」;結合性決定同優先序「左結合」或「右結合」。
1. 算術運算子
| 運算子 | 功能 | 結合性 | 備註 |
+ | 加 / 一元正號 | 左 / 右 | |
- | 減 / 一元負號 | 左 / 右 | |
* | 乘 | 左 | |
/ | 除 | 左 | 整數除法截尾向零 |
% | 取模 (餘數) | 左 | 僅整數型,a % b 符號同 a |
++ | 遞增 (前綴/後綴) | 右 | 前綴回傳新值,後綴回傳舊值 |
-- | 遞減 (前綴/後綴) | 右 | 同上 |
整數除法與取模範例
15 / 2 == 7 /* 商 */
15 % 2 == 1 /* 餘數 */
/* -15 / 2 == -7, -15 % 2 == -1 (C99 規定向零截尾) */
字元參與算術運算 (自動提升為 int)
char m = 'c'; /* 99 */
char n = m + 'A' - 'a'; /* 99 + 65 - 97 = 67 = 'C' */
/* 小寫轉大寫:c + 'A' - 'a' */
2. 關係與邏輯運算子
| 運算子 | 功能 | 結果型別 | 結合性 |
< <= > >= | 小於/大於比較 | int (0/1) | 左 |
== != | 等於/不等於 | int (0/1) | 左 |
&& | 邏輯與 (短路) | int (0/1) | 左 |
|| | 邏輯或 (短路) | int (0/1) | 左 |
! | 邏輯非 | int (0/1) | 右 |
短路求值:&& 左運算元為 0 時不算右邊;|| 左運算元非 0 時不算右邊。
3. 位元運算子 (C 語言特色,貼近硬體)
| 運算子 | 功能 | 適用型別 | 結合性 |
& | 位元 AND | 整數/字元 | 左 |
| | 位元 OR | 整數/字元 | 左 |
^ | 位元 XOR | 整數/字元 | 左 |
~ | 位元 NOT (補數) | 整數/字元 | 右 |
<< | 左移 (低位補 0) | 整數/字元 | 左 |
>> | 右移 (高位補 0/符號位) | 整數/字元 | 左 |
位元 vs 邏輯運算子差異
int x = 7; /* 0111 */
x && 8 == 1 /* 邏輯與:非零且非零 → 真 (1) */
x & 8 == 0 /* 位元與:0111 & 1000 = 0000 */
移位非循環:高位/低位捨棄,另一端補 0 (無號) 或符號位 (有號)
4. 特殊運算子
| 運算子 | 名稱 | 功能 | 結合性 |
?: | 條件運算子 (三元) | cond ? expr1 : expr2,cond 真取 expr1 假取 expr2 | 右 |
& | 取址 (一元) | 回傳運算元位址 | 右 |
* | 間接取值 (一元) | 回傳位址所指物件值 | 右 |
, | 逗號運算子 | 左運算元求值後捨棄,回傳右運算元值 | 左 |
sizeof | 大小運算子 (一元) | 回傳型別/運算元大小 (位元組數),編譯期常數 | 右 |
+= -= *= /= %= | 複合賦值 | a += b 等價 a = a + b (a 僅評估一次) | 右 |
條件運算子範例
int x = 50;
int y = (x > 70) ? 100 : 0; /* y = 0 */
逗號運算子範例
int x = 50;
int y = (x = x - 5, x / 5); /* x=45, y=9 */
完整優先序表 (高 → 低)
1. () [] . -> /* 最高:函數呼叫、下標、結構成員 */
2. ++ -- + - ~ ! * & sizeof (型別) /* 一元運算子 */
3. * / % /* 乘法性 */
4. + - /* 加法性 */
5. << >> /* 移位 */
6. < <= > >= /* 關係 */
7. == != /* 等值 */
8. & /* 位元 AND */
9. ^ /* 位元 XOR */
10. | /* 位元 OR */
11. && /* 邏輯與 */
12. || /* 邏輯或 */
13. ?: /* 條件 */
14. = += -= *= /= %= &= ^= |= /* 賦值 (右結合) */
15. , /* 逗號 (最低) */
優先序實戰驗證
10 > 4 && !(100 < 99) || 3 <= 5
/* 步驟:
100 < 99 → 0
!0 → 1
10 > 4 → 1
1 && 1 → 1
3 <= 5 → 1
1 || 1 → 1 (結果 1)
*/
10 > 4 && !(100 < 99) && 3 <= 5
/* 1 && 1 && 1 → 1? 實際:1 && 1 = 1, 1 && 1 = 1 → 結果 1
原教材說 0 是錯誤,正確應為 1 */
避坑指南
- 別依賴優先序寫難讀代碼:多加括號
(a + b) * c。
- 移位量 ≥ 位寬 = UB:
x << 32 在 32-bit int 上未定義。
- 有號右移 = 實作定義:可攜程式僅對無號型別移位。
- 複合賦值單次評估:
a[i++] += 1 中 i++ 只執行一次。
- 逗號運算子別濫用:僅用於
for 迴圈多變數初始化/遞增等慣用語。