代码并非必须自上而下顺序执行。条件分支(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 分支
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 更好。下面这个示例是经典的猜谜:
#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
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用于处理所有未匹配到的情况,一般写在末尾。
条件分支部分就讲到这里。下一章节介绍循环,实现代码的重复执行。