引子
什么?万年丕更的作者更新了?
没错!而且我们不当标题党,我决定把《我的世界》串进文章里。
什么?你不玩《我的世界》?
木有关系 本专栏文章主要在讲c++语言的语法点和知识,保证让不玩《我的世界》的人也能听懂!
木哈哈哈哈,又水了四行
目录
引子
目录
1.while循环 加入了群聊
1.1 break语句和continue语句
1.2 死循环
2.要致富,先撸树
2.1 剩余的饥饿值(for循环)
T2.1解题思路
T2.1参考答案
2.2 原木放哪里?(while循环)
T2.2解题思路
T2.2参考答案
尾声
1.while循环 加入了群聊
前面几期的循环章节我们讲了for循环,相信你在今后的学习中能熟练运用它。
还记得上次我们用scratch里的循环来讲解for循环码?
图1.scratch里的循环结构
今天我们要学习一种新的循环结构,大家请看第三个(上往下)scratch积木块,你可以把今天这个循环理解成条件循环。字面意思,重复执行直到<条件>为真,也就是当条件成立的时候才跳出循环,和for循环还是有一点点相似的o。
好吧,不卖关子了。今天我们将迎来一位新同学——while循环
首先我们来了解一下while的组成:
//#1:内部只有一个语句
while (条件表达式) 语句;while (条件表达式)语句;//#2:内部有多个语句
while (条件表达式)
{语句1;语句2;......语句n;
} //大括号的作用先前已讲过,这里就不重复了
while循环的一般执行顺序是:
- 判断<条件表达式>是否成立,成立跳到2.,否则跳出循环
- 按照先后顺序执行内部语句块(有时会有些特殊情况,具体下面会讲)
- 跳回1.
注意:在以后的算法学习中,你可能会看到这样式的while:
TYPE a;
while (cin >> a){语句1;语句2;......语句n;
}
不用太吃惊啦,这只是:
C++ 语言中用于读取输入数据直到遇到文件结束符(EOF)或输入错误为止的一种方式。
在这个语句中,cin 是 C++ 标准库中的输入流对象,用于从标准输入(通常是键盘)读取数据。
a
是需要读取的数据的变量名。这个循环会一直执行,直到遇到以下情况之一:
- 读取到文件结束符(EOF)。这意味着输入已经结束,没有更多的数据可供读取。
- 读取过程中发生错误。例如,如果输入的数据类型与期望的类型不匹配,或者输入的数据本身不合法,那么
cin
对象会设置错误标志,循环将终止。
(以上来自百度 文心一言)
前面讲到while循环在执行内部语句的时候可能会遇到特殊情况,那么到底是什么特殊情况呢?
1.1 break语句和continue语句
让我们设想一种情境,你在循环的过程中,已经求得了问题的解,这时候再循环下去就没有意义了。所以这个时候我们就要跳出循环。那么在c++语言里,我们如何才能跳出循环呢?这就要借用两个语句的力量——
我知道标题上写了!再写一遍也不是不可以!
break语句、continue语句!
什么是break呢?你可以把它当作跳出循环的工具。break的作用就是跳出这一层循环(或switch)然后继续执行循环(或switch)后面的语句。注意,break跳出的是这一层循环!
#include <iostream>
using namespace std;
int main(){for (int i = 0;i < 10;i ++){if (i == 5) break; //当i等于5时,跳出循环cout << i << endl;}//该程序只能输出数字0~4return 0;
}
什么又是continue呢?你可以把它理解成一个快进按钮。continue可以马上结束这一次循环,直接进入下一次循环。注意:continue是结束这一次循环!
#include <iostream>
using namespace std;
int main(){for (int i = 0;i < 10;i ++){if (i == 5) continue; //当i等于5时,直接进入下一次循环cout << i << endl;}//该程序只能输出数字0~4和数字6~9return 0;
}
1.2 死循环
上期我们在讲for的时候就已经讲过死循环了。
有一种循环结构则不需要跳出循环,即死循环。因此,死循环中条件表达式的值恒为1。
for循环也可以用于死循环,如下:
for (;;)
{
//语句
}
言简意赅的说,就是:木有变量!木有条件!木有更改!只要一直循环下去就可以了!
这期我们来深刻的剖析一下死循环和可能的避免方法。
死循环(endless loop)是编程中的一个概念,指的是无法靠自身的控制终止的循环。简单来说,就是在某一时刻,当程序遇到循环判断语句使条件一直成立时,导致此时该程序始终在执行,跳不出循环,程序不能自己正常结束。具体的例子有:
//for死循环实例
for (;;){cout << a;
}//while死循环实例
while (1){cout << a;
}while (true){cout << a;
}
提示:上面的代码在运行过程中若被强制停止,可能对你的宝贝电脑会有损伤!
是不是听起来很危险?
死循环通常是由于程序员疏忽或者错误导致的,例如忘记设置循环终止条件、判断条件错误等。死循环会导致程序无法继续执行其他任务,甚至使系统资源被耗尽,程序崩溃。
为了避免死循环,程序员应该在编写循环语句时确保有一个合适的退出条件,或者在循环体中加入一些判断条件来确保循环会在某个时刻终止。同时,也可以使用一些调试工具来跟踪程序的执行过程,找到导致死循环的原因并修复它。
没错,我们应该在编写程序的时候尽量避免死循环。 这时就要用到上面说到的两个特殊语句中的break了。我们可以设置当程序达到某一个特定条件时跳出循环。如下:
#include <iostream>
using namespace std;
int main(){int a;while (1){cout << a << endl;if (a == 5) break; //a等于5时跳出循环}return 0;
}
好了,至此,相信你已经可以很好的掌握while语句了
2.要致富,先撸树
俗话说,要致富,先撸树。史蒂夫深谙此道理,但看看自己的仓库中木头存量寥寥无几,于是决定出发去收集一些木头来塞满自己的箱子。
乱砍滥伐是违法行为,小朋友们千万不要模仿哦!
2.1 剩余的饥饿值(for循环)
史蒂夫出发后才发现忘了带食物,此时他还有hunger点饥饿值(即满饥饿值),他不知道砍完所有木头后自己的饥饿值还剩多少(允许负数的情况),已知砍1棵树需要消耗2饥饿值,请你编写程序帮他计算。
输入:
第一行 输入三个整数m、n、hunger,其中m*n是合法砍树区域(即可以砍树的地方),hunger是初始饥饿值
下面m行每行输入n个数(0或1),1代表有树,0代表空地
输出:
处理过后的hunger,剩余饥饿值
输入样例:
4 5 20
0 0 1 0 1
1 0 0 0 0
0 1 1 0 1
0 0 0 0 1
输出样例:
6
提示:请先自行思考,再看答案o
T2.1解题思路
思考1:如何保存树木生长情况以及判断一个位置上长有树而非空地?
分析输入的数据,我们会发现输入的数据只有0、1两种,因此我们完全可以可以使用二维布尔型(或整型,效果同)数组来保存树木生长情况。在判断的时候,由于数据只可能是0或1,我们可以直接对这个位置判断。
思考2:怎么才能遍历到所有位置?
使用一个双重循环,第一重循环遍历每一行,第二重遍历每一列即可。或者使用滚动数组的方法(留给有能力的同学,这里就不写了)
T2.1参考答案
解法1:
#include <iostream>
using namespace std;
int m,n,hunger;
int main(){cin >> m >> n >> hunger;int tree[m][n];for (int i = 0;i < m;i ++)for (int j = 0;j < n;j ++){cin >> tree[i][j];if (tree[i][j]) hunger -= 2;}cout << hunger;return 0;
}
解法2(三目运算符):
#include <iostream>
using namespace std;
int m,n,hunger;
int main(){cin >> m >> n >> hunger;int tree[m][n];for (int i = 0;i < m;i ++)for (int j = 0;j < n;j ++){cin >> tree[i][j];hunger -= tree[i][j] ? 2 : 0;}cout << hunger;return 0;
}
2.2 原木放哪里?(while循环)
史蒂夫的背包快要装满啦!他又砍了一组原木,请你编写一程序,找到这组原木从左到右数第一个可以放置的位置并返回其下标,背包满了则输出"The bag is full!"。(背包是一维的)
输入:
第一行 一个整数n,史蒂夫背包的大小(长度)
第二行 n个数字(0或1),1代表有东西占位(1组原木或其他东西,反正史蒂夫刚刚砍的那一组原木肯定不能放在这了),0则相反
输出:
一个整数,目标位置的下标
输入样例:
9
1 1 1 1 1 0 1 1 0
输出样例:
5
T2.2解题思路
思考1:如何返回下标?
可以设立一个变量i,循环改变i的值,若数组里下表为i的元素合法时,返回i就可以了。这类似于指针,以后我们讲指针的时候会用到类似的思想
思考2:如何改变i的值?
对数组中下表为i的元素进行判断(由于这个元素只存在0、1两种情况,我们可以沿用T2.1的判断方法),若等于1,则代表不能放在这里,i ++。重复直到元素为0时停止
T2.2参考答案
解法1(for循环解法):
#include <iostream>
using namespace std;
int n;
bool isFull = 1; //用于检测背包是否装满
int main(){cin >> n;int bag[n];for (int i = 0;i < n;i ++){cin >> bag[i];}//以下for循环for (int i = 0;i < n;i ++){if (!bag[i]){ //检测到空位cout << i;isFull = 0; //有空位,说明背包未满break;}}if (isFull) cout << "The bag was full!";return 0;
}
解法2(while循环解法)(输入部分都一样):
#include <iostream>
using namespace std;
int n,i;
bool isFull = 1; //用于检测背包是否装满
int main(){cin >> n;int bag[n];for (int a = 0;a < n;a ++){cin >> bag[a];}//以下while循环while (bag[i] && i <= n - 1)i ++; //无空位且位置合法,移动下标isFull = i <= n - 1 ? 0 : 1; //若i“溢出”则背包满if (isFull) cout << "The bag was full!";else cout << i;return 0;
}
尾声
没有尾声
史蒂夫今天收获颇丰,因为他挖到了一大盒木头;
我们今天也收获颇丰,因为认识了一个新的循环——while。相信你在今后的学习之路上一定能熟练地掌握并运用它!