運算符是構建程式邏輯的基石。本文深度解析 C 語言基本運算中的易錯點:整數除法截斷、取模負數規則、自增自減副作用、sizeof 編譯期計算特性、關系運算符優先級結合性,配合實戰代碼驗證。
int a = 1 / 2; // 結果 0,非 0.5!整數除整數得整數,直接截斷小數部分 double b = 10.5 + 10; // 10 隱式提升為 double,結果 20.5 int c = 10.5 + 1.7; // 雙精度相加後截斷為 int,結果 12(丟失精度) double d = (double)1 / 2; // 強制轉型至少一個操作數,結果 0.5
int / int → int,double / int → double7 % 3 → 1 -7 % 3 → -1 // 結果符號與被除數 (左操作數) 一致 7 % -3 → 1 -7 % -3 → -1
#include <stdio.h>
int main() {
int total_seconds;
printf("請輸入秒數: ");
scanf("%d", &total_seconds);
int minutes = total_seconds / 60;
int seconds = total_seconds % 60;
printf("%d 分 %d 秒\n", minutes, seconds);
return 0;
}
int a = 10; int b = a++ + ++a; // 未定義行為!C 標準不保證求值順序 // 不同編譯器可能產生 21、22 或其他結果
a = a++、b = a++ + ++a 皆為未定義行為 (UB)10++ 編譯錯誤,左值必須可修改int a = 10; int b = a++; // b=10, a=11 (後置:先用後增) int c = ++a; // a=12, c=12 (前置:先增後用) // 拆分為多條語句,明確副作用順序
sizeof 10; // 4 (int 常量) sizeof 10.9; // 8 (double 常量) int x; sizeof x; // 4 (變量類型 int) sizeof (int); // 4 (類型名**必須加括號**) // 陣列與指針的關鍵區別 int arr[10]; sizeof arr; // 40 (整個陣列大小,僅在陣列定義作用域有效) int *p = arr; sizeof p; // 4/8 (指針大小,32/64 位系統)
| 形式 | 括號要求 | 示例 |
|---|---|---|
sizeof 表達式 | 可省略 | sizeof x, sizeof 10 |
sizeof (類型名) | **必須加括號** | sizeof (int), sizeof (struct Node) |
int a = 3, b = 7; int r = b > a; // r = 1 (真) int s = a == b; // s = 0 (假) // C 語言真假規則:非 0 即真,0 為假 if (-5) // 真 if (3.14) // 真 if (0) // 假
() 括號最高> < >= <= 同級,左結合== != 同級,左結合,優先級**低於**上組2 == 3 > 1 → 2 == (3 > 1) → 2 == 1 → 0 (假) 4 > 3 > 2 → (4 > 3) > 2 → 1 > 2 → 0 (假) 3 + 4 > 8 - 2 → 7 > 6 → 1 (真)
#include <stdio.h>
int main() {
// 除法與類型提升
printf("1/2=%d, (double)1/2=%f\n", 1/2, (double)1/2);
// 取模符號規則
printf("-7%%3=%d, 7%%-3=%d\n", -7%3, 7%-3);
// sizeof 陣列 vs 指針
int arr[5] = {1,2,3,4,5};
int *p = arr;
printf("sizeof(arr)=%zu, sizeof(p)=%zu\n", sizeof(arr), sizeof(p));
// 關系運算鏈
printf("2==3>1=%d, 4>3>2=%d\n", 2==3>1, 4>3>2);
return 0;
}
輸出:
1/2=0, (double)1/2=0.500000 -7%3=-1, 7%-3=1 sizeof(arr)=20, sizeof(p)=8 2==3>1=0, 4>3>2=0
精通這些運算細節,能避開 90% 的 C 語言基礎級 Bug,為寫出正確、高效代碼奠定堅實基礎。