import{_ as l,c as a,j as s,a6 as i,o as n}from"./chunks/framework.CZKtKhAm.js";const p="/c/assets/1.CTMA-Poz.jpg",h="/c/assets/2.B2g4y1OY.png",k="/c/assets/3.DEoM0p3m.png",t="/c/assets/4.DxEoA7Ht.png",e="/c/assets/5.DtY5Pf6u.png",r="/c/assets/6.CButBugT.png",E="/c/assets/7.DG_I9X5w.png",d="/c/assets/8.Cw8LCRHN.png",g="/c/assets/9.TqkSPw2X.png",c="/c/assets/10.DJkVOkw7.png",y="/c/assets/11.Bkdbe2NL.png",F="/c/assets/12.D2yeCvfw.png",H=JSON.parse('{"title":"第一章:概述","description":"","frontmatter":{},"headers":[],"relativePath":"notes/01_c-basic/04_xdx/index.md","filePath":"notes/01_c-basic/04_xdx/index.md","lastUpdated":1721701891000}'),b={name:"notes/01_c-basic/04_xdx/index.md"},u=i('
流程控制结构
是用来控制程序中各语句执行顺序
的语句,并且可以将语句组合成能完成一定功能
的小逻辑模块
。
在程序设计中规定了三种
流程结构,如下所示:
顺序结构
:程序从上到下逐行执行,中间没有任何判断和跳转。分支结构
:根据条件,有选择的执行某段代码。在 C 语言中,有 if...else
和 switch...case
两种分支语句。循环结构
:根据循环条件,重复性的执行某段代码。在 C 语言中,有 for
、while
、do...while
三种循环结构。在生活中的洗衣工厂
,就包含了上述的三种流程结构,如下所示:
#include <stdio.h>
int main() {
int x = 1;
int y = 2;
printf("x = %d \\n", x); // x = 1
printf("y = %d \\n", y); // y = 2
// 对 x 和 y 的值进行修改
x++;
y = 2 * x + y;
x = x * 10;
printf("x = %d \\n", x); // x = 20
printf("y = %d \\n", y); // y = 6
return 0;
}
if(条件表达式){
语句;
}
NOTE
非0
表示真(true)
,0
表示假(false)
。非0
),就会执行代码块中的语句;否则,就不会执行代码块中的语句。需求:成年人心率的正常范围是每分钟 60~100 次。体检时,如果心率不在此范围内,则提示需要做进一步的检查。
示例:
#include <stdio.h>
int main() {
int heartBeats = 0;
printf("请输入您的心率:");
scanf("%d", &heartBeats);
if (heartBeats < 60 || heartBeats > 100) {
printf("您的心率不在正常范围内,请做进一步的检查。\\n");
}
printf("体检结束!!!");
return 0;
}
需求:根据年龄判断,如果是未成年人,则提示 "未成年人请在家长陪同下访问!" 。
示例:
#include <stdio.h>
int main() {
int age = 0;
printf("请输入你的年龄:");
scanf("%d", &age);
if (age < 18) {
printf("未成年人请在家长陪同下访问!\\n");
}
printf("欢迎继续访问!");
return 0;
}
if(条件表达式) {
语句块1;
}else {
语句块2;
}
NOTE
非0
表示真(true)
,0
表示假(false)
。非0
),就会执行代码块 1 中的语句;否则,执行代码块 2 中的语句。需求:判断一个整数,是奇数还是偶数。
示例:
#include <stdio.h>
int main() {
int num = 0;
printf("请输入一个整数:");
scanf("%d", &num);
if (num % 2 == 0) {
printf("%d 是偶数\\n", num);
} else {
printf("%d 是奇数\\n", num);
}
return 0;
}
需求:输入年龄,如果大于18岁,则输出 "你年龄大于18,要对自己的行为负责!";否则,输出 "你的年龄不大这次放过你了。"
示例:
#include <stdio.h>
int main() {
int age = 0;
printf("请输入年龄:");
scanf("%d", &age);
if (age > 18) {
printf("你年龄大于18,要对自己的行为负责!\\n");
} else {
printf("你的年龄不大,这次放过你了!\\n");
}
return 0;
}
NOTE
#include <stdio.h>
int main() {
int year = 0;
printf("请输入年份:");
scanf("%d", &year);
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
printf("%d 是闰年\\n", year);
} else {
printf("%d 不是闰年\\n", year);
}
return 0;
}
if (条件表达式1) {
语句块1;
} else if (条件表达式2) {
语句块2;
}
...
} else if (条件表达式n) {
语句块n;
} else {
语句块n+1;
}
NOTE
非0
表示真(true)
,0
表示假(false)
。非0
)还是假(值为 0
): 互斥
(彼此之间没有交集)关系时,条件判断语句及执行语句间顺序无所谓。包含
关系时,必须小上大下 / 子上父下
,否则范围小的条件表达式将不可能被执行。{}
是可以省略的;但是,强烈建议保留!!!需求:张三参加考试,他和父亲达成协议,如果成绩不到 60 分没有任何奖励;如果成绩 60分(含)到 80 分,奖励一个肉夹馍;如果成绩 80 分(含)到 90 分,奖励一个 ipad;如果成绩 90 分及以上,奖励一部华为 mate60 pro 。
示例:
#include <stdio.h>
int main() {
int score = 0;
printf("请输入分数:");
scanf("%d", &score);
// 容错:分数不可能小于 0 或大于 100
if (score < 0 || score > 100) {
printf("输入的分数有误!\\n");
return 0;
}
if (score >= 90) {
printf("奖励你一部华为 mate60 pro\\n");
} else if (score >= 80) {
printf("奖励你一个 ipad\\n");
} else if (score >= 60) {
printf("奖励你一个肉夹馍\\n");
} else {
printf("你的成绩不及格,没有任何奖励!");
}
return 0;
}
需求:判断水的温度,如果大于 95℃,则打印 "开水";如果大于 70℃ 且小于等于 95℃,则打印 "热水";如果大于 40℃ 且小于等于 70℃,则打印 "温水";如果小于等于 40℃,则打印 "凉水"。
示例:
#include <stdio.h>
int main() {
int temperature = 0;
printf("请输入水的温度:");
scanf("%d", &temperature);
if (temperature > 95) {
printf("开水 \\n");
} else if (temperature > 70 && temperature <= 95) {
printf("热水 \\n");
} else if (temperature > 40 && temperature <= 70) {
printf("温水 \\n");
} else {
printf("凉水 \\n");
}
return 0;
}
switch(表达式){
case 常量值1:
语句块1;
//break;
case 常量值2:
语句块2;
//break;
...
case 常量值n:
语句块n;
//break;
[default:
语句块n+1;
]
}
NOTE
需求:编写一个程序,该程序可以接收一个字符,比如:a、b、c、d;其中, a 表示星期一,b 表示星期二…,根据用户的输入显示相应的信息,要求使用 switch 语句。
示例:
#include <stdio.h>
int main() {
char chs;
printf("请输入一个字符(a、b、c、d):");
scanf("%c", &chs);
switch (chs) {
case 'a':
printf("今天是星期一 \\n");
printf("窗前明月光 \\n");
break;
case 'b':
printf("今天是星期二 \\n");
printf("疑是地上霜 \\n");
break;
case 'c':
printf("今天是星期三 \\n");
printf("举头望明月 \\n");
break;
case 'd':
printf("今天是星期四 \\n");
printf("低头思故乡 \\n");
break;
default:
printf("输入错误!");
break;
}
return 0;
}
需求:编写程序,输入月份,输出该月份有多少天。说明:1 月、3 月、5 月、7月、8 月、10 月、12 月有 31 天,4 月、6 月、9 月、11 月有 30 天,2 月有 28 天或 29 天。
示例:
#include <stdio.h>
int main() {
int month;
printf("请输入月份 (1-12):");
scanf("%d", &month);
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
printf("%d 月有 31 天\\n", month);
break;
case 4:
case 6:
case 9:
case 11:
printf("%d 月有 30 天\\n", month);
break;
case 2:
printf("%d 月有 28 天或 29 天\\n", month);
break;
default:
printf("输入错误!");
break;
}
return 0;
}
NOTE
嵌套分支层数不宜过多,建议最多不要超过 3 层。
NOTE
#include <stdio.h>
int main() {
int month;
int age;
double price = 60;
printf("请输入月份 (1-12):");
scanf("%d", &month);
printf("请输入年龄:");
scanf("%d", &age);
// 旺季
if (month >= 4 && month <= 10) {
if (age < 18) {
price /= 2;
} else if (age > 60) {
price /= 3;
}
} else {
if (age >= 18) {
price = 40;
} else {
price = 20;
}
}
printf("票价: %.2lf\\n", price);
return 0;
}
NOTE
如果种子的值相同,那么每次生成的随机数将相同,解决方案就是将种子的值设置为当前的时间戳。
srand(10); // seed 种⼦ rand random 随机
NOTE
随机数函数在 #include <stdlib.h>
中声明。
// 根据种⼦值产⽣⼀个 0-32767 范围的随机数
int result = rand();
int random_in_range(int min, int max) {
return rand() % (max - min + 1) + min;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// 生成指定范围的随机数的函数
int randomInRange(int min, int max) {
return rand() % (max - min + 1) + min;
}
int main() {
// 使用当前时间作为种子
srand(time(0));
// 定义范围
int min = 1;
int max = 100;
// 生成并打印随机数
for (int i = 0; i < 10; ++i) {
int random = randomInRange(min, max);
printf("%d \\n", random);
}
return 0;
}
for(初始化条件①;循环条件表达式②;迭代语句④){
循环体语句③
}
NOTE
,
隔开)。,
隔开)。NOTE
执行过程是:① --> ② --> ③ --> ④ --> ② --> ③ --> ④ --> ... --> ② 。
需求:输出 5 行 Hello World!
。
示例:
#include <stdio.h>
int main() {
for (int i = 1; i <= 5; ++i) {
printf("Hello World!\\n");
}
return 0;
}
需求:求 1 ~ 100 之内所有偶数的和,以及偶数的个数。
示例:
#include <stdio.h>
int main() {
int sum = 0;
int count = 0;
for (int i = 1; i <= 100; i++) {
if (i % 2 == 0) {
sum += i;
count++;
}
}
printf("1 ~ 100 中的所有偶数的和为: %d \\n", sum);
printf("1 ~ 100 中的所有偶数的个数为: %d \\n", count);
return 0;
}
需求:输出所有的水仙花数,所谓水仙花数是指一个 3 位数,其各个位上数字立方和等于其本身,例如:153 = 1×1×1 + 3×3×3 + 5×5×5
。
示例:
#include <stdio.h>
int main() {
int count = 0;
for (int i = 100; i <= 999; i++) {
// 获取三位数
int ge = i % 10;
int shi = i / 10 % 10;
int bai = i / 100;
// 判定是否为水仙花数
if (ge * ge * ge + shi * shi * shi + bai * bai * bai == i) {
printf("水仙花数:%d\\n", i);
count++;
}
}
printf("水仙花数总个数:%d\\n", count);
return 0;
}
需求:将 1 ~ 10 倒序输出,如:10 、9 、8 ...
示例:
#include <stdio.h>
int main() {
for (int i = 10; i >= 0; i--) {
printf("%d ", i);
}
return 0;
}
NOTE
#include <stdio.h>
int main() {
int m = 12, n = 20;
// 取出两个数中的较小值
int min = (m < n) ? m : n;
for (int i = min; i >= 1; i--) {
if (m % i == 0 && n % i == 0) {
printf("最大公约数是:%d\\n", i); // 公约数
break; //跳出当前循环结构
}
}
// 取出两个数中的较大值
int max = (m > n) ? m : n;
for (int i = max; i <= m * n; i++) {
if (i % m == 0 && i % n == 0) {
printf("最小公倍数是:%d\\n", i); // 公倍数
break;
}
}
return 0;
}
初始化条件①;
while (循环条件语句②) {
循环体语句③;
迭代语句④;
}
NOTE
while(循环条件部分)
中循环条件为非0
值,表示 true
、真
;为0
值,表示 false
、假
。可以相互转换
,二者没有性能上的差别。初始化条件部分的作用域不同
。NOTE
执行过程是:① --> ② --> ③ --> ④ --> ② --> ③ --> ④ --> ... --> ② 。
需求:输出 5 行 Hello World!
。
示例:
#include <stdio.h>
int main() {
int i = 1;
while (i <= 5) {
printf("Hello World!\\n");
i++;
}
return 0;
}
需求:求 1 ~ 100 之内所有偶数的和,以及偶数的个数。
示例:
#include <stdio.h>
int main() {
int sum = 0;
int count = 0;
int i = 1;
while (i <= 100) {
if (i % 2 == 0) {
sum += i;
count++;
}
i++;
}
printf("1 ~ 100 中的所有偶数的和为: %d \\n", sum);
printf("1 ~ 100 中的所有偶数的个数为: %d \\n", count);
return 0;
}
需求:世界最高山峰是珠穆朗玛峰,它的高度是 8848.86 米,假如我有一张足够大的纸,它的厚度是 0.1 毫米。请问,我折叠多少次,可以折成珠穆朗玛峰的高度?
示例:
#include <stdio.h>
int main() {
// 折叠的次数
int count = 0;
// 珠峰的高度
int zfHeight = 8848860;
// 每次折叠的高度
double paperHeight = 0.1;
while (paperHeight <= zfHeight) {
count++;
paperHeight *= 2;
}
printf("需要折叠 %d 次,才能得到珠峰的高度。\\n", count);
printf("折纸的高度为 %.2f 米,超过了珠峰的高度", paperHeight / 1000);
return 0;
}
①初始化部分;
do{
③循环体部分
④迭代部分
}while(②循环条件部分);
NOTE
do{} while();
最后有一个分号。NOTE
执行过程是:① --> ③ --> ④ --> ② --> ③ --> ④ --> ② --> ... --> ② 。
#include <stdio.h>
int main() {
int sum = 0;
int count = 0;
int i = 1;
do {
if (i % 2 == 0) {
sum += i;
count++;
}
i++;
} while (i <= 100);
printf("1 ~ 100 中的所有偶数的和为: %d \\n", sum);
printf("1 ~ 100 中的所有偶数的个数为: %d \\n", count);
return 0;
}
需求:实现 ATM 取款机功能。
示例:
#include <stdio.h>
int main() {
// 账户余额
double balance = 0.0;
// 客户选择
int selection;
// 存款金额
double addMoney;
// 取款金额
double minusMoney;
// 退出标识
bool exitFlag = false;
do {
printf("=========ATM========\\n");
printf("\\t1、存款\\n");
printf("\\t2、取款\\n");
printf("\\t3、显示余额\\n");
printf("\\t4、退出\\n");
printf("请选择(1-4):");
scanf("%d", &selection);
switch (selection) {
case 1:
printf("您当前的余额是: %.2f\\n", balance);
printf("请输入存款金额:");
scanf("%lf", &addMoney);
balance += addMoney;
printf("存款成功,您当前的余额是:%.2f\\n", balance);
break;
case 2:
printf("您当前的余额是: %.2f\\n", balance);
printf("请输入取款金额:");
scanf("%lf", &minusMoney);
if (minusMoney > balance) {
printf("余额不足,取款失败。\\n");
} else {
balance -= minusMoney;
printf("取款成功,您的余额为:%.2f\\n", balance);
}
break;
case 3:
printf("您的账户余额为:%.2f\\n", balance);
break;
case 4:
exitFlag = true;
printf("欢迎下次再来。\\n");
break;
default:
printf("输入有误,请重新输入。\\n");
break;
}
} while (!exitFlag);
return 0;
}
for(初始化语句①; 循环条件语句②; 迭代语句⑦) {
for(初始化语句③; 循环条件语句④; 迭代语句⑥) {
循环体语句⑤;
}
}
NOTE
行数
,内层循环控制列数
。需求:打印 5 行 *
,要求每行 6 个 *
。
示例:
#include <stdio.h>
int main() {
for (int i = 1; i <= 5; ++i) {
for (int j = 1; j < 6; ++j) {
printf("* ");
}
printf("\\n");
}
return 0;
}
需求:打印 5 行直角三角形。
示例:
#include <stdio.h>
int main() {
for (int i = 1; i <= 5; ++i) {
for (int j = 1; j <= i; ++j) {
printf("* ");
}
printf("\\n");
}
return 0;
}
需求:打印 5 行倒直角三角形。
示例:
#include <stdio.h>
int main() {
for (int i = 1; i <= 5; ++i) {
for (int j = 1; j <= 6 - i; ++j) {
printf("* ");
}
printf("\\n");
}
return 0;
}
需求:打印 9 ×
9 乘法表。
示例:
#include <stdio.h>
int main() {
for (int i = 1; i <= 9; ++i) {
for (int j = 1; j <= i; ++j) {
printf("%d × %d = %d ", i, j, i * j);
}
printf("\\n");
}
return 0;
}
while(1){
...
}
for(;;){
...
}
NOTE
#include <stdio.h>
int main() {
// 记录输入的整数
int num = 0;
// 记录正数个数
int positiveCount = 0;
// 记录负数个数
int negativeCount = 0;
while (true) {
printf("请输入一个整数:");
scanf("%d", &num);
if (num > 0) {
positiveCount++;
} else if (num < 0) {
negativeCount++;
} else {
printf("程序结束!\\n");
break;
}
}
printf("正数的个数:%d\\n", positiveCount);
printf("负数的个数:%d\\n", negativeCount);
return 0;
}
NOTE
break 一旦执行,就结束(或跳出)当前循环结构;并且,此关键字的后面,不能声明其它语句。
3
,就停止打印#include <stdio.h>
int main() {
for (int i = 0; i < 10; ++i) {
if (i == 3) {
break;
}
printf("%d \\n", i);
}
printf("程序结束!\\n");
return 0;
}
#include <stdio.h>
int main() {
bool isFlag = false;
int num = 0;
do {
printf("请输入一个整数(必须大于 1 ):");
scanf("%d", &num);
if (num <= 1) {
printf("输入的数字不是合法,请重新输入!!!\\n");
isFlag = true;
} else {
isFlag = false;
}
} while (isFlag);
bool isPrime = true;
for (int i = 2; i < num; i++) {
if (num % i == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
printf("%d 是一个质数\\n", num);
} else {
printf("%d 不是一个质数\\n", num);
}
printf("程序结束!\\n");
return 0;
}
NOTE
continue 一旦执行,就结束(或跳出)当次循环结构;并且,此关键字的后面,不能声明其它语句。
3
,就继续下一次打印#include <stdio.h>
int main() {
for (int i = 0; i < 10; ++i) {
if (i == 3) {
continue;
}
printf("%d \\n", i);
}
printf("程序结束!\\n");
return 0;
}
#include <stdio.h>
int main() {
for (int i = 1; i <= 100; i++) {
if (i % 7 == 0 || i % 10 == 7 || i / 10 == 7) {
continue;
}
printf("%d ", i);
}
printf("程序结束!\\n");
return 0;
}
NOTE
和 break 和 continue 不同的是,return 直接结束整个方法,不管这个 return 处于多少层循环之内。
#include <stdio.h>
int main() {
for (int i = 1; i <= 100; i++) {
if (i % 7 == 0 || i % 10 == 7 || i / 10 == 7) {
return 0; // 结束整个函数或方法
}
printf("%d ", i);
}
printf("程序结束!\\n");
return 0;
}