switch 實戰:運費計算程式中 if-else 與 switch 邏輯差異分析if-else 版本邏輯缺陷if (s < 250) d = 0;
if (250 <= s < 500) d = 0.02; // 錯誤:C 不支援鏈式比較,實為 (250 <= s) < 500 → 0 或 1 < 500 → 恆真
if (500 <= s < 1000) d = 0.05; // 同理錯誤
...
C 語言無鏈式比較,250 <= s < 500 等價於 (250 <= s) < 500。250 <= s 結果為 0 或 1,必定 < 500,導致所有 s >= 250 都進入此分支,折扣錯誤。
if-else if 寫法if (s < 250) d = 0;
else if (s < 500) d = 0.02;
else if (s < 1000) d = 0.05;
else if (s < 2000) d = 0.08;
else if (s < 3000) d = 0.10;
else d = 0.15;
switch 版本邏輯分析if (s >= 3000) c = 12;
else c = s / 250; // 整數除法:0~11 對應 0~2750km 每 250km 一級
switch (c) {
case 0: d = 0; break;
case 1: d = 2; break; // 250-499km → 2%
case 2: case 3: d = 5; break; // 500-749km → 5%
case 4: case 5: case 6: case 7: d = 8; break; // 1000-1999km → 8%
case 8: case 9: case 10: case 11: d = 10; break; // 2000-2999km → 10%
case 12: d = 15; break; // >=3000km → 15%
}
f = p * w * s * (1 - d/100.0);
case 穿透多個 case 連寫無 break,共用同一段代碼。上例中 case 2: case 3: 皆執行 d=5,實現區間合併。
if 版本因鏈式比較錯誤,導致 s>=250 全部折扣 2%。switch 版本邏輯正確,區間映射精確。switch 使用最佳實踐case 以 break 結尾**,除非刻意穿透(加註釋 // fallthrough)。default:** 處理預期外值,防呆。double discount[] = {0, 2, 5, 5, 8, 8, 8, 8, 10, 10, 10, 10, 15};,d = discount[c]; 更簡潔。#include
#include
int main(void) {
int s;
double p, w, d, f;
printf("輸入運費/公里, 重量, 距離(公里): ");
if (scanf("%lf,%lf,%d", &p, &w, &s) != 3) return 1;
int c = (s >= 3000) ? 12 : s / 250;
static const double disc[] = {0, 2, 5, 5, 8, 8, 8, 8, 10, 10, 10, 10, 15};
d = disc[c];
f = p * w * s * (1 - d / 100.0);
printf("總運費: %.2f\n", f);
return 0;
}