第二章:流程控制 (选择结构)

本章核心: 让程序学会“思考”和“做决定”(如果…就…,否则…)。


1. 关系运算符与逻辑运算符

判断语句基于关系运算符(例如 >==)的结果(真或假)。

1.1 关系运算符

== (等于), != (不等于), >, <, >=, <=

1.2 逻辑运算符

&& (与), || (或), ! (非)。

补充考点:

  • 数学写法 vs C 语言写法

    • 数学里写:$0 < x < 10$

    • C 语言必须写成:(x > 0) && (x < 10)

  • 优先级

    • ! (最高) > 算术运算符 > 关系运算符 > && > || (最低)。

习题 1 (对应:关系与逻辑运算)

题目: 编写代码判断输入的三个整数 a, b, c 能否构成三角形。

构成三角形的条件: 任意两边之和大于第三边。

要求: 使用逻辑与运算符 && 连接三个条件。

预期输出结果:

1
2
请输入三边: 3 4 5
可以构成三角形

答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

int main() {
int a, b, c;
printf("请输入三边: ");
scanf("%d %d %d", &a, &b, &c);

// 必须三个条件同时满足,所以用 &&
if ((a + b > c) && (a + c > b) && (b + c > a)) {
printf("可以构成三角形\n");
} else {
printf("无法构成三角形\n");
}
return 0;
}

易错:

  1. a+b>c 等条件用 || 连接(变成了“只要有一组边满足就行”,逻辑错误)。

  2. 试图写成数学连写形式 a+b>c>... (C 语言不支持)。


2. if-else 结构

用于根据条件的真假执行不同的代码块。

1
2
3
4
5
if (条件表达式) {
// 1. 如果条件为真 (非0),执行这里的代码
} else {
// 2. 如果条件为假 (0),执行这里的代码
}

示例: 判断一个数是否为正数。

1
2
3
4
5
6
7
int num = -5;
if (num > 0) {
printf("是正数\n");
} else {
printf("不是正数\n");
}
// 输出: 不是正数

补充考点 (悬挂 else):

当有多个 if 和 else 嵌套时,C 语言规定:else 总是与它上面最近的、未配对的 if 配对。

  • 建议:无论只有一行代码还是多行,永远加上 { },防止逻辑混乱。

3. 多重条件 (if-else if-else)

用于处理多个互斥的条件判断。

1
2
3
4
5
6
7
if (条件 1) {
// 满足条件 1
} else if (条件 2) {
// 不满足条件 1,但满足条件 2
} else {
// 所有条件都不满足
}

习题 2

题目: 编写程序,接收用户输入的整数成绩 (score),根据以下标准输出评定结果。

要求:

  1. 使用 if-else if-else 结构。

  2. 成绩范围 0-100。

    • $\ge 90$: A (优秀)

    • $\ge 70$ 且 $< 90$: B (良好)

    • $< 70$: C (及格线以下)

预期输出结果:

1
2
3
请输入您的成绩 (0-100): 
85
评定结果: B (良好)

答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>

int main() {
int score;

printf("请输入您的成绩 (0-100): \n");
scanf("%d", &score);

// 标准逻辑流:从高到低判断,代码更易读
if (score >= 90) {
printf("评定结果: A (优秀)\n");
}
else if (score >= 70) {
// 能走到这里,说明分数肯定小于 90,所以只需判断是否 >= 70
printf("评定结果: B (良好)\n");
}
else {
// 剩下的所有情况 (即小于 70)
printf("评定结果: C (及格线以下)\n");
}

return 0;
}

易错:

  1. 逻辑顺序混乱:如果先判断 score >= 70,那么 95 分也会被判定为 B(因为 95 也大于 70)。

  2. else 后面画蛇添足加条件(else (score < 70) 是语法错误,else 后不能跟括号)。


4. switch-case 结构

适用于一个变量的取值,需要执行多分支选择的情况。

1
2
3
4
5
6
7
8
9
10
switch (变量/表达式) {
case 常量值1:
// 执行代码
break; // 必须要有!
case 常量值2:
// 执行代码
break;
default:
// 如果所有 case 都不匹配,则执行 default
}

重点提醒 :

易错点: switch 语句中 break 的使用

  • 陷阱: 如果一个 case 分支中没有 break,程序会继续执行下一个 case 分支的代码,直到遇到 breakswitch 结束。这通常被称为穿透 (fall-through),是初学者最常犯的逻辑错误。

补充考点 (类型限制): switch 括号里的变量,以及 case 后面的值,必须是整数 (int) 或字符 (char)。

  • 错误case 3.14: (不能用浮点数)

  • 错误case "A": (不能用字符串,字符用单引号 'A')


习题 3

题目: 编写程序,接收用户输入的星期数 (1-7 之间的整数 day),输出对应的星期名称(Monday, Tuesday… Sunday)。如果输入其他数字,输出 “Error”。

要求:

  1. 必须使用 switch-case 结构。

  2. 易错点: 每一个 case 结束时必须有 break;

  3. 默认处理: 使用 default: 处理非 1-7 的输入。

预期输出结果:

1
2
3
请输入星期数 (1-7): 
3
星期三

答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>

int main() {
int day;

printf("请输入星期数 (1-7):\n");
scanf("%d", &day);

switch(day) {
case 1:
printf("星期一\n");
break; // ✅ 必须有 break,防止穿透
case 2:
printf("星期二\n");
break;
case 3:
printf("星期三\n");
break;
case 4:
printf("星期四\n");
break;
case 5:
printf("星期五\n");
break;
case 6:
printf("星期六\n");
break;
case 7:
printf("星期日\n");
break;
default:
// 处理所有非 1-7 的情况
printf("输入错误,请输入1到7之间的数字。\n");
}

return 0;
}

易错:

  1. 漏写 break; 导致程序打印出多天的名字。

  2. switch 后面的括号里不需要分号 ;

  3. default 拼写错误。