代码并非必须自上而下顺序执行。条件分支(decision making)能够让程序进行判断,依据条件成立与否,选择执行对应的代码。我们先从最简单的 if 语句开始学习。

if 语句

if 会检测表达式的真假,并根据结果选择执行对应的代码。最基础的判断是比较两个值是否相等,使用 ==:

int target = 10;
if (target == 10) {
    printf("target 等于 10\n");
}

除此之外,也可以判断两个数是否不等、大于或者小于:

int foo = 1, bar = 2;
if (foo < bar) {
    printf("foo 比 bar 小\n");
}
if (foo > bar) {
    printf("foo 比 bar 大\n");
}

注意 if 括号里最终都会当成整数判断:0 为假,非 0 为真。

else:条件不成立时怎么办

当条件不为真,需要执行另一部分代码时,可以使用 else:

开始条件?真执行 if 分支假执行 else 分支后续代码结束

if / else 执行流程:条件为真走 if 分支,为假走 else 分支

int foo = 1, bar = 2;
if (foo < bar) {
    printf("foo 比 bar 小\n");
} else {
    printf("foo 比 bar 大\n");
}

嵌套 if:条件里面再套条件

if 内部可以继续嵌套 if,适用于多层逻辑判断。

int peanuts_eaten = 22;        // 已经吃了多少个
int peanuts_in_jar = 100;      // 罐子里有多少个
int max_peanut_limit = 50;     // 最多能吃多少

if (peanuts_in_jar > 80) {
    if (peanuts_eaten < max_peanut_limit) {
        printf("随便吃,管够!\n");
    }
} else {
    if (peanuts_eaten > peanuts_in_jar) {
        printf("没了,不能再拿了!\n");
    } else {
        printf("行,再来一个。\n");
    }
}

但嵌套层次过多会降低代码可读性,条件允许时尽量拆分为独立的 if 序列。

用 && || ! 组合多个条件

几个条件要一起判断时,用逻辑运算符:&& 表示都要成立,|| 表示至少一个成立,! 取反:

int foo = 1, bar = 2, moo = 3;
if (foo < bar && moo > bar) {
    printf("foo 比 bar 小,并且 moo 比 bar 大\n");
}
if (foo < bar || moo > bar) {
    printf("foo 比 bar 小,或者 moo 比 bar 大\n");
}
if (target != 10) {
    printf("target 不等于 10\n");
}

这里有一个实用特性:短路求值。对于 &&,若左侧表达式结果为假,则右侧不会执行;对于 ||,若左侧表达式结果为真,则右侧不会执行。例如 age != 0 && score / age > 60,就可以利用该特性规避除零错误,防止程序崩溃。

switch:按整数取值分散处理

一个整数值对应多种分支用 switch 比一长串 else if 更好。下面这个示例是经典的猜谜:

C 语言 if-else 猜数字判断示例运行
#include <stdio.h>

int main(void) {
    int guess;
    printf("猜一个数字(答案是 555):");
    scanf("%d", &guess);

    if (guess == 555) {
        printf("答对了!\n");
    } else if (guess < 555) {
        printf("猜小了。\n");
    } else {
        printf("猜大了。\n");
    }
    return 0;
}

switch 与 case

C 语言 switch 分支判断示例运行
int day = 3;
switch (day) {
    case 1: printf("星期一\n"); break;
    case 2: printf("星期二\n"); break;
    case 3: printf("星期三\n"); break;
    default: printf("不是星期几\n"); break;
}

使用 switch 有几点细节需要注意:

  • switch 后的表达式与 case 常量值都必须是整型(字符类型也适用,本质上存储的是 ASCII 整数)。
  • 一旦匹配成功,代码会持续向下执行,直到遇到 break; 才退出分支。如果遗漏 break,程序会继续执行后续 case,这种现象称为落空(fallthrough),需要格外留意。
  • default 用于处理所有未匹配到的情况,一般写在末尾。

条件分支部分就讲到这里。下一章节介绍循环,实现代码的重复执行。