1.6 分支结构与条件语句 | Branch Structure and Conditional Statements

发布于 2025-09-15  565 次阅读


分支结构与条件语句 | Branch Structure and Conditional Statements

一、回顾与引入

在上一章中,我们学习了各种运算符:

  • 算术运算符:+ - * / %
  • 比较运算符:== != > < >= <=
  • 逻辑运算符:&& || !

我们同时学习到,每个逻辑判断表达式都有它们的对应的值。例如3 > 2的值是1(代表真),-1 > 3的值是0(代表假)。

我们很容易发现,逻辑判断表达式的核心是判断,这是否意味着我们可以让程序通过判断条件表达式的真假来执行不同的功能?

今天我们要系统学习条件语句,让程序能够根据不同的情况做出不同的反应,就像人类的思维一样进行判断和选择。

二、什么是分支结构?

分支结构就是程序根据条件的真假,选择不同的执行路径。

想象生活中的场景:

  • 如果下雨了,我就带伞;否则,我就不带伞
  • 如果考试分数≥60,就及格;否则,就不及格
  • 如果年龄≥18,可以投票;否则,不能投票

在程序中,我们使用条件语句来实现分支结构,最常用的就是if语句。

程序执行流程对比

顺序结构(之前学的):

语句1 → 语句2 → 语句3 → ...

分支结构(今天要学的):

        条件判断
       /        \
    真(True)   假(False)
      /           \
   执行A        执行B
      \           /
       \         /
        继续执行

三、if语句的基本语法

实现分支结构的条件语句中,最常用的是 if语句,我们通过下面一些简单例子来学习if语句的基本语法。

1. 简单if语句

if (条件表达式) {
    // 条件为真时执行的语句
}

if语句是这样构成的:在if关键字后带有英文括号(),括号内填入条件表达式(逻辑判断表达式),其后带有英文大括号{}括起来的代码块。

程序执行到if语句时,会先对英文括号()内的表达式进行判断。如果表达式的值为1(真),就会执行英文大括号{}内的语句,否则跳过{}中的语句。待英文大括号{}内的语句执行完,或被跳过后,程序接着执行if后续的语句。

示例:判断是否成年

//Simple_If.c
#include <stdio.h>

int main() {
    int age;

    printf("请输入您的年龄: ");
    scanf("%d", &age);

    if (age >= 18) {
        printf("您已经成年了!\n");
        printf("可以独立承担法律责任。\n");
    }

    printf("程序结束。\n");

    return 0;
}

运行示例:

请输入您的年龄: 20
您已经成年了!
可以独立承担法律责任。
程序结束。
请输入您的年龄: 16
程序结束。

代码块

值得说明的是,我们这里提到了代码块(Code Blocks)的概念。代码块是由英文大括号{}括起来的部分。

在上面的例子里,我们提到

if (age >= 18) {
    printf("您已经成年了!\n");
    printf("可以独立承担法律责任。\n");
}

这样,在age >= 18这个条件满足的时候,{}内的语句都会执行。但如果像下面这样

if (age >= 18) printf("您已经成年了!\n");
printf("可以独立承担法律责任。\n");

if语句后,不使用英文大括号{}括起来,这样写没有问题,但if只会把其后紧跟的第一句话printf("您已经成年了!\n");作为条件为1(真)时执行的语句。

printf("可以独立承担法律责任。\n");则被视作与if地位相当,在if语句执行完后,程序顺序执行的语句。

此外,在if语句后需要执行的语句如果确实只有一句,那么不带大括号{}的写法,也是保持代码可读性强、整洁美观的一种方式。

2. if-else语句

在自然语言中,我们除了会见到像

如果下雨了,我就带伞

这样的结构以外,我们还会见到含有“如果...否则...”的结构。例如:

如果年龄≥18,可以投票;否则,不能投票

因此,C语言提供if-else语句。它的基本语法如下,我们仍然通过一个简单例子来学习if-else语句。

if (条件表达式) {
    // 条件为真时执行
} else {
    // 条件为假时执行
}

示例:判断奇偶性

//If_Else.c
#include <stdio.h>

int main() {
    int number;

    printf("请输入一个整数: ");
    scanf("%d", &number);

    if (number % 2 == 0) {
        printf("%d 是偶数\n", number);
    } else {
        printf("%d 是奇数\n", number);
    }

    return 0;
}

运行示例:

请输入一个整数: 8
8 是偶数

3. if-else if-else语句

有时,我们需要解决的问题,只进行一次判断并不能解决问题。这时,我们便涉及到ifif-else语句的嵌套。

if (条件1) { // 总 if
    if (条件2) { // 条件1成立时,内嵌的 if
        // 条件1和2都成立时,执行的语句
    }
    // 条件1成立条件下,不论条件2是否成立,都执行的语句

} else {
    if (条件3) { // 条件1不成立时,内嵌的 if
        // 条件1不成立但条件3成立时,执行的语句
    } else {
        // 条件1和3都不成立时,执行的语句
    }
}

此外,我们刚才提到

if语句后需要执行的语句如果确实只有一句,那么不带大括号{}的写法,也是保持代码可读性强、整洁美观的一种方式。

因此,下面的写法也是合法的。这样的写法叫做else-if结构,常常用于实现判断多选一的功能:

if (条件1) {

} else if (条件2) {

}

例如:

如果温度高于20度,我就去游泳
如果温度高于0度但低于20度,我就去打球
如果温度低于0度,我就去滑冰

这个例子的特点是,三种选项不是先后包含关系,而是互斥的,只能选择其中一个。这时,连续的else-if结构就很适合处理这类问题。例如:

示例:温度决定安排

//Temperature_Depended_Schedule.c
#include <stdio.h>

int main() {
    int temp;

    printf("请输入今天的温度: ");
    scanf("%d", &temp);

    if (temp >= 20) {
        printf("我今天去游泳。\n");
    } else if (temp >= 0) {
        // 这里按理应该写成 temp >= 0 && temp < 20
        // 但功能是一样的,想想是为什么?
        printf("我今天去打球。\n");
    } else {
        printf("我今天去滑冰。\n");
    }

    return 0;
}

四、条件表达式详解

1. 简单条件

int age = 18;
if (age >= 18) {        // 算数比较
    printf("成年\n");
}

char grade = 'A';
if (grade == 'A') {     // 字符比较
    printf("优秀\n");
}

2. 复合条件

使用逻辑运算符组合多个条件:

//Compound_Conditions.c
#include <stdio.h>

int main() {
    int age, income;

    printf("请输入年龄: ");
    scanf("%d", &age);
    printf("请输入年收入(万元): ");
    scanf("%d", &income);

    // 逻辑与:两个条件都要满足
    if (age >= 18 && income >= 10) {
        printf("符合贷款条件\n");
    } else {
        printf("不符合贷款条件\n");

        // 具体说明原因
        if (age < 18) {
            printf("原因:年龄不足18岁\n");
        }
        if (income < 10) {
            printf("原因:年收入不足10万元\n");
        }
    }

    return 0;
}

3. 条件的真假判断

我们在此前学习到,C语言中,1表示条件是真,0表现条件是假。

那么既非0、又非1的值代表什么?我们在学习数据类型(1.2)时曾经提到数据类型的强制转换:

尽管数据类型不匹配的错误,是我们在编程的时候要尽量避免的,但C语言仍然针对这些失误,智能的提供了解决办法。即数据的强制转换
...
类似的还有将非0的数,如2-5520.1314赋值给布尔型的时候,会被强制转换为true,即1

因此,准确地说,在C语言中:

  • 0表示假(false)
  • 非0表示真(true)
//Truth_Values.c
#include <stdio.h>

int main() {
    int a = 5, b = 0;

    if (a) {        // a = 5,非0,为真
        printf("a为真\n");
    }

    if (b) {        // b = 0,为假
        printf("b为真\n");
    } else {
        printf("b为假\n");
    }

    if (a > b) {    // 5 > 0,结果为1(真)
        printf("a > b 为真\n");
    }

    return 0;
}

五、常见错误与注意事项

1. 赋值与比较混淆

int x = 5;

// ❌ 错误:使用赋值运算符
if (x = 10) {           // 这里是赋值,不是比较!
    printf("执行\n");   // 总是会执行
}

// ✅ 正确:使用比较运算符
if (x == 10) {          // 这才是比较
    printf("x等于10\n");
}

这里可能有一些难懂:为什么在条件表达式处写赋值语句,if总是判定为真、并执行后面的代码块?我们在上一章学习到:

此外值得一提的是,即使是赋值表达式x = 5也有它对应的值。这个值也只能是1(真)或0(假),表示赋值是否成功。因此通常情况下,赋值表达式的值一般都为1。这会在下一节提到判断语句的时候再次提到。

因此,当程序执行到if (x = 10)时,会先执行x = 10这一赋值语句,在赋值成功后,赋值表达式x = 10的值确定为1,后续if内的代码自然也就执行下去。

2. 分号的位置

int age = 20;

// ❌ 错误:if后面多了分号
if (age >= 18);         // 这里的分号结束了if语句
{
    printf("成年\n");   // 这个代码块总是会执行
}

// ✅ 正确:
if (age >= 18) {
    printf("成年\n");
}

3. 大括号的使用

// 单条语句可以省略大括号
if (age >= 18) printf("成年\n");

// 多条语句必须使用大括号
if (age >= 18) {
    printf("成年\n");
    printf("可以投票\n");
}

4. 浮点数比较问题

float a = 0.1 + 0.2;
float b = 0.3;

// ❌ 可能有误差
if (a == b) {
    printf("相等\n");
}

// ✅ 使用误差范围比较
if (a - b < 0.0001 && a - b > -0.0001) {
    printf("基本相等\n");
}

这一点可能比较反常、在现阶段可能难以理解,因此需要我们记住:浮点数的计算精度并不高,在比较是否相等时,第二种是更为保险的方法

七、实际应用:出行建议小贴士

和之前的内容一样,我们仍然用一个小例子来复习一下本节内容。你能看懂每一条语句在执行什么样的功能么?

//TravelHint.c
#include <stdio.h>

int main() {
    char weather;
    int temperature;

    printf("今天天气如何?(s=晴天, r=雨天, c=阴天): ");
    scanf(" %c", &weather);

    printf("今天气温多少度?: ");
    scanf("%d", &temperature);

    printf("\n=== 出行建议 ===\n");

    if (weather == 's') {           // 晴天
        printf("天气:晴天\n");
        if (temperature > 30) {
            printf("建议:天气炎热,注意防晒,多喝水\n");
        } else if (temperature > 20) {
            printf("建议:天气宜人,适合外出\n");
        } else {
            printf("建议:天气较凉,注意保暖\n");
        }
    } else if (weather == 'r') {    // 雨天
        printf("天气:雨天\n");
        printf("建议:记得带伞\n");
        if (temperature < 10) {
            printf("额外提醒:气温较低,注意保暖\n");
        }
    } else if (weather == 'c') {    // 阴天
        printf("天气:阴天\n");
        if (temperature > 25) {
            printf("建议:虽然阴天,但温度较高,注意通风\n");
        } else {
            printf("建议:天气适中,正常出行\n");
        }
    } else {
        printf("输入的天气类型无效\n");
    }

    return 0;
}

九、动手练习

练习1:简单密码强度检测器

编写程序检测密码强度:

  • 如果长度<6,显示"密码太短"
  • 如果长度6-8,显示"密码强度:弱"
  • 如果长度9-12,显示"密码强度:中"
  • 如果长度>12,显示"密码强度:强"

练习2:BMI健康指数计算器

编写程序计算BMI并给出健康建议:

  • BMI = 体重(kg) / (身高(m))²
  • BMI < 18.5:体重过轻
  • 18.5 ≤ BMI < 24:正常体重
  • 24 ≤ BMI < 28:超重
  • BMI ≥ 28:肥胖
// 练习2参考答案
#include <stdio.h>

int main() {
    float height, weight, bmi;

    printf("=== BMI健康指数计算器 ===\n");
    printf("请输入您的身高(米): ");
    scanf("%f", &height);
    printf("请输入您的体重(千克): ");
    scanf("%f", &weight);

    // 输入验证
    if (height <= 0 || weight <= 0) {
        printf("输入错误:身高和体重必须大于0!\n");
        return 1;
    }

    // 计算BMI
    bmi = weight / (height * height);

    printf("\n=== 健康评估结果 ===\n");
    printf("身高: %.2f米\n", height);
    printf("体重: %.2f千克\n", weight);
    printf("BMI指数: %.2f\n", bmi);

    // 健康评估
    if (bmi < 18.5) {
        printf("评估: 体重过轻\n");
        printf("建议: 适当增加营养摄入,进行力量训练\n");
    } else if (bmi < 24) {
        printf("评估: 正常体重\n");
        printf("建议: 保持良好的饮食和运动习惯\n");
    } else if (bmi < 28) {
        printf("评估: 超重\n");
        printf("建议: 控制饮食,增加有氧运动\n");
    } else {
        printf("评估: 肥胖\n");
        printf("建议: 请咨询医生,制定科学的减重计划\n");
    }

    return 0;
}

练习3:年份判断器

编写程序判断用户输入的年份是否为闰年:

  • 能被4整除但不能被100整除的年份是闰年
  • 能被400整除的年份是闰年

下一章预告: 学会了条件语句后,我们将学习循环结构,让程序能够重复执行某些操作,实现更强大的功能!


这里是 /* Huajidawang */ 的个人主页