分支结构(一)
多种情况,程序怎样作出选择?

从脉搏状态判断到混合数据输入与多分支

进一步理解分支结构

脉搏二分支
→
多区间判断
→
读入运算符
→
多分支计算

核心不是“多写几个 if”,而是把规则变成互斥、完整、有顺序的分支。

案例1 / 脉搏状态判断器
先理解数据,
再决定怎样分支
脉搏以“次/分钟”记录,是常见生命体征信息之一。
脉率区间else if边界

一次脉搏测量,程序需要知道什么?

脉搏测量示意

说明

  • 变量 p 表示每分钟脉搏次数。
  • 一个数值本身不是结论,程序必须依据明确规则解释。

上一课已经会“二选一”

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

if (p >= 60 && p <= 100)
    printf("Suitable\n");
else
    printf("Need further classification\n");

问题:55 和 108 都进入 else,但它们应该是同一种情况吗?

三种情况:先把规则分清楚

p < 60
心跳偏缓
教学提示
60 <= p && p <= 100
适合
教学提示
p > 100
心跳偏快
教学提示
覆盖完整
互不重叠
边界明确

else if:前面不成立,才继续判断

if (条件1) {
    语句1;
} else if (条件2) {
    语句2;
} else {
    语句3;
}

执行逻辑

  1. 先判断条件1。
  2. 不成立,才判断条件2。
  3. 前面都不成立,执行 else。
  4. 一旦某个分支执行,后面分支跳过。

把三个区间写成一个多分支

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

if (p < 60) {
    printf("Slow pulse\n");
} else if (p <= 100) {
    printf("Suitable\n");
} else {
    printf("Fast pulse\n");
}

为什么第二个条件只写 p <= 100?

因为走到这里已经意味着 p >= 60。

条件写对了,顺序也可能写错

版本A:从具体区间开始
if (p < 60)
    printf("Slow\n");
else if (p <= 100)
    printf("Suitable\n");
else
    printf("Fast\n");
版本B:先写更宽条件
if (p <= 100)
    printf("Suitable\n");
else if (p < 60)
    printf("Slow\n");
else
    printf("Fast\n");

输入 55,版本B会进入哪一支?

用4个数,快速检查三个分支

5960100101
输入 预期分支 为什么有用
59 Slow 检查60左侧
60 Suitable 检查下边界
100 Suitable 检查上边界
101 Fast 检查100右侧
案例2 / 脉搏数据计算模块
分支条件不一定来自“数值范围”,
也可以来自一个字符
把上一案例扩展为“记录与分析助手”的一个计算模块:用户输入两个数值和一个运算符,由程序选择相应计算。
doublecharscanf多分支

输入 72 + 76,程序要保存什么?

72

double value1

第1个数值

+

char op

一个字符

76

double value2

第2个数值

新的问题:'+' 不是数字,怎样输入?

char:保存一个字符

字符常量

'+'  '-'  '*'  '/'
'A'  '1'  ' '

字符常量用单引号括起来。

字符变量

char op;
op = '+';

op 保存用户选择的运算符。

scanf 按数据类型读取

double value1, value2;
char op;

scanf("%lf %c %lf", &value1, &op, &value2);
%lf

读取 double

%c

读取一个字符

%lf

读取 double

注意:格式串中的空格可以跳过输入中的空白字符,避免 %c 意外读到前面的空格或换行。

同样是多分支,只是条件换成了字符

if (op == '+')
    计算 value1 + value2;
else if (op == '-')
    计算 value1 - value2;
else if (op == '*')
    计算 value1 * value2;
else if (op == '/')
    计算 value1 / value2;
else
    提示 Unknown operator;

连续区间 → 比较数值;固定运算符 → 比较字符。

完整的 if-else if 版本

double value1, value2;
char op;

scanf("%lf %c %lf", &value1, &op, &value2);

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

为什么除法分支里还要再判断一次?

第一层

op == '/'

用户选择了除法。

第二层

value2 != 0

除法还有自己的前提条件。

这就是“分支内部继续分支”的最小例子。

现在你能解释这两种“多分支”了吗?

脉搏区间

p < 60 / p <= 100 / 其它

条件来自连续数值区间。

运算符

op == '+' / '-' / '*' / '/'

条件来自若干固定字符。

下一课时:固定选项很多时,能不能写得更清楚?

第1课时小结

  • 多分支:else if 按顺序检查多个条件。
  • 隐含范围:前一条件失败,会缩小后一条件的有效范围。
  • 边界测试:优先检查59/60、100/101一类边界。
  • 字符数据:char 可保存运算符等单字符信息。
  • 混合输入:%lf %c %lf 读取不同类型数据。
  • 嵌套判断:一个分支内部可以继续判断自己的特殊条件。