Appearance
L1-14 while循环
while循环语句
格式
c++
while(表达式)
{
循环体
}
以上为 while 循环的一般格式。再来看一个实际的例子:
c++
int i = 0;
while(i < 10)
{
cout << "Hello world" << endl;
i++;
}
执行这段程序,同之前的 for 程序相同,会输出 10 行 Hello world 。
这段 while 程序与上面的 for 程序,有着完全相同的执行流程。
i<10
为循环表达式。
cout<<"Hello world"<<endl
为循环体。
循环条件表达式
while 循环中的“表达式”就是循环条件,注意:这个表达式不可为空,当表达式为非 0 值或永真式时, while 循环陷入死循环。
循环体
循环体一般在 while 后用花括号括起来。可以是语句,代码段,或者新的循环。可以为空语句,可以是一个简单表达式。当循环体为一个表达式或者空语句时,可以省略花括号。
循环流程
while 循环的流程图如下:
单选题
for循环和while循环都是先判断表达式,后执行循环体
A. 错误
B. 正确
题解
B
for循环和while循环都是先判断表达式,后执行循环体
单选题
下面两个 while 循环,输入同样的 n(大于 0),哪一个执行的次数更多?
程序1
c++
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
while (n > 0)
n--;
return 0;
}
程序2
c++
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
while (n)
n--;
return 0;
}
A. 程序1更多
B. 程序2更多
C. 一样多
题解
C
while(n) 是判断 n 不等于 0。当 n 是正整数时,和 while(n>0) 的功能相同。
while循环实例
我们先来用 while 循环,实现一个 1−100 的累加:
c++
#include<bits/stdc++.h>
using namespace std;
int main() {
int i = 1, sum = 0;
while(i <= 100)
{
sum += i;
i++;
cout << sum << endl;
}
}
以上这段代码将会输出:
text
1
3
6
10
....
4950
5050
除了处理一些基础的运算,循环结构还可以用来帮我们处理更多的输入。
c++
#include<bits/stdc++.h>
using namespace std;
int main() {
int i = 0, sum = 0, value;
while(i < 5)
{
cin >> value;
sum += value;
i++;
}
cout << sum << endl;
}
这段程序将对我们输入的 5 个数进行求和。如果输入: 1 8 6 4 7 ,将会输出 26 。
如果我们希望程序不只能处理 5 个数,而是按照我们输入的一个数字 k ,然后对后面 k 个数进行求和,那么程序可以这样写:
c++
#include<bits/stdc++.h>
using namespace std;
int main() {
int i = 0, sum = 0, value, k;
cin >> k;
while(i < k)
{
cin >> value;
sum += value;
i++;
}
cout << sum << endl;
}
我们还可以配合之前学过的 if ,来处理更多的计算。下面这段程序,将会要求用户先输入一个数 k ,然后再输入 k 个数,程序会对所有输入的数字中, 5 的倍数进行求和。
c++
#include<bits/stdc++.h>
using namespace std;
int main() {
int i = 0, sum = 0, value, k;
cin >> k;
while(i < k)
{
cin >> value;
if(value % 5 == 0)
sum += value;
i++;
}
cout << sum << endl;
}
do...while循环语句
格式
c++
do{
循环体
}while(表达式);
以上为 do...while 循环的一般格式。再来看一个实际的例子:
c++
int i = 0;
do{
cout << "Hello!" << endl;
i++;
}while(i < 10);
循环表达式
do...while 循环中的“表达式”就是循环条件,注意:这个表达式不可为空,当表达式为非0值或永真式时, do...while 循环陷入死循环,需要在循环体内部用 break 语句跳出(也可用 goto 语句跳到程序体中,但是不推荐) 。当它为 0 值或永假式时,循环不运行。
循环体
与 while 语句中的循环体相同,但是需要注意的是: do … while 语句中是先无条件执行一遍循环体, 再进入循环表达式的判断, 直到表达式为 0 退出循环。 而 while 语句每次执行循环体内容都需要先进行一次循环表达式的判断。
循环流程
do … while 循环的流程图如右图所示
do … while 循环在实际应用中,并不是很常见,大家更习惯于用 for 和 while 来解决问题,因此在这里不做更多实例分析。
单选题
while 循环是(),do−while 循环是()
- 先判断条件,再执行循环体
- 先执行循环体,再判断条件
A. 1 1
B. 1 2
C. 2 1
D. 2 2
题解
B
while 循环:先判断条件,再执行循环体 do−while 循环:先执行循环体,再判断条件
单选题
执行下面的程序,会输出()?
text
#include <bits/stdc++.h>
using namespace std;
int main() {
int n = 123456;
while(n) {
cout << n % 10;
n /= 10;
}
return 0;
}
A. 123456
B. 654321
C. 12345
D. 65432
题解
B
1、从程序可知,这个题目的循环部分是取余除10,依次从最低位输出,输出123456输出654321
循环结构对比
while 循环与 for 循环可以相互替代,一般来说, while 语句和 do … while 语句适合事先不知道循环次数的循环, for 循环适合已知循环次数的循环。
结构上看, while 语句和 for 语句的循环体都需要判断后执行,而 do...while 语句第一次循环体执行的循环却不需要判断。因此,循环体至少执行一次适合使用 do...while 语句。
本质上来说,三种循环可以互相转换,没有本质上的区别,因此使用上可以凭借自己喜好,代码简洁,清晰一目了然即可。
习题
课堂练习:启蒙练习-2的幂整除
给一个正整数n,计算它最多能被2的多少次幂整除
输入格式
输入一个数n
输出格式
输出一个数
输入样例
text
896
输出样例
text
7
c++
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, cnt = 0;
cin >> n;
while(n) {
if (n % 2 == 0) {
cnt++;
n /= 2;
} else {
break;
}
}
cout << cnt << endl;
return 0;
}
题解 1
一个数能够被 2 整除,那么它就是偶数。
能被 4 ( 2 的平方) 整除,那么它除以二以后还是个偶数
………
依此类推,当一个数一直除以二直到他变成奇数,它除以二的次数就是所求的答案。
如果要计算一个数能被 3 的多少次幂整除,代码要怎么修改?
课后作业:角谷猜想
角谷猜想的内容是:“对任意的正整数n,若为偶数,则把它除以2;若为奇数,则把它乘以3加1 。经过如此有限次运算后,总可以得到正整数值1 。“ 请你编一个程序,根据输入的正整数n,输出每一步运算结果。
输入格式
输入一个正整数n。
输出格式
输出若干行,每行一个算式表示计算过程。
输入样例
text
3
输出样例
text
10
5
16
8
4
2
1
数据范围
对于20%的数据,2≤n≤10; 对于100%的数据,2≤n≤100;
c++
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
while(n != 1) {
if (n % 2 == 0) {
n /= 2;
cout << n << endl;
} else {
n = n * 3 + 1;
cout << n << endl;
}
}
return 0;
}
题解 1
由于不清楚循环的次数,所以想到用 while 循环来解决问题,按照题目的要求,如果是偶数则 n−>n/2 ,如果是奇数则 n=3n+1 ,直到 n 的值变为 1 为止。
进阶习题:空瓶换饮料
某饮料公司最近推出了一个“空瓶换饮料”的活动:如果你拥有3个空瓶就可以兑换一瓶饮料,初始你有 n 瓶饮料,喝完后的空瓶可以继续用来兑换饮料。问总共可以喝到多少瓶饮料。
输入格式
一行,1个整数n,表示初始饮料的数量(1 <= n <= 10^9)。
输出格式
一行,对应答案
输入样例
text
10
输出样例
text
14
c++
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, cnt = 0;
cin >> n;
int a = n;
while(n > 2) {
cnt += n / 3;
n = n / 3 + n % 3;
}
cout << a + cnt << endl;
return 0;
}
- 题解 1
用 while 循环模拟兑换过程,同时用个变量 sum 做喝过饮料的计数,用一个 t 做剩余瓶盖的计数。
初始 sum=n ,表示喝了最初的 n 瓶。
之后 t=n%3 ,即当前 n 个瓶盖经过兑换,剩余的瓶盖。
n=n/3 ,即当前 n 个瓶盖可以兑换多少瓶饮料。
再下一轮兑换时,先进行计数,即 sum=sum+n ,再把剩余的 t 个瓶盖,加到 n 当中,模拟兑换过程。
直到 n 等于 0 为止。
头脑风暴
过桥问题
在漆黑的夜里,四位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,四个人一共只带了一只手电筒,而桥窄得只够让两个人同时通过。如果各自单独过桥的话,四人所需要的时间分别是 1,2,5,8 分钟;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。问题是,你如何设计一个方案,让用的时间最少。
如果四个人的时间是 1,8,9,10 的话呢?
如果是 N 个人的话呢?
设这四个人叫做 A,B,C,D,他们所需要的时间分别是 1,2,5,8 分钟。
第一步: A 和 B 过桥,花费 2 分钟。
第二步: A 回来,花费 1 分钟。
第三步: C 和 D 过桥,花费 8 分钟。
第四步: B 回来,花费 2 分钟。
第五步: A 和 B 过桥,花费 2 分钟。
这样只要花费 2+1+8+2+2=15 分钟
下面再来考虑 A,B,C,D 四个人所需要的时间分别是 1,8,9,10 分钟。
第一步: A 和 B 过桥,花费 8 分钟。
第二步: A 回来,花费 1 分钟。
第三步: A 和 C 过桥,花费 9 分钟。
第四步: A 回来,花费 1 分钟。
第五步: A 和 D 过桥,花费 10 分钟。
总共花费: 29 分钟。如果仍按照上面的方法来做,需要花费: 8+1+10+8+8=35 分钟。