while循环结构(4.3dowhile循环结构)
上一节讲了while循环结构的格式及编程方法,while循环结构是先判断条件表达式,条件为真则执行循环体,条件为假则退出循环。如果第一次判断条件不成立,循环体一次也不会被执行,所以又称为“当型循环”。本节主要讲另一种循环——do_while循环,又称为“直到型”循环,这种循环会先执行一次循环体,再进行条件判断,当条件为假时结束循环。
do_while循环结构的一般形式为:
do
S
while(表达式);
S称为循环体,可以是空语句、简单语句或复合语句,最后一个分号“;”是语句的结束符号,不能省略。do_while是先执行一次循环体S,再进行表达式计算并判断,如果结果为真,继续重复执行循环体S。执行过程如流程图:
do_while循环流程图
以下形式是合法的do_while形式。
(1)
i=10;
do ; while(--i);
(2)
i=10;
do printf("*"); while(--i);
(3)
i=10;
do{
printf("*");
--i;
}while(i>=0);
(1)的循环体是一条空语句(;),且被执行了10次,但什么也没干,循环结束后i变成了0;(2)和(3)功能是一样的,都是在屏幕上显示10个*号,(3)用复合语句作循环体,(2)用单条语句作循环体,计算--i表达式后再判断结果是否为真,显得要紧凑一些。
与while循环不同,do_while是先执行一次循环体,再进行条件判断,因此这种循环至少会被执行一次。我们可以把前面一些用while实现的程序改写成用do_while实现,如求100的累加和,用while实现时是这样的:
sum=0;i=1;
while(i<=100){
sum=sum i;i ;
}
而改成用do_while实现变成:
sum=0;i=1;
do{
sum=sum i;i ;
}while(i<=100);
两段代码在求100的累加和时写法虽不同,但结果都是一样的,都是在i为101时退出循环。但是在求前n项的累加和时却未必等价,设n由键盘输入,前面两段程序可以写为:
(1)用while实现
sum=0;i=1;
scanf("%d",&n);
while(i<=n){
sum=sum i;i ;
}
(2)用do_while实现
sum=0;i=1;
scanf("%d",&n);
do{
sum=sum i;i ;
}while(i<=n);
两个程序分别执行后,当输入大于0的数时,两个程序的运算结果一样。但是当输入0时,结果还一样吗?代码(1)的sum为0,因为循环体一次也没执行;而代码(2)的结果为1,因为循环体执行了一次,1被加进了sum中。可见前n项累加和的程序,用while和do_while实现存在细微差别,用do_while并不完全正确。
例1:从键盘读入一个整数,统计该数的位数并输出。
如输入495,输出结果为3。如果输入0至9的一个数,则输出结果为1。
我们知道任何一个整数,其绝对值总是可以写为:
n=m*10 r;
其中,r称为n的个位,m是n整除以10后(丢掉个位)的结果。因此一个整数,可以可以拆分为m和r两个部分,m的位数刚好是n丢掉个位的数,r只有一位。如:
495 可拆分为m=49,r=5;
49又可拆分为m=4,r=9;
4又可拆分为 m=0,r=4;
当拆分到m为零时,拆分结束。从上述的分析可知一个具有k位的整数可以被拆分k次,每次从右到左依次把相应位丢掉,至到所有位全部拆分出为止(此时m==0)。由于我们不关心拆出来的位用来干什么,我们直接把整数的后一位丢掉就行,因此,丢掉n的个位的代码为:
m=n/10;
m就是n丢掉了个位后乘余的数,设一个计数变量cnt统计丢掉的位的数,因为每做一次m=n/10就丢掉一个位,因此接着要让cnt加1。循环体变为:
m=n/10;
cnt=cnt 1;
因为还要继续对m进行拆分,所以下一次执行循环时变量n要变为m的值,也就是要把m赋给n,循环体变为:
m=n/10;
cnt=cnt 1;
n=m;
考虑循环体第1行和第3行之间,m没有发生变化,所以两句可以合并为一句,即n=n/10,循环体变为:
n=n/10;
cnt=cnt 1;
由于循环执行的条件是n>0,因此可以用while语句构造循环如下:
while(n>0){
n=n/10;
cnt=cnt 1;
}
当n为大于0的整数时,while循环总能得到正确结果。但是当n=0时,循环体一次也不执行,cnt为0,而正确结果应为1。因此可以用do_while循环解决n为0的问题。用do_while写的代码如下:
do{
n=n/10;
cnt=cnt 1;
}while(n>0);
这样程序就更加完整了,输入任何合法的整数总能得到正确的结果。完整的程序如下:
#include <stdio.h>
int main(void)
{
int cnt=0;
int n;
printf("Enter a integer:");
scanf("%d",&n);
if(n<0) n=-n;
do{
n=n/10;
cnt=cnt 1;
}while(n>0);
printf("it contains %d digits!\n",cnt);
return 0;
}
程序中考虑了n为负整数的情况,当n为负整数时先要变成其相反数。思考一下,如果要用while循环,如何修正刚才的n为0时的错误!
例2:用do_while语句根据格雷戈里公式计算π值,要求最后一项精度小于10^-4。
由于结束循环使用item的绝对值小于10^-4,因此程序与while版本的功能一样,只是循环构造略有不同。
#include<stdio.h>
#include<math.h>
int main( )
{
int flag,d;
double item,sum,pi;
item=1;
d=1;
flag=1;
do{
sum=sum item;
d=d 2;
flag=-flag;
item=flag*1.0/d;
}while(fabs(item)>=1e-4);
pi=4*sum;
printf("pi=%f\n",pi);
}
大部分情况下,用do_while可以完成的循环,稍作补充和修改也可以用while完成,针对do_while至少执行一次循环体的特例在while中要作特殊处理。如在例1中,如果要想用while代替do_while,要对n=0的情况进行特殊处理。
本节主要介绍了do_while循环的格式和执行过程,比较了while与do_while语句构造循环异同,介绍了两种循环结构的相互替代方法。本节就讲到这里,下节再见。
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com