分段函數是數學建模與工程計算常見需求。本文以三段式函數為例,示範 if-else if-else 結構的正確寫法、邊界條件處理、輸入驗證與擴展性設計。
y = f(x) = x (0 ≤ x < 10) 10 (10 ≤ x < 20) x² + 3 (20 ≤ x < 40) 錯誤 (其他)
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int x;
long long y; // x² 可能超過 int 範圍
printf("輸入整數 x (0-39): ");
if (scanf("%d", &x) != 1) {
fprintf(stderr, "輸入無效:需為整數\n");
return EXIT_FAILURE;
}
if (x >= 0 && x < 10) {
y = x;
} else if (x >= 10 && x < 20) {
y = 10;
} else if (x >= 20 && x < 40) {
y = 1LL * x * x + 3; // 1LL 強制 long long 運算防溢位
} else {
fprintf(stderr, "錯誤:x 不在定義域 [0, 40) 內\n");
return EXIT_FAILURE;
}
printf("f(%d) = %lld\n", x, y);
return EXIT_SUCCESS;
}
| 技術點 | 說明 | 程式碼體現 |
|---|---|---|
| 邊界條件 | 區間包含關係明確 | x >= 0 && x < 10、x >= 10 && x < 20 互不重疊、無縫隙 |
| 型別擴展 | 防止 x*x 溢位 | long long y、1LL * x * x |
| 輸入驗證 | 檢查 scanf 回傳值 | if (scanf(...) != 1) |
| 錯誤輸出 | 使用 stderr、非零退出碼 | fprintf(stderr, ...)、EXIT_FAILURE |
當分段數多、邏輯固定時,用資料表驅動更易維護:
typedef struct { int min, max; long long (*func)(int); } Segment;
long long seg1(int x) { return x; }
long long seg2(int x) { return 10; }
long long seg3(int x) { return 1LL * x * x + 3; }
Segment table[] = {
{0, 9, seg1},
{10, 19, seg2},
{20, 39, seg3}
};
long long eval_piecewise(int x) {
for (size_t i = 0; i < sizeof(table)/sizeof(table[0]); i++) {
if (x >= table[i].min && x <= table[i].max)
return table[i].func(x);
}
return LLONG_MIN; // 錯誤標記
}
// 邊界測試
assert(eval_piecewise(0) == 0);
assert(eval_piecewise(9) == 9);
assert(eval_piecewise(10) == 10);
assert(eval_piecewise(19) == 10);
assert(eval_piecewise(20) == 403); // 20*20+3
assert(eval_piecewise(39) == 1524); // 39*39+3
// 異常測試
assert(eval_piecewise(-1) == LLONG_MIN);
assert(eval_piecewise(40) == LLONG_MIN);
分段函數實現看似簡單,實則考驗邊界條件嚴謹性、型別安全意識、錯誤處理規範。掌握「條件互斥窮盡、型別預留餘量、表格驅動解耦」三大原則,能讓條件邏輯既清晰又易擴展,是從寫腳本走向工程化的關鍵一步。