while循环

作者: qiqi 分类: c++ 发布时间: 2024-07-06 11:36

上一节我们学习了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,并且按照以下的规律进行变换:

(1)如果是个奇数,则下一步变成3N+1。
(2)如果是个偶数,则下一步变成N/2。
不单单是学生,甚至连教师、研究员、教授与学究都纷纷加入。为什么这种游戏的魅力经久不衰?因为人们发现,无论N是怎样一个数字,最终都无法逃脱回到谷底1。准确地说,是无法逃出落入底部的4-2-1循环,永远也逃不出这样的宿命。这就是著名的“冰雹猜想”

现在请你编写一个程序,输入一个正整数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后面的代码,直接进行下一次循环。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

标签云