while循环
上一节我们学习了for循环,for循环适合于已知循环次数或需要简单计数的情况。比如输出1-10。开始、结束还有步长非常的明确。但有些时候,我们不清楚循环的具体次数,或者需要我们求循环的具体次数,那么用for循环就不太适合了。这里我们介绍另外 一种循环的语法结构——while循环。
在C++中,while循环的基本结构是这样的:
while (条件)
{
// 要重复执行的代码
}
只要括号中条件为真,循环体就会一直重复执行下去。
例1 输出所有大于零小于n的数。
int n;
cin>>n;
while(n>0)
{
cout<<n<<endl;
n–;
}
上面代码中n–这行非常重要,不仅仅是为了依次输出所有整数,还是为了保证循环能正常结束。试想如果n的值不变化,或者越变越大,那么n>0的条件就会永远成立,循环将永远重复执行下去。这种永远无法结束的循环被称为死循环。死循环通常是由于编程错误引起的,例如:
(1)循环条件永远为真。
(2)循环体内的逻辑错误导致无法达到退出条件。
死循环会导致程序无法继续执行后续代码,严重时甚至会使系统资源耗尽,导致系统崩溃。正因如此,有些病毒程序就是利用死循环来实现其恶意目的,如消耗系统资源、持续感染或干扰正常操作。
我们来看下面的例题。
例题2 小球从h米高处自由落下,着地后又弹回高度的一半再落下。经过多少次落地后,小球弹起的高度才会低于0.5米?
参考代码:
int cnt = 0 ;//记录落地次数
double h; //小球高度
cin>>h;
while(h>0.5)
{
h /= 2;
cnt++;
}
cout<<cnt<<endl;
例题3 一只蜗牛从一口枯井的底部向井口爬,它白天往上爬3米,夜晚往下滑2米。已知井深h米,问这只蜗牛至少需要几天爬到井口?

参考代码:
int days = 0 ;//记录天数
int h,distance = 0; //井的深度 蜗牛爬的距离
cin>>h;
while(distance<h)//爬的高度低于井深就继续
{
days++;
distance += 3; // 白天爬3米
if (distance >= h)
{
break; // 如果白天爬完后已经到达或超过井口,则跳出循环
}
distance -= 2; // 夜晚滑2米
}
cout<<days<<endl;
这段代码出现了一个break关键字,后面会详细讲解。这里只要知道他的作用是跳出循环的即可。
看到这里有些数学好的同学可能会说,这个问题也不需要循环呀,只要用7减去3的差除以3减去2的差的商再加1就行了啊。算式为:
(h-3)/(3-2) +1
是的,这么做是更简洁更优秀的做法。但是对数学的要求更高。所以学习C++语言和数学是相辅相成的关系。
以下是从数学角度的详细推理过程:
(1)理解问题:
-
- 蜗牛白天爬3米,夜晚滑2米,因此每天净爬升1米。
- 如果井深为 米,我们需要计算蜗牛爬到井口所需的最少天数。
(2)特殊情况:如果井深 米,蜗牛一天就能爬到井口,因为它白天就能爬出去。
(3)一般情况:
- 对于 米的情况,蜗牛每天净爬升1米。
- 在最后一天,蜗牛白天爬3米,如果这3米足以让它到达或超过井口,它就不再下滑。
- 因此,我们需要计算在最后一天之前,蜗牛需要爬多少天,然后在最后一天它直接爬到井口。
(4)计算公式:
- 在最后一天之前,蜗牛需要爬 米(因为最后一天它直接爬3米)。
- 每天净爬升1米,所以需要 天。
- 加上最后一天,总共需要 天。
int h,days;
cin >> h;
if (h <= 3)
{
days = 1; // 如果井深小于等于3米,蜗牛一天就能爬出去
}
else
{
days = (h – 3) + 1; // 计算总天数
}
cout << days << endl;
例4 冰雹猜想 上个世纪70年代中期,美国各所名牌大学校园内,人们都像发疯一般,夜以继日,废寝忘食地玩弄一种数学游戏。这个游戏十分简单:任意写出一个正整数N,并且按照以下的规律进行变换:
现在请你编写一个程序,输入一个正整数n,然后根据冰雹猜想的规则输出每一步变换的过程。
参考代码:
int n;
cin>>n;
cout<<n;
while(n!=1)
{
if(n%2==1)
n = n * 3 +1;//奇数乘3加1
else
n = n / 2;//偶数除以2
cout<<“–>”<<n;
}
cout<<endl;
例5 输入一个整数n,计算n是几位数。
int n,cnt=0;
cin>>n;
while(n)
{
cnt++;
n /= 10;
}
cout<<cnt<<endl;
例6 等待输入值。输入两个整数,回车后输出结果,然后再输入一对,回车再输出结果…直到输入第一个数为零。因为不知道用户什么时候会输入0,所以你不能预先设定循环次数。
参考代码:
int a,b;
while(cin>>a>>b)
{
if(a==0)break;
cout<<a+b<<endl;
}
初学者可以使用这段代码,尽量不要在循环中使用cin或者cout,因为这两个实例的效率非常低,如果在循环中使用容易造成时间超限。取而代之的是使用scanf()函数和printf()函数。后面我们会详细介绍这两个函数,这里记住与循环结构的特殊用法即可。
如果输入终止的条件是输入数据的个数。比如每次循环都输入两个数,如果只输出一个数就代表结束输入。那怎么处理呢?请参考下面的代码:
int a,b;
while(scanf(“%d%d”,&a,&b)==2)
{
cout<<a+b<<endl;
}
如果输入的终止条件都没有那该怎么办呢?
int a,b;
while(scanf(“%d%d”,&a,&b)!=EOF)
{
cout<<a+b<<endl;
}
这段代码表示只要还有数据就继续循环。这几种输入数据的方式非常的重要,在竞赛中会经常遇到!
在C++中还有一个do…while循环结构,它与 while 循环和 for 循环类似,但有一个关键的区别:无论条件是否为真,do…while 循环至少会执行一次循环体。语法如下:
do {
// 循环体
} while (条件);
do…while 首先执行循环体内的代码,执行完循环体后,检查条件表达式。如果条件为真(true),则再次执行循环体;如果条件为假(false),则退出循环。
让我们通过一个简单的场景来理解为什么需要 do…while 循环。比如我们设计一个密码锁,要求用户输入密码,需要用户先输入密码然后判断密码是否正确,正确就退出循环往下执行,错误则重新输入密码。这种情况下,输入并判断密码是否正确的工作至少要执行一次,因此用do…while循环结构要比其他结构更适合。下面举个简单的例子,让我直观感受下do…while的用法:
int number;
do {
cout << “请输入一个正整数: “;
cin >> number;
if(number%2==0)
cout<<“Yes”;
else
cout<<“No”;
cout<<endl;
} while (number <= 0);
循环控制语句
在C++中有两个非常重要的控制语句,用于控制循环的执行流程。分别是break语句和continue语句。
break语句用于立即终止当前循环,并跳出循环体。一旦程序执行到break,循环就会完全停止,不再进行任何后续的迭代。它还可以终止switch语句中的一个case。
continue语句用于跳过当前循环的剩余语句,并立即开始下一次循环的迭代。换句话说,当程序执行到continue时,它会忽略循环体内continue后面的代码,直接进行下一次循环。
