C 語言提供兩大分支機制:if 系列(條件靈活、支援任意表達式)與 switch(整數/字元等值匹配、跳轉表優化)。掌握其語法細節、巢狀規則與典型應用模式,是寫出清晰邏輯的關鍵。
if (表達式) {
語句序列;
}
// 後續程式碼
表達式非 0 → 執行大括號內語句;為 0 → 直接跳過。大括號可省略(單語句),但**強烈建議保留**以防維護時誤增行導致邏輯錯誤。
double score;
scanf("%lf", &score);
if (score >= 60)
printf("Pass!\n");
printf("Program over.\n"); // 無論及格與否都執行
if (表達式) {
語句A;
} else {
語句B;
}
非 0 執行 A,為 0 執行 B,二者必居其一。
if (score >= 60)
printf("Pass!\n");
else
printf("Fail!\n");
// 格式一:標準 else-if 階梯(推薦)
if (expr1) { ... }
else if (expr2) { ... }
else if (expr3) { ... }
else { ... }
// 格式二:省略大括號的緊湊寫法(單語句時可用)
if (expr1) stmt1;
else if (expr2) stmt2;
else stmt3;
int a; scanf("%d", &a);
int abs_a = abs(a); // 需 #include
if (abs_a < 10) printf("%d is 1 digit\n", a);
else if (abs_a < 100) printf("%d is 2 digits\n", a);
else if (abs_a < 1000) printf("%d is 3 digits\n", a);
else if (abs_a < 10000) printf("%d is 4 digits\n", a);
else if (abs_a < 32767) printf("%d is 5 digits\n", a);
else printf("Number too large\n");
條件**互斥且有序**,自上而下首次匹配即執行,效率與可讀性俱佳。
if (a > 0)
if (b > 0) printf("A");
else printf("B"); // else 配對給最近的 if (b>0)!
規則:`else` 永遠與**最近的未配對 `if`** 綁定。務必用大括號明確界定作用域:
if (a > 0) {
if (b > 0) printf("A");
} else {
printf("B"); // 明確屬於外層 if
}
switch (表達式) {
case 常量表達式1: 語句; break;
case 常量表達式2: 語句; break;
...
default: 語句; // 可選
}
int score; scanf("%d", &score);
switch (score / 10) { // 整數除法自動截斷
case 10:
case 9: printf("Grade A\n"); break;
case 8: printf("Grade B\n"); break;
case 7: printf("Grade C\n"); break;
case 6: printf("Grade D\n"); break;
default: printf("Grade E\n");
}
利用**多 case 共用代碼**(`case 10: case 9:`)簡化區間判斷。
switch (n1) {
case 1:
switch (n2) { // 內層 switch
case 11: ...; break; // 僅跳出內層
}
break; // 外層需自行 break
case 2: ...;
}
`break` **僅跳出它所在的最內層 switch/迴圈**。
int year; scanf("%d", &year);
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
printf("Leap year\n");
else
printf("Common year\n");
邏輯:能被 4 整除且非整百年,或能被 400 整除。
int y, m, d, sum = 0;
scanf("%d%d%d", &y, &m, &d);
switch (m) { // 累加前 m-1 月天數
case 12: sum += 30;
case 11: sum += 31;
case 10: sum += 30;
case 9: sum += 31;
case 8: sum += 31;
case 7: sum += 30;
case 6: sum += 31;
case 5: sum += 30;
case 4: sum += 31;
case 3: sum += 28;
case 2: sum += 31;
case 1: break; // 無需加
}
sum += d; // 加上當月天數
// 閏年且月份>2,補一天
if ((y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) && m > 2)
sum++;
printf("Day of year: %d\n", sum);
技巧:`switch` **故意省略 `break` 實現累加**(貫穿特性),從 12 月倒序加到輸入月份前一月,代碼極度緊湊。
| 場景 | 推薦 | 理由 |
|---|---|---|
| 區間判斷、浮點比較、複雜邏輯表達式 | if-else | switch 僅支援整數常量等值匹配 |
| 多固定值匹配(選單、狀態碼、字元指令) | switch | 編譯器優化為跳轉表,O(1) 查找;碼可讀性高 |
| 少量分支(2-3 條) | if-else | 無顯著效能差異,if 更靈活 |
| 需範圍判斷但值為整數 | if-else 或 switch+技巧 | 如分數等級可用 switch(score/10) |
選擇結構是程式決策的核心。if-else 以靈活著稱,處理範圍、複雜條件;switch 以高效著稱,處理離散值匹配。實戰中常混合使用:外層 `switch` 分發命令類型,內層 `if` 處理參數驗證。養成「加大括號、防貫穿、查類型」三部曲,能消除 90% 分支相關 Bug。