C语言学习笔记 -63.流程控制17 - 选择9 - if...else if多分支选择与常见错误解析

一、本节学习定位

本节属于 流程控制 中的核心内容,重点讲解 if、else if、else 多分支选择结构 的写法与常见错误。

在 C 语言中,程序并不是简单地从上到下全部执行。遇到 if 语句 时,程序会根据条件表达式的真假选择不同的执行路径。因此,理解 if 语句的执行流程 是看懂 C 程序的基础。

本节重点包括:

  1. if...else 的基本结构;

  2. else if 多分支结构的执行规则;

  3. 多个条件同时成立时,只执行第一个满足条件的分支;

  4. else 后面不能直接写条件表达式;

  5. else (表达式); 语法上可能成立,但逻辑上没有实际意义;

  6. 成绩等级判断中区间条件的正确写法;

  7. 90 <= score <= 100 这种数学写法在 C 语言中是错误的。


二、if...else 的基本形式

1. 基本语法

复制代码
if (表达式)
{
    语句A;
}
else
{
    语句B;
}

执行逻辑如下:

  1. 先判断 if 后面括号中的表达式;

  2. 如果表达式为真,即非 0,执行 语句A

  3. 如果表达式为假,即 0,执行 else 后面的 语句B

  4. if 分支和 else 分支只能执行其中一个。


2. 示例程序

复制代码
#include <stdio.h>

int main(void)
{
    if (3 > 2)
    {
        printf("AAAA\n");
    }
    else
    {
        printf("BBBB\n");
    }

    return 0;
}

3. 运行结果

复制代码
AAAA

4. 程序分析

3 > 2 成立,因此程序执行 if 分支中的语句:

复制代码
printf("AAAA\n");

else 分支不会执行。


三、常见错误一:if 后误加分号导致 else 出错

1. 错误写法

复制代码
if (3 > 2);
    printf("AAAA\n");
else
    printf("BBBB\n");

这段程序是错误的。

2. 错误原因

在 C 语言中,单独一个分号可以构成一条 空语句

复制代码
;

因此:

复制代码
if (3 > 2);

等价于:

复制代码
if (3 > 2)
    ;

也就是说,if 实际控制的是一条空语句。

于是错误代码会被理解为:

复制代码
if (3 > 2)
    ;                   // if 控制的是空语句

printf("AAAA\n");       // 已经不属于 if 结构

else                    // else 前面没有可匹配的 if
    printf("BBBB\n");

当编译器执行到 else 时,会发现前面已经没有可匹配的 if,因此会产生语法错误。

3. 常见编译错误含义

可能出现类似提示:

复制代码
else without a previous if

含义是:

复制代码
else 前面没有可以匹配的 if

四、else if 多分支结构

当一个问题有多个判断条件时,通常使用 else if 多分支结构

1. 基本语法

复制代码
if (表达式1)
{
    语句A;
}
else if (表达式2)
{
    语句B;
}
else if (表达式3)
{
    语句C;
}
else
{
    语句D;
}

2. 执行规则

程序会从上到下依次判断:

  1. 如果 表达式1 成立,执行 语句A,后面的 else ifelse 全部跳过;

  2. 如果 表达式1 不成立,才判断 表达式2

  3. 如果 表达式2 成立,执行 语句B,后面的分支全部跳过;

  4. 如果前面的条件都不成立,才会继续向下判断;

  5. 最后的 else 表示"以上条件都不成立时执行"。


五、多个条件同时成立时,只执行第一个满足的分支

1. 示例程序

复制代码
#include <stdio.h>

int main(void)
{
    if (3 > 2)
    {
        printf("AAAA\n");
    }
    else if (3 > 1)
    {
        printf("BBBB\n");
    }
    else
    {
        printf("CCCC\n");
    }

    return 0;
}

2. 条件分析

条件 是否成立
3 > 2 成立
3 > 1 成立

虽然两个条件都成立,但程序只会输出:

复制代码
AAAA

3. 原因分析

else if 的含义是:

复制代码
否则,如果......

只有当前面的 if 条件不成立时,才会进入后面的 else if 判断。

因此:

复制代码
if (3 > 2)

已经成立并执行后,整个 if...else if...else 结构就结束了,后面的条件不会再判断。


六、成绩等级判断示例

截图中给出的成绩判断程序属于典型的多分支选择结构。其逻辑是:

分数范围 输出结果
score > 100 这是做梦
90 <= score <= 100 优秀
80 <= score < 90 良好
60 <= score < 80 及格
0 <= score < 60 不及格

但在 C 语言中,不能直接写成数学形式:

复制代码
90 <= score <= 100

必须写成:

复制代码
score >= 90 && score <= 100

七、错误写法:不能写成 90 <= score <= 100

1. 错误写法

复制代码
else if (90 <= score <= 100)
{
    printf("优秀!\n");
}

这不是正确的 C 语言区间判断。

2. 错误原因

在数学中:

复制代码
90 <= score <= 100

表示 score 在 90 到 100 之间。

但在 C 语言中,这个表达式会被按如下方式理解:

复制代码
(90 <= score) <= 100

其中:

复制代码
90 <= score

的结果只有两种:

表达式结果 数值
0
1

然后继续判断:

复制代码
0 <= 100

或:

复制代码
1 <= 100

这两个结果都为真。

因此,90 <= score <= 100 并不能正确判断 score 是否在 [90, 100] 区间内。


八、正确写法:使用逻辑与运算符 &&

1. 正确区间判断

复制代码
score >= 90 && score <= 100

含义是:

复制代码
score 大于等于 90,并且 score 小于等于 100

只有两个条件同时成立,整个表达式才成立。

2. 常见区间写法对比

数学含义 错误写法 C 语言正确写法
90 <= score <= 100 90 <= score <= 100 score >= 90 && score <= 100
80 <= score < 90 80 <= score < 90 score >= 80 && score < 90
60 <= score < 80 60 <= score < 80 score >= 60 && score < 80
0 <= score < 60 0 <= score < 60 score >= 0 && score < 60

九、成绩等级判断完整程序

1. 示例代码

复制代码
#include <stdio.h>

int main(void)
{
    int score;

    printf("请输入成绩:");
    scanf("%d", &score);

    if (score > 100)
    {
        printf("这是做梦!\n");
    }
    else if (score >= 90 && score <= 100)
    {
        printf("优秀!\n");
    }
    else if (score >= 80 && score < 90)
    {
        printf("良好!\n");
    }
    else if (score >= 60 && score < 80)
    {
        printf("及格!\n");
    }
    else if (score >= 0 && score < 60)
    {
        printf("不及格!继续努力!\n");
    }

    return 0;
}

2. 程序说明

代码 作用
scanf("%d", &score); 输入成绩
score > 100 判断成绩是否超过正常范围
score >= 90 && score <= 100 判断是否为优秀
score >= 80 && score < 90 判断是否为良好
score >= 60 && score < 80 判断是否为及格
score >= 0 && score < 60 判断是否为不及格

十、没有 else 时可能出现逻辑漏洞

上面的程序没有最终的 else 分支。如果输入负数,例如:

复制代码
-9

程序执行过程如下:

判断条件 是否成立
score > 100 不成立
score >= 90 && score <= 100 不成立
score >= 80 && score < 90 不成立
score >= 60 && score < 80 不成立
score >= 0 && score < 60 不成立

所有条件都不成立,因此程序不会输出任何等级信息。

这说明:

复制代码
else 不是必须写,但如果不写 else,就要确认是否已经覆盖所有可能情况。

十一、改进版:增加 else 处理非法成绩

为了避免输入负数时没有任何输出,可以增加最后的 else

复制代码
#include <stdio.h>

int main(void)
{
    int score;

    printf("请输入成绩:");
    scanf("%d", &score);

    if (score > 100)
    {
        printf("这是做梦!\n");
    }
    else if (score >= 90 && score <= 100)
    {
        printf("优秀!\n");
    }
    else if (score >= 80 && score < 90)
    {
        printf("良好!\n");
    }
    else if (score >= 60 && score < 80)
    {
        printf("及格!\n");
    }
    else if (score >= 0 && score < 60)
    {
        printf("不及格!继续努力!\n");
    }
    else
    {
        printf("成绩输入不合法!\n");
    }

    return 0;
}

程序特点

  1. score > 100 单独处理大于 100 的异常情况;

  2. score >= 0 && score <= 100 范围内按等级判断;

  3. score < 0 时进入最后的 else

  4. 所有输入情况都有明确输出。


十二、常见错误二:else 后不能直接写条件表达式

1. 错误结构

截图中出现了类似结构:

复制代码
if (表达式1)
    A;
else if (表达式2)
    B;
else if (表达式3)
    C;
else (表达式4)
    D;

这种写法是错误的。

2. 错误原因

else 的含义是:

复制代码
否则

它本身不负责判断条件。

如果还要继续判断条件,必须写成:

复制代码
else if (表达式4)

不能写成:

复制代码
else (表达式4)

十三、正确写法一:去掉 else 后面的条件

如果最后一个分支表示"以上条件都不成立",应写成:

复制代码
if (表达式1)
{
    A;
}
else if (表达式2)
{
    B;
}
else if (表达式3)
{
    C;
}
else
{
    D;
}

这里的 else 不需要条件,表示:

复制代码
表达式1、表达式2、表达式3 都不成立时,执行 D。

十四、正确写法二:在 else 后加 if

如果最后一个分支仍然需要判断条件,应写成:

复制代码
if (表达式1)
{
    A;
}
else if (表达式2)
{
    B;
}
else if (表达式3)
{
    C;
}
else if (表达式4)
{
    D;
}

这里的含义是:

复制代码
表达式1 不成立,再判断表达式2;
表达式2 不成立,再判断表达式3;
表达式3 不成立,再判断表达式4。

十五、else (表达式); 的语法与逻辑问题

1. 语法上可能通过的写法

复制代码
if (1 > 2)
{
    printf("AAAA\n");
}
else if (1 > 5)
{
    printf("BBBB\n");
}
else
    (5 > 10);

printf("CCCC\n");

这段代码语法上可以成立,但逻辑上没有实际意义。

2. 等价理解

上面的代码等价于:

复制代码
if (1 > 2)
{
    printf("AAAA\n");
}
else if (1 > 5)
{
    printf("BBBB\n");
}
else
{
    (5 > 10);   // 只是计算表达式,结果被丢弃
}

printf("CCCC\n");  // 不属于 if...else if...else 结构

3. 运行结果

由于 printf("CCCC\n"); 不受 if...else 控制,所以它一定会执行。

运行结果为:

复制代码
CCCC

4. 关键结论

复制代码
(5 > 10);

是一条 表达式语句 ,它只是计算 5 > 10 的结果,然后丢弃结果。由于没有赋值、没有输出、没有函数调用副作用,所以这条语句没有实际意义。


十六、else (表达式) 不加分号时为什么会出错

1. 错误写法

复制代码
if (1 > 2)
{
    printf("AAAA\n");
}
else if (1 > 5)
{
    printf("BBBB\n");
}
else (5 > 10)
{
    printf("CCCC\n");
}

或者:

复制代码
else (5 > 10)
    printf("CCCC\n");

2. 错误原因

else 后面必须跟一条合法语句。

复制代码
(5 > 10)

本身只是一个表达式,不是完整语句。表达式必须加分号才构成表达式语句:

复制代码
(5 > 10);

但是即使写成表达式语句,它也只是被 else 控制的一条无实际意义的语句,后面的 printf 仍然可能脱离 else 控制。


十七、if...else if...else 常见错误总结表

错误写法 是否语法错误 主要问题 正确写法
if (条件); printf(...); else ... else 找不到匹配的 if 删除 if 后的分号
else (表达式) printf(...); else 后不是合法语句 写成 else if (表达式)
else (表达式); printf(...); 通常不是 else 控制无意义表达式,printf 脱离控制 写成 else if (表达式)else { ... }
90 <= score <= 100 通常不是 逻辑错误,不能表示数学区间 score >= 90 && score <= 100
没有最后的 else 不是 可能存在未覆盖输入 根据需要增加 else

十八、VSCode 中建议的调试方法

1. 新建文件

建议文件名:

复制代码
if_else_error.c

2. 编译程序

在 VSCode 终端中执行:

复制代码
gcc -Wall if_else_error.c -o if_else_error.exe

3. 运行程序

复制代码
./if_else_error.exe

4. 建议测试的数据

对于成绩判断程序,可以依次输入:

输入 预期输出
101 这是做梦
95 优秀
85 良好
70 及格
55 不及格
-9 如果无最终 else,可能无输出;改进版应输出成绩非法

十九、本节核心结论

  1. else if 多分支结构中,只会执行第一个满足条件的分支。

  2. 即使多个条件同时成立,也不会全部执行。

  3. else 后面不能直接写条件表达式。

  4. 如果 else 后还需要判断条件,必须写成 else if (表达式)

  5. 如果 else 表示兜底分支,则后面不应再写条件。

  6. else (表达式); 虽然可能语法上成立,但通常没有实际意义。

  7. 数学中的连续区间写法不能直接用于 C 语言。

  8. 判断区间时,应使用逻辑与运算符 &&

  9. 初学阶段建议使用花括号明确每个分支的控制范围。

  10. 分析 if...else if...else 程序时,要重点看"哪个分支先满足,哪个分支会被跳过"。


二十、参考出处

  1. 《C程序设计(第五版)》谭浩强,第 3 章"最简单的 C 程序设计------顺序程序设计"

  2. 《C程序设计(第五版)》谭浩强,第 4 章"选择结构程序设计"

  3. 郝斌《C语言自学入门教程》对应内容:if 常见错误、多分支判断、else 后条件表达式错误、成绩等级判断示例。