if 和 switch
到现在为止,程序都是从上往下,每一行都跑。这一课让程序学会选择:条件成立就做这件事,不成立就做那件事,或者干脆跳过。
1#include <stdio.h>2 3int main(void) {4 int temp = 31;5 if (temp > 30) {6 printf("很热,记得多喝水\n");7 }8 printf("今天 %d 度\n", temp);9 return 0;10}
很热,记得多喝水 今天 31 度
if 后面的括号里是条件。条件成立,花括号里的代码块就跑;不成立,就跳过它。最后一个 printf 在 if 外面,不管怎样都会跑。把 31 改成 25 再运行一次看看。
比较两个值
条件里最常用的是比较运算符:
| 写 | 意思 |
|---|---|
a == b | 等于(两个等号) |
a != b | 不等于 |
a < b | 小于 |
a > b | 大于 |
a <= b | 小于或等于 |
a >= b | 大于或等于 |
比较的结果是一个整数:成立是 1,不成立是 0。可以直接用 %d 打出来:
1#include <stdio.h>2 3int main(void) {4 int a = 7;5 int b = 10;6 printf("%d\n", a < b);7 printf("%d\n", a == b);8 printf("%d\n", a != b);9 printf("%d\n", a >= 7);10 return 0;11}
1 0 1 1
if 和 else
条件不成立时也想做点什么,就加上 else。两个代码块里,正好有一个会跑:
1#include <stdio.h>2 3int main(void) {4 int score = 58;5 if (score >= 60) {6 printf("及格\n");7 } else {8 printf("不及格,还差 %d 分\n", 60 - score);9 }10 printf("成绩已登记\n");11 return 0;12}
不及格,还差 2 分 成绩已登记
点单步,看看程序跳过了哪几行。
小技巧: 代码块里只有一条语句时,花括号可以不写,但最好一直写上。以后往里面加第二行时,不会因为忘了补括号而出错。
多个条件:else if
有好几种情况,就用 else if 接起来。程序从上往下一个一个地试,第一个成立的代码块跑完,后面的就都不看了:
1#include <stdio.h>2 3int main(void) {4 int score = 85;5 if (score >= 90) {6 printf("优秀\n");7 } else if (score >= 75) {8 printf("良好\n");9 } else if (score >= 60) {10 printf("及格\n");11 } else {12 printf("不及格\n");13 }14 return 0;15}
良好
85 也满足 score >= 60,但只显示了「良好」:前面的条件已经成立,后面的不会再试。所以顺序很重要。
这段程序显示什么?
1#include <stdio.h>2 3int main(void) {4 int score = 95;5 if (score >= 60) {6 printf("及格\n");7 } else if (score >= 90) {8 printf("优秀\n");9 }10 return 0;11}
程序先试 score >= 60,成立,显示「及格」,后面的 else if 就不看了。想让 95 分显示「优秀」,要把更严的条件 score >= 90 放在前面。
并且、或者、不是
几个条件可以连起来:
| 写 | 意思 | 什么时候成立 |
|---|---|---|
a && b | 并且 | 两边都成立 |
a || b | 或者 | 至少一边成立 |
!a | 不是 | a 不成立 |
1#include <stdio.h>2 3int main(void) {4 int temp = 22;5 int age = 70;6 if (temp >= 18 && temp <= 26) {7 printf("温度正合适\n");8 }9 if (age < 12 || age >= 65) {10 printf("门票半价\n");11 }12 if (!(temp > 30)) {13 printf("不用开空调\n");14 }15 return 0;16}
温度正合适 门票半价 不用开空调
数学里写 18 <= temp <= 26,C 里要写成 temp >= 18 && temp <= 26。直接写 18 <= temp <= 26 能编译,意思却完全不一样:先算 18 <= temp,得到 0 或 1,再拿这个数和 26 比,结果永远成立。
真和假就是数
C 没有单独的「真」「假」:条件就是一个数,0 是假,不是 0 的数都是真,负数也算真。所以可以直接拿一个数当条件:
1#include <stdio.h>2 3int main(void) {4 int stock = 0;5 if (stock) {6 printf("有货\n");7 } else {8 printf("卖完了\n");9 }10 printf("%d\n", !stock);11 printf("%d\n", -3 && 5);12 return 0;13}
卖完了 1 1
stock 是 0,所以是假;!stock 把假变成真,得到 1。-3 和 5 都不是 0,&& 两边都是真,结果是 1。
= 和 == 不一样
= 是赋值,== 才是比较。在 if 里少写一个等号,是 C 里最常见的错误之一:
1#include <stdio.h>2 3int main(void) {4 int score = 70;5 if (score = 100) {6 printf("满分!\n");7 }8 printf("score 现在是 %d\n", score);9 return 0;10}
满分! score 现在是 100
score = 100 不是在问「score 是不是 100」,而是把 100 放进 score。这个式子的值是 100,不是 0,所以条件成立。于是 70 分也显示了「满分!」,而且 score 被改成了 100。把 = 改成 == 再运行一次。
小技巧: 程序能运行、结果却不对时,先找找 if 里是不是少了一个等号。
switch:按值分情况
拿一个整数和几个固定的值比,用 switch 写起来更清楚:
1#include <stdio.h>2 3int main(void) {4 int day = 6;5 switch (day) {6 case 1:7 case 2:8 case 3:9 case 4:10 case 5:11 printf("上班\n");12 break;13 case 6:14 case 7:15 printf("周末\n");16 break;17 default:18 printf("没有这一天\n");19 }20 return 0;21}
周末
switch 找到和 day 相等的 case,从那里开始往下跑,遇到 break 就跳出 switch。几个 case 挨着写,就是它们共用同一段代码。哪个 case 都不相等时,跑 default。
case 后面只能是固定的整数或字符(比如 'A'),不能是变量,也不能是小数。
**忘了 break**,程序不会停,会接着跑下一个 case 的代码,这叫「掉下去」:
1#include <stdio.h>2 3int main(void) {4 char grade = 'B';5 switch (grade) {6 case 'A':7 printf("优秀\n");8 case 'B':9 printf("良好\n");10 case 'C':11 printf("及格\n");12 default:13 printf("继续努力\n");14 }15 return 0;16}
良好 及格 继续努力
grade 是 'B',从 case 'B' 开始跑,可是一个 break 都没有,于是一路掉到底,显示了三行。点单步看它是怎么往下走的。最后一道练习就是一个这样的 switch,等你来修。
练一练
写好代码,点检查。提示随便看,实在想不出来再看答案。
奇数还是偶数
✓用 if 和 else 判断 n 是奇数还是偶数。n 是 7 时,显示 7 是奇数;改成 8 时,应该显示 8 是偶数。
7 是奇数
1#include <stdio.h>2 3int main(void) {4 int n = 7;5 6 return 0;7}
冷、舒适还是热
✓温度低于 18 度显示 冷,18 到 26 度(都包括)显示 舒适,高于 26 度显示 热。temp 是 27。
热
1#include <stdio.h>2 3int main(void) {4 int temp = 27;5 6 return 0;7}
修好红绿灯
✓light 是 'Y'(黄灯),程序却显示了好几行。改好它,只显示 慢下来。
慢下来
1#include <stdio.h>2 3int main(void) {4 char light = 'Y';5 switch (light) {6 case 'R':7 printf("停\n");8 case 'Y':9 printf("慢下来\n");10 case 'G':11 printf("走\n");12 default:13 printf("不认识的灯\n");14 }15 return 0;16}
这一课学会了
- 比较运算符
==!=<><=>=的结果是1(成立)或0(不成立)。 if/else if/else从上往下试,只跑第一个成立的代码块,所以顺序很重要。&&是并且,||是或者,!是不是;范围要写成temp >= 18 && temp <= 26。- 在 C 里,
0是假,不是 0 的数都是真。 =是赋值,==是比较;if (x = 100)永远成立,还会改掉x。switch按整数或字符的值分情况;每个case后面写break,不然会掉到下一个case。