第四章 循环控制
关键考点总览
跳转到:关键考点总览- for循环语句格式与执行流程
- while循环语句格式与执行流程
- do while循环语句格式与执行流程
- 三种循环的相互转换
- 逗号表达式的执行规则
- break语句的作用与适用范围
- continue语句的作用
- 死循环的构造与退出
- 枚举法的基本思想与实现
- 贪婪法的基本思想与局限性
详细知识点
跳转到:详细知识点4.1 循环基础概念
跳转到:4.1 循环基础概念定义/语法
跳转到:定义/语法-
循环三要素:循环初始条件、循环终止条件、循环控制变量的更新规则(趋向终止条件)
[来源:第4章 p3] -
循环周期:循环体所有语句的一次完全执行称为一个循环周期
[来源:第4章 p9,Notes]
规则/规范
跳转到:规则/规范-
需要多次重复执行某任务的问题考虑使用循环来解决
[来源:第4章 p3] -
计算机善于完成繁重的、但有规律的重复性计算,这是采用循环控制的内在逻辑
[来源:第4章 p2]
4.2 for循环
跳转到:4.2 for循环定义/语法
跳转到:定义/语法- for语句格式:
for(表达式1; 表达式2; 表达式3) 语句
- 表达式1:初始化循环控制变量
- 表达式2:循环控制条件(可转换为bool的表达式;结果为0/false则退出循环)
- 表达式3:每个循环周期结束后对循环控制变量的修正
[来源:第4章 p9]
执行逻辑
跳转到:执行逻辑- for循环执行过程:
- 计算表达式1(初始化循环控制变量)
- 计算表达式2(循环控制条件)
- 如果表达式2结果非0(true),执行循环体,然后计算表达式3,回到步骤2
- 如果表达式2结果为0(false),for语句执行结束
[来源:第4章 p9]
代码模式
跳转到:代码模式-
典型for循环示例:
for (int i = 0; i < 100; i++) ... // 从0到99for (int i = 100; i > 1; i -= 2) ... // 从100递减,步长2[来源:第4章 p9]
-
从1加到100的标准写法:
int i, s = 0;for (i = 1; i <= 100; ++i) s += i;[来源:第4章 p10]
规则/规范
跳转到:规则/规范-
for括号内声明的循环变量(如
for (int i = 1; ...))具有for语句作用域:它是一个新的局部变量,可遮蔽同名外部变量;若需要在循环外继续使用该变量,应在循环外定义
[来源:第4章 p10,Notes] -
最佳实践:使用标准格式,循环控制变量外围无定义;规则放在括号里,要执行的放在循环体里
[来源:第4章 p10,Notes] -
for循环语句很方便用于确定循环次数的循环控制
[来源:第4章 p14]
易错点与辨析
跳转到:易错点与辨析-
⚠️ 变量s必须初始化为0,否则结果不确定
[来源:第4章 p10,Notes] -
⚠️ for循环中的表达式3是在所有循环内语句执行结束之后才执行的,需特别注意执行顺序
[来源:第4章 p18,Notes]
4.3 逗号表达式
跳转到:4.3 逗号表达式定义/语法
跳转到:定义/语法- 逗号表达式格式:
[来源:第4章 p11]表达式1, 表达式2, ..., 表达式n
执行逻辑
跳转到:执行逻辑- 逗号表达式执行过程:
- 逗号运算符起分割作用
- 先执行表达式1,再执行表达式2,...,再执行表达式n(从左到右)
- 整个表达式的计算结果为最后一个表达式的值
[来源:第4章 p11]
代码模式
跳转到:代码模式- 示例:若 a 初值为 0,则表达式
a += 1, a += 2, a += 3, a += 4, a += 5的值为 15,且执行完后 a 的值也变为 15
[来源:第4章 p11]
4.4 while循环
跳转到:4.4 while循环定义/语法
跳转到:定义/语法- while语句格式:
[来源:第4章 p16]while (表达式) 语句// 循环体可以是复合语句或空语句
执行逻辑
跳转到:执行逻辑- while循环执行过程:
- 计算表达式的值(作为循环控制条件)
- 如果为0,循环终止,执行while循环之后的语句
- 如果非0,执行整个循环体
- 重复上述过程
[来源:第4章 p16]
代码模式
跳转到:代码模式- 求e^x的级数展开(当某一项的绝对值小于阈值时结束循环):
[来源:第4章 p17]ex = 0; p = 1; i = 0;while (fabs(p) > 1e-6) {ex += p;++i;p = p * x / i;}
4.5 for与while的相互转换
跳转到:4.5 for与while的相互转换规则/规范
跳转到:规则/规范- for语句改写为while语句的方法:
[来源:第4章 p18]// for形式for(表达式1; 表达式2; 表达式3) 语句// 等价的while形式(若循环体中没有continue;如有continue需确保仍执行“表达式3”)表达式1;while(表达式2) {语句;表达式3;}
代码模式
跳转到:代码模式- 转换示例:
[来源:第4章 p18]// for形式for(double x = a + dlt/2; x < b; x += dlt)integral += (x*x + 5*x + 1) * dlt;// while形式double x = a + dlt/2;while(x < b) {integral += (x*x + 5*x + 1) * dlt;x += dlt;}
4.6 do while循环
跳转到:4.6 do while循环定义/语法
跳转到:定义/语法- do...while语句格式:
[来源:第4章 p20]do 语句 while (表达式);// 循环体可以是复合语句或空语句// 注意末尾有分号
执行逻辑
跳转到:执行逻辑- do...while执行过程:先执行循环体,然后判断循环条件,如条件成立,继续循环,直到条件为假
[来源:第4章 p20]
易错点与辨析
跳转到:易错点与辨析- ⚠️ while与do while的核心区别:
- while:先判断后执行,循环体可能一次都不执行
- do while:先执行后判断,循环体至少执行一次
[来源:第4章 p20]
代码模式
跳转到:代码模式-
输入数据累加直到输入0为止:
total = 0;do {cout << "Input a number:";cin >> value;total += value;} while (value != 0);[来源:第4章 p20]
-
二分法求方程根(x³+2x²+5x-1=0 在[-1,1]区间):
double x, x1 = -1, x2 = 1, fx1, fx;do {fx1 = x1*x1*x1 + 2*x1*x1 + 5*x1 - 1;x = (x1 + x2) / 2;fx = x*x*x + 2*x*x + 5*x - 1;if (fx * fx1 > 0) x1 = x; else x2 = x;} while (fabs(fx) > 1e-7);[来源:第4章 p22]
4.7 死循环与中途退出
跳转到:4.7 死循环与中途退出定义/语法
跳转到:定义/语法-
死循环:循环控制条件永远为真的循环
[来源:第4章 p24] -
构造死循环的方式:
for (;;); // 三个表达式均省略;其中表达式2省略时默认为true(死循环)for (;true;) ... // 表达式2恒为truefor (;1;) ... // 表达式2恒为非0while (true) ... // 条件恒为true[来源:第4章 p24]
规则/规范
跳转到:规则/规范-
运行时跳出死循环:通常可用 Ctrl+C(命令行)或 IDE 的 Stop/Terminate 按钮中断(取决于运行环境)
[来源:第4章 p24] -
死循环设置好退出机制后是有用的(如cin等待输入)
[来源:第4章 p24,Notes]
4.8 break语句
跳转到:4.8 break语句定义/语法
跳转到:定义/语法- break语句:用于跳出一个循环体或switch体
[来源:第4章 p26]
规则/规范
跳转到:规则/规范-
break的适用范围:对于嵌套结构,break只能跳出其所在的底层结构
[来源:第4章 p26] -
break一般与if语句配合使用,if负责检查终止条件,条件满足后break结束循环
[来源:第4章 p25,Notes]
代码模式
跳转到:代码模式- 使用break的死循环模式:
[来源:第4章 p25]while (true) {// 提示用户并读入数据if (value == 标志) break; // break语句跳出循环// 对数据作出处理}
例题结论
跳转到:例题结论- 【执行结果分析】 嵌套结构中switch内的break退出switch,while内的break退出while:
输出结果:for (int i = 0; i < 2; i++) {while(1) {switch(1) {case 1: break; // 退出switchcase 2: cout << "switch" << endl;}cout << "while" << endl;break; // 退出whilecout << "behind while break" << endl; // 不执行}cout << " for loop" << endl;}[来源:第4章 p26]whilefor loopwhilefor loop
易错点与辨析
跳转到:易错点与辨析-
⚠️ 多层嵌套循环要跳出所有循环,需要多个break配合标志变量:
bool flag = false;for (...) {for (...) {for (...) {if (条件) { flag = true; break; }}if (flag) break;}if (flag) break;}[来源:第4章 p37]
-
或者将标志变量放入循环条件:
for (dt = 1; dt <= 4 && !flag; ++dt) {for (hz = 1; hz <= 4 && !flag; ++hz) {...}}[来源:第4章 p38]
4.9 continue语句
跳转到:4.9 continue语句定义/语法
跳转到:定义/语法- continue语句:跳过本轮循环周期中剩余的语句,直接开始下一轮循环
[来源:第4章 p25]
规则/规范
跳转到:规则/规范-
continue与break的区别:break终止循环,continue跳过当前轮
[来源:第4章 p25,Notes] -
在for循环中,continue会跳过之后语句,直接执行表达式3
[来源:第4章 p25]
代码模式
跳转到:代码模式- 求0至x之间偶数的和:
[来源:第4章 p25]int sum, i;for (sum = 0, i = 0; i <= x; i++) {if (i % 2 != 0) continue; // 奇数跳过sum += i;}
4.10 枚举法
跳转到:4.10 枚举法定义/语法
跳转到:定义/语法- 枚举法:对所有可能的情况一一去尝试,直到找到正确的答案。非常适合利用计算机求解
[来源:第4章 p33]
代码模式
跳转到:代码模式-
买水果问题(50元买100个水果:西瓜5元、苹果1元、桔子1元3个。下述代码默认每种水果至少买1个;若允许西瓜为0,则还存在 mellon:0 apple:25 orange:75):
for (mellon = 1; mellon < 10; ++mellon)for (apple = 1; apple < 50 - 5*mellon; ++apple) {orange = 3 * (50 - 5*mellon - apple);if (mellon + apple + orange == 100) {cout << "mellon:" << mellon << ' ';cout << "apple:" << apple << ' ';cout << "orange:" << orange << endl;}}输出结果:
mellon:1 apple:18 orange:81mellon:2 apple:11 orange:87mellon:3 apple:4 orange:93[来源:第4章 p34]
-
罗列2到100的素数(或:输出100以内素数):
for (int i = 2; i <= 100; i++) {bool flag = true;for (int j = 2; j < i; j++) {if (i % j == 0) {flag = false;break;}}if (flag) cout << i << endl;}[来源:第4章 p39]
易错点与辨析
跳转到:易错点与辨析-
【整理自 PPT】枚举法中,可以按一个约束条件列出所有可行情况,然后检查每个可能解是否满足其他约束条件
[来源:第4章 p33] -
【整理自 PPT】四大湖问题中,布尔条件可以参与加法运算:
(a == 1) + (b == 4) + (c == 3)表示满足条件的个数
[来源:第4章 p35]
4.11 贪婪法
跳转到:4.11 贪婪法定义/语法
跳转到:定义/语法- 贪婪法:在求解过程的每一步都选取一个局部最优的策略,把问题规模缩小,最后把每一步的结果合并起来形成一个全局解
[来源:第4章 p41]
代码模式
跳转到:代码模式- 硬币找零问题(1分、2分、5分、1角硬币,找K分零钱):
[来源:第4章 p42]int money = K;int onejiao = 0, fivefen = 0, twofen = 0, onefen = 0;while (money >= 10) { ++onejiao; money -= 10; }while (money >= 5) { ++fivefen; money -= 5; }while (money >= 2) { ++twofen; money -= 2; }while (money >= 1) { ++onefen; money -= 1; }
易错点与辨析
跳转到:易错点与辨析-
⚠️ 贪婪法不一定得到最优解! 如果局部最优无法带来全局最优,就不具备贪心选择的性质
[来源:第4章 p43] -
反例:硬币面值为1分、3分、9分、1角时,找27分:
- 贪婪法:27 = 10 + 10 + 3 + 3 + 1 = 5个硬币
- 最优解:27 = 9 + 9 + 9 = 3个硬币
[来源:第4章 p43]
4.12 本章总结
跳转到:4.12 本章总结判定条件/等价表述
跳转到:判定条件/等价表述-
计算机的强项是不厌其烦地做同样的操作,这是通过循环语句实现的
[来源:第4章 p44] -
三种循环语句:for、while、do while
[来源:第4章 p44] -
枚举法:对某些问题,在寻找解时需要检查所有可能的方案,从中找出可行解
[来源:第4章 p44] -
贪婪法:可用于求问题的最优解,但不一定对所有问题都能得到最优解
[来源:第4章 p44]
4.13 习题与答案
跳转到:4.13 习题与答案例题结论
跳转到:例题结论-
xyz + yzz = 532,x、y、z各代表不同数字,求x、y、z。
答案:xyz = 321(即 x=3, y=2, z=1)
[来源:第4章 p45,Notes] -
输出N行等腰三角形:输入整数N,输出由''组成的等腰三角形,下行比上行多两个'',尖角朝上。
提示:设输入为 N(行数),第 i 行(i 从 0 开始)输出:先输出 (N - i - 1) 个空格,再输出 (2i + 1) 个 '';行尾空格可省略
[来源:第4章 p45,Notes] -
求x的平方根(迭代法):
- (1) Root = x/2
- (2) 检查 root*root 和 x 的差
- (3) 按 root = (root + x/root)/2 更新
- (4) 重复直到误差小于1%
[来源:第4章 p45]
学习目标核对
跳转到:学习目标核对根据PPT第7页的学习目标:
- ✅ for, while, do while:熟练掌握一种循环结构
- ✅ 另外两种:会读即可
- ✅ 会使用 break、continue 编程
[来源:第4章 p7,学习目标]