switch 语句详解
switch 是多分支选择结构,核心作用是根据一个表达式的固定值(如整数、字符、枚举,部分语言支持字符串)匹配不同的 case 分支,执行对应逻辑;相比嵌套 if-else,它更适合 “等值判断” 的多分支场景,结构更清晰。
switch 广泛应用于 C/C++、Java、JavaScript、C# 等语言,核心语法一致,仅在表达式类型支持上有细微差异。
一、基本语法(通用格式)
java
运行
switch (表达式) {
case 常量值1:
// 匹配常量值1时执行的代码
语句块1;
break; // 可选:跳出switch,避免case穿透
case 常量值2:
// 匹配常量值2时执行的代码
语句块2;
break;
// 可添加任意多个case分支
default:
// 所有case都不匹配时执行的代码(可选)
语句块n;
break; // 末尾default的break可省略,建议保留
}
关键说明:
| 组成部分 | 核心规则 |
|---|---|
| 表达式 | 类型有限制(见下文),最终需返回一个 “可匹配的固定值”(如整数、字符); |
| case 常量值 | 必须是不可变的常量(字面量、final 常量),且所有 case 值必须唯一; |
| break | 终止当前分支,跳出 switch;无 break 会触发 “case 穿透”(继续执行下一个 case); |
| default | 可选分支,所有 case 不匹配时执行,位置可任意(通常放末尾); |
二、执行流程
-
计算
switch后表达式的值; -
依次匹配
case后的常量值:- 找到匹配的 case → 执行该 case 后的代码,直到遇到
break或switch结束; - 未找到匹配的 case → 执行
default后的代码(若有);
- 找到匹配的 case → 执行该 case 后的代码,直到遇到
-
执行完对应分支后,跳出
switch(或因无 break 继续 “穿透”)。
流程图简化:
plaintext
计算表达式值 → 匹配case?→ 是→执行对应case(遇break则退出) | 否→执行default(若有)→退出switch
三、核心特点(vs if-else)
| 特性 | switch 语句 | if-else 语句 |
|---|---|---|
| 适用场景 | 等值判断(固定值分支) | 范围判断 / 复杂条件判断 |
| 可读性 | 多分支(≥3 个)时更清晰 | 少分支(≤2 个)时更简洁 |
| 表达式类型 | 有限制(如 C 仅支持整型) | 无限制(布尔表达式即可) |
| 执行效率 | 编译期优化,效率更高 | 逐行判断,效率略低 |
四、示例代码(不同场景)
示例 1:基础用法(Java,数字匹配星期)
java
运行
public class SwitchBasic {
public static void main(String[] args) {
int week = 3; // 要匹配的值
switch (week) {
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
case 3:
System.out.println("星期三");
break; // 匹配到case3,执行后break跳出
case 4:
System.out.println("星期四");
break;
case 5:
System.out.println("星期五");
break;
case 6:
System.out.println("星期六");
break;
case 7:
System.out.println("星期日");
break;
default:
System.out.println("输入的星期数无效");
break;
}
}
}
输出:星期三
示例 2:利用 case 穿透(多 case 共用逻辑)
适用于 “多个值对应同一逻辑” 的场景(如判断季节):
java
运行
int month = 4;
switch (month) {
case 3:
case 4:
case 5: // 3/4/5月都匹配该分支(利用穿透)
System.out.println("春季");
break; // 执行后跳出,避免继续穿透
case 6:
case 7:
case 8:
System.out.println("夏季");
break;
case 9:
case 10:
case 11:
System.out.println("秋季");
break;
case 12:
case 1:
case 2:
System.out.println("冬季");
break;
default:
System.out.println("无效月份");
break;
}
输出:春季
示例 3:C 语言示例(仅支持整型 / 字符型)
C 语言不支持字符串,仅支持整型(int、char,char 本质是 ASCII 整型):
c
运行
#include <stdio.h>
int main() {
char grade = 'B'; // 字符型(ASCII值为66)
switch (grade) {
case 'A':
printf("优秀\n");
break;
case 'B':
printf("良好\n");
break;
case 'C':
printf("及格\n");
break;
default:
printf("不及格\n");
break;
}
return 0;
}
输出:良好
示例 4:Java 字符串匹配(Java 7+ 支持)
java
运行
String fruit = "apple";
switch (fruit) {
case "apple":
System.out.println("苹果,单价8元/斤");
break;
case "banana":
System.out.println("香蕉,单价3元/斤");
break;
case "orange":
System.out.println("橙子,单价5元/斤");
break;
default:
System.out.println("暂无该水果价格");
break;
}
输出:苹果,单价8元/斤
五、常见注意事项
1. 必加 break:避免 case 穿透(新手高频坑)
若 case 后无 break,执行完当前 case 后会继续执行下一个 case 的代码,直到遇到 break 或 switch 结束(除非刻意利用穿透,否则必须加 break):
java
运行
int num = 2;
switch (num) {
case 1:
System.out.println("1");
case 2:
System.out.println("2"); // 匹配到这里,无break
case 3:
System.out.println("3"); // 继续穿透执行
break;
}
// 输出:2 3(非预期结果)
2. default 分支的特性
- 可选性:没有
default时,所有 case 不匹配则直接退出 switch,无任何执行; - 位置灵活:可放在任意 case 前 / 后,但通常放末尾(可读性更高);
- 执行优先级:即使
default在开头,也会先匹配 case,无匹配才执行default。
3. 表达式类型限制(关键差异)
| 语言 | 支持的表达式类型 | 不支持的类型 |
|---|---|---|
| C/C++ | 整型(int、char)、枚举 | 字符串、浮点型(float/double) |
| Java | byte/short/int/char、枚举、String(7+) | long、浮点型 |
| JavaScript | 任意类型(隐式转字符串 / 数字) | 浮点型(精度问题,不推荐) |
4. case 常量的规则
case后必须是常量值(字面量、final 常量),不能是变量 / 动态表达式(如case i、case 1+2不行,编译期可计算的表达式除外);- 多个 case 不能有相同的常量值,否则编译报错。
5. 慎用 switch 嵌套
可在 case 内嵌套 switch,但可读性极差,尽量避免;若必须嵌套,注意 break 仅跳出当前层switch。
6. 代码块 {} 的规范
-
switch 整体的
{}不可省略; -
case 内若有多行代码,无需额外加
{},但建议添加(提高可读性):java
运行
// 推荐写法 case 1: { System.out.println("星期一"); int count = 1; // 局部变量 break; }