C语言case语句如何实现多分支选择?

99ANYc3cd6
预计阅读时长 21 分钟
位置: 首页 C语言 正文

switch-case 是一种多路分支语句,它可以根据一个变量的值,从多个执行分支中选择一个来执行,它相当于 if-else if-else 链条的一种更清晰、更高效的替代方案(在特定情况下)。

c语言case
(图片来源网络,侵删)

基本语法

switch-case 语句的基本结构如下:

switch (expression) {
    case constant_expression1:
        // 当 expression 的值等于 constant_expression1 时,执行的代码
        break; // 可选,但强烈推荐
    case constant_expression2:
        // 当 expression 的值等于 constant_expression2 时,执行的代码
        break; // 可选,但强烈推荐
    case constant_expression3:
        // 当 expression 的值等于 constant_expression3 时,执行的代码
        break; // 可选,但强烈推荐
    default:
        // 当 expression 的值不匹配任何一个 case 时,执行的代码
        break; // 可选,但强烈推荐
}

语法详解

a. switch (expression)

  • expression 是一个整型表达式(包括 int, char, short, long 等,因为 char 在本质上是小整数)。
  • 它不能是浮点型(float, double)或字符串类型。
  • switch 会计算这个表达式的值,然后与下面每个 case 的值进行比较。

b. case constant_expression:

  • constant_expression 必须是一个常量或常量表达式10, 'A', 2*5),不能是变量。
  • 每个 case 的值必须是唯一的,不能有两个 case 标签使用相同的常量值。
  • switch 的表达式的值与某个 case 的值匹配时,程序会从该 case 标签之后的语句开始执行,并依次向下执行,直到遇到 break 语句或 switch 语句块的末尾。

c. break; 语句

  • breakswitch-case 中最关键也最容易出错的点。
  • break 的作用是立即终止 switch 语句的执行,程序流程会跳转到 switch 语句块后面的第一条语句。
  • 如果某个 case 后面没有 break,程序会“穿透”(fall through)到下一个 case,继续执行其代码,即使它的 case 值并不匹配,这有时是故意的(用于多个 case 共享同一段代码),但更多时候是编程失误。

d. default:
  • default 是一个可选的“默认”分支。
  • switch 表达式的值不匹配任何一个 case 的值,那么程序就会执行 default 标签后面的代码。
  • default 可以放在 switch 块的任何位置(通常在最后),但从可读性角度,放在最后是最好的实践。
  • default 后面也可以使用 break,但这不是必需的,因为 default 是最后一个分支时,break 之后就是 switch 的结束。

示例代码

示例 1:标准用法(带 break

这是最常见的用法,每个 case 都是独立的。

#include <stdio.h>
int main() {
    int day = 3;
    char dayName[20];
    switch (day) {
        case 1:
            strcpy(dayName, "Monday");
            break;
        case 2:
            strcpy(dayName, "Tuesday");
            break;
        case 3:
            strcpy(dayName, "Wednesday");
            break;
        case 4:
            strcpy(dayName, "Thursday");
            break;
        case 5:
            strcpy(dayName, "Friday");
            break;
        case 6:
            strcpy(dayName, "Saturday");
            break;
        case 7:
            strcpy(dayName, "Sunday");
            break;
        default:
            strcpy(dayName, "Invalid day");
            break;
    }
    printf("Day %d is %s\n", day, dayName); // 输出: Day 3 is Wednesday
    return 0;
}

执行流程:

  1. day 的值是 3
  2. switch 开始匹配。
  3. case 1, case 2 都不匹配。
  4. case 3 匹配成功,程序开始执行 strcpy(dayName, "Wednesday");
  5. 遇到 break;switch 语句立即结束,程序跳转到 printf

示例 2:“穿透”效应(不带 break

我们希望多个 case 执行同一段代码,这时可以利用“穿透”特性。

c语言case
(图片来源网络,侵删)
#include <stdio.h>
int main() {
    char grade = 'B';
    switch (grade) {
        case 'A':
            printf("Excellent!\n");
            break;
        case 'B':
        case 'C':
            printf("Good job!\n"); // 当 grade 是 'B' 或 'C' 时,都会执行这里
            break;
        case 'D':
            printf("You passed.\n");
            break;
        case 'F':
            printf("Sorry, you failed.\n");
            break;
        default:
            printf("Invalid grade.\n");
            break;
    }
    return 0;
}

执行流程:

  1. grade 的值是 'B'
  2. switch 匹配到 case 'B'
  3. 由于 case 'B' 后面没有 break,程序会继续向下执行,进入 case 'C' 的代码块。
  4. 执行 printf("Good job!\n");
  5. case 'C' 后面有 breakswitch 语句结束。

示例 3:default 的位置

default 可以放在任何位置,但逻辑上通常放在最后。

#include <stdio.h>
int main() {
    int number = 5;
    switch (number) {
        default:
            printf("Number is not 1, 2, or 3.\n");
            break; // 虽然是最后一个,但加上 break 是好习惯
        case 1:
            printf("Number is 1.\n");
            break;
        case 2:
            printf("Number is 2.\n");
            break;
        case 3:
            printf("Number is 3.\n");
            break;
    }
    return 0;
}

执行流程:

  1. number 的值是 5
  2. switch 从上到下查找匹配的 case
  3. case 1, case 2, case 3 都不匹配。
  4. 程序执行 default 分支,打印 Number is not 1, 2, or 3.

switch-case vs. if-else if-else

特性 switch-case if-else if-else
判断条件 只能判断整型字符型常量 可以判断任何类型的表达式(浮点、字符串、逻辑等)
代码结构 对于多分支选择,结构更清晰,可读性高 对于少量分支或复杂条件,结构灵活
执行效率 通常效率更高,因为编译器可以生成跳转表,实现直接跳转,而不是像 if 那样逐一比较 效率相对较低,需要从上到下依次判断条件
break 需要 break 来防止“穿透” 每个分支都是独立的,不需要 break
共享逻辑 必须依赖“穿透”来实现,容易出错 可以用 &&, 等逻辑操作符轻松实现

选择建议:

c语言case
(图片来源网络,侵删)
  • 当你需要根据一个整型变量的值进行多路分支,并且分支较多(4 个以上)时,优先使用 switch-case,因为它更清晰。
  • 当你的判断条件很复杂(if (x > 10 && y < 5)),或者判断的类型不是整型(if (strcmp(str, "hello") == 0)),或者分支很少时,使用 if-else if-else

注意事项和常见错误

  1. 忘记 break:这是最常见的错误,会导致逻辑混乱,程序执行了不该执行的代码。

    // 错误示例
    int x = 2;
    switch (x) {
        case 1:
            printf("One\n");
        case 2: // 匹配到这里
            printf("Two\n"); // 执行
        case 3: // 因为没有 break,继续执行
            printf("Three\n"); // 也执行了!
        default:
            printf("Default\n"); // 也执行了!
    }
    // 输出:
    // Two
    // Three
    // Default
  2. switch 表达式不是整型:编译器会报错。

    // 错误示例
    double d = 1.2;
    switch (d) { // 错误:switch 表达式不能是 double 类型
        case 1.2:
            // ...
    }
  3. case 值不是常量:编译器会报错。

    // 错误示例
    int a = 5;
    int b = 10;
    switch (a) {
        case b: // 错误:case 标签必须是常量表达式
            // ...
    }
  4. 多个 case 使用相同的值:编译器会报错。

    // 错误示例
    switch (a) {
        case 1:
            // ...
        case 1: // 错误:重复的 case 值
            // ...
    }

switch-case 是 C 语言中一个非常强大的控制流工具,特别适用于处理基于单一整型变量的多路选择问题,理解其核心机制——匹配和执行以及break 的重要性——是正确使用它的关键。break 是防止代码“穿透”的“安全阀”,而 default 则是处理所有“意外情况”的“兜底方案”。

-- 展开阅读全文 --
头像
织梦CMS网站数量究竟有多少?
« 上一篇 04-20
织梦购物车手机模板如何适配手机端?
下一篇 » 04-20

相关文章

取消
微信二维码
支付宝二维码