核心思想
switch 语句的核心是整型表达式的匹配,它计算一个表达式的值,然后与 case 标签中的值进行比较,一旦找到匹配的 case,程序就会执行该 case 后面的所有代码,直到遇到 break 语句为止。

(图片来源网络,侵删)
对于成绩等级判断,我们需要将连续的分数范围(如90-100)转换为离散的整数值,以便与 case 标签匹配,最常用的方法就是除法取整。
经典方法 - 使用整数除法
这是最常见、最符合 switch 语句设计思想的方法。
算法分析
我们假设分数 score 是一个整数(0-100),我们可以用 score / 10 来得到一个代表区间的整数:
score在 [90, 100] 区间:score / 10的结果是9或10。score在 [80, 89] 区间:score / 10的结果是8。score在 [70, 79] 区间:score / 10的结果是7。- ...以此类推。
这样,一个连续的分数范围就被巧妙地转换成了几个离散的整数值,完美契合了 switch 的需求。

(图片来源网络,侵删)
代码实现
#include <stdio.h>
int main() {
int score;
printf("请输入学生的成绩 (0-100): ");
scanf("%d", &score);
// 对输入进行有效性检查
if (score < 0 || score > 100) {
printf("输入无效,请输入0-100之间的整数,\n");
return 1; // 非正常退出
}
// 使用 switch 语句判断等级
switch (score / 10) {
case 10:
case 9:
printf("成绩等级: A\n");
break; // 必须使用 break 来跳出 switch,否则会继续执行下一个 case
case 8:
printf("成绩等级: B\n");
break;
case 7:
printf("成绩等级: C\n");
break;
case 6:
printf("成绩等级: D\n");
break;
// 处理 0-5 的情况
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
printf("成绩等级: E\n");
break;
// default 是一个可选的分支,当没有任何 case 匹配时执行。
// 在这个例子中,由于我们已经有 if 检查,所以这里不会执行。
// 但为了代码的健壮性,保留它是好习惯。
default:
printf("未知错误,\n");
break;
}
return 0;
}
代码关键点解析
switch (score / 10): 这是switch的核心,我们计算score / 10的值,然后用这个值去匹配下面的case。case 10:和case 9:: 注意这里没有break。score是100,score/10是10,会匹配case 10:,然后因为没有break,会继续向下执行,直到遇到case 9:的代码块,这样就实现了90-100分都为A等级的效果,这被称为“贯穿”(fall-through),在这里是特意为之。break;: 每个case代码块的末尾都需要一个break;来终止switch结构,防止程序“掉入”下一个case。default::score / 10的值不与任何一个case匹配(score是负数或大于100,但我们用if已经处理了),就会执行default后面的代码,它就像if-else里的else一样。- 输入验证: 在
switch之前加入if语句检查输入是否合法,是一个非常好的编程习惯,可以避免很多意外错误。
使用字符 (ASCII码)
switch 语句也可以作用于 char 类型,因为 char 在本质上是整型(存储的是ASCII码),我们可以让用户输入一个字母(如 'A', 'B'),然后直接用 switch 判断。
这种方法不用于计算分数,而是用于处理已知的、离散的选项。
代码示例
#include <stdio.h>
int main() {
char grade;
printf("请输入成绩等级 (A, B, C, D, E): ");
scanf(" %c", &grade); // 注意 %c 前面的空格,用于跳过之前输入可能留下的换行符
switch (grade) {
case 'A':
printf("优秀!\n");
break;
case 'B':
printf("良好!\n");
break;
case 'C':
printf("及格!\n");
break;
case 'D':
printf("及格!\n");
break;
case 'E':
printf("不及格!\n");
break;
default:
printf("输入的等级无效!\n");
break;
}
return 0;
}
特点
- 适用场景: 适用于选项是固定字符的情况,比如菜单选择。
- 不适用场景: 不适合从分数推导出等级的场景,因为它无法处理“90分以上是A”这样的范围逻辑。
switch vs. if-else if
对于“成绩等级判断”这个问题,if-else if 也是一个非常直观和强大的选择。
if-else if 实现
#include <stdio.h>
int main() {
int score;
printf("请输入学生的成绩 (0-100): ");
scanf("%d", &score);
if (score < 0 || score > 100) {
printf("输入无效,\n");
} else if (score >= 90) {
printf("成绩等级: A\n");
} else if (score >= 80) {
printf("成绩等级: B\n");
} else if (score >= 70) {
printf("成绩等级: C\n");
} else if (score >= 60) {
printf("成绩等级: D\n");
} else {
printf("成绩等级: E\n");
}
return 0;
}
如何选择?
| 特性 | switch |
if-else if |
|---|---|---|
| 判断依据 | 精确匹配 (等于某个值) | 范围比较 (大于、小于、等于) |
| 可读性 | 当选项多且是离散值时,结构清晰 | 当判断条件复杂(范围、逻辑组合)时,更自然 |
| 灵活性 | 较低,只能判断整型或字符 | 非常高,可以判断任何表达式 |
| 性能 | 在某些编译器和场景下可能比一长串 if-else if 稍快 |
通常性能也很好,取决于具体实现 |
| 最佳实践 | 菜单系统、状态机、枚举类型处理 | 范围判断(如成绩、年龄段)、复杂逻辑组合 |
对于“成绩等级判断”这个具体问题,if-else if 在逻辑上更直接、更易读,因为它本身就是为范围判断而设计的,而 switch 的实现则是一种技巧,需要你将范围转换为精确匹配的值。

(图片来源网络,侵删)
掌握 switch 的这种用法非常重要,因为它在很多其他场景下(如解析命令、状态机)是 if-else if 无法替代的。
