分支结构(二)
固定选项很多时,怎样写得更清楚?

从脉搏数据计算模块到菜单驱动的健康数据助手

四个固定运算符,都用 else if 可以吗?

if (op == '+')
    ...
else if (op == '-')
    ...
else if (op == '*')
    ...
else if (op == '/')
    ...

共同特点:反复比较同一个变量与若干固定值。

案例3 / 脉搏数据助手
当程序有多个功能,
先让用户选择“做什么”
把上一课已有的“记录、判断、计算”功能组织成一个简单菜单,模拟健康数据记录终端的交互方式。
菜单choiceswitchcase

一个程序开始有“多个功能”

脉搏数据助手

  • 记录一次脉搏数据
  • 显示范围提示
  • 比较两次读数
  • 完成简单数据计算

0:退出程序

已有功能

  • 输入一次脉搏数据。
  • 根据区间给出教学提示。
  • 比较两次测量值。
  • 执行简单数据计算。

用户怎样告诉程序:“我现在要做第3项”?

把“功能选择”变成一个整数 choice

输入的是一个值,决定的是一条执行路径。

3.1 / switch-case
一个变量对应多个固定值:
用 switch 表达更直接
switchcasebreakdefault

switch 先看表达式的值,再找匹配的 case

switch (表达式) {
    case 常量1:
        语句段1;
        break;
    case 常量2:
        语句段2;
        break;
    default:
        默认语句段;
        break;
}

switch

看哪个变量/表达式。

case

与哪个固定值匹配。

break

执行完当前分支后离开。

把菜单映射成多条固定路径

choice = 1
choice = 2
choice = 3
choice = 4
其他
switch
(choice)
case 1 → 记录脉搏
case 2 → 状态提示
case 3 → 比较两次数据
case 4 → 数据计算
default → 无效选项

菜单的 switch 骨架

int choice;
scanf("%d", &choice);

switch (choice) {
    case 1:
        printf("Record pulse\n");
        break;
    case 2:
        printf("Show range hint\n");
        break;
    case 3:
        printf("Compare two readings\n");
        break;
    case 4:
        printf("Simple calculator\n");
        break;
    case 0:
        printf("Exit\n");
        break;
    default:
        printf("Invalid choice\n");
        break;
}

case 用来匹配固定的离散值

适合

case 1:
case 2:
case '+':
case 'A':

固定整数或字符常量。

不适合

case p < 60:
case 60 <= p && p <= 100:

范围判断仍应使用 if-else。

范围判断找 if,固定选项想 switch。

3.2 / break 与贯穿执行
为什么每个 case
后面通常都要有 break?
预测运行解释

如果删掉 break,输入 1 会输出什么?

switch (choice) {
    case 1:
        printf("Record pulse\n");
    case 2:
        printf("Show range hint\n");
    case 3:
        printf("Compare readings\n");
    default:
        printf("End\n");
}
只输出1行?
输出2行?
一直向后执行?

没有 break:会继续向后执行

输入1

  1. 找到 case 1
  2. 执行case 1
  3. 继续执行case 2
  4. 继续执行case 3
  5. 继续执行default

因此

break;

不是“结束程序”,而是离开当前 switch。

这也是为什么删除一个 break 会改变后续所有输出。

用户输入 9 怎么办?

default:
    printf("Invalid choice\n");
    break;
设计意识:菜单不仅要说明“正确选项做什么”,还要定义“其他输入怎么办”。
3.3 / 迁移与结构选择
同一个问题,
什么时候用 if,什么时候用 switch?
范围固定值可读性

运算符也是“一个变量 + 多个固定值”

switch (op) {
    case '+':
        printf("= %.2f\n", value1 + value2);
        break;
    case '-':
        printf("= %.2f\n", value1 - value2);
        break;
    case '*':
        printf("= %.2f\n", value1 * value2);
        break;
    case '/':
        if (value2 != 0)
            printf("= %.2f\n", value1 / value2);
        else
            printf("Divisor cannot be 0!\n");
        break;
    default:
        printf("Unknown operator!\n");
}

同一个程序里可以同时存在 switch 和嵌套的 if。

if-else 与 switch 各自擅长什么?

问题 更自然的结构 原因
p < 60 if 范围比较
60 <= p && p <= 100 if 复合条件
choice = 1/2/3/4 switch 固定离散选项
op = '+'/'-'/'*'/'/' switch 固定字符值

脉搏数据助手的两层选择

第1层:选功能

switch (choice) {
    case 2:
        // 查看状态提示
        ...
}

固定菜单值 → switch

第2层:做区间判断

if (p < 60)
    ...
else if (p <= 100)
    ...
else
    ...

连续范围 → if-else

程序结构不是“二选一”,而是根据问题把不同结构组合起来。

先搭结构,再逐步填充功能

#include <stdio.h>

int main(void)
{
    int choice, p;
    scanf("%d", &choice);

    switch (choice) {
        case 1:
            scanf("%d", &p);
            break;
        case 2:
            scanf("%d", &p);
            if (p < 60)
                printf("Slow pulse\n");
            else if (p <= 100)
                printf("Suitable\n");
            else
                printf("Fast pulse\n");
            break;
        default:
            printf("Invalid choice\n");
    }
    return 0;
}

这里只展示结构骨架;循环菜单将在后续循环结构中继续升级。

只判断“该用什么结构”

问题A

判断脉搏是否小于60。

?

问题B

选择菜单1/2/3/4。

?

问题C

选择 + - * /。

?

A:if  B:switch  C:switch(也可用else-if)

第2课时小结

  • switch:适合“同一个变量匹配多个固定值”。
  • case:提供可能的入口,不会自动结束。
  • break:结束当前分支并离开 switch。
  • default:处理没有匹配任何 case 的情况。
  • 结构选择:范围/复杂条件优先 if,固定离散值优先 switch。
  • 组合:菜单用 switch,菜单内部仍可继续使用 if。