📄 第10章 循环语句.htm
字号:
<P>do
<P>{
<P> 需要循环执行的语句;
<P>}
<P>while(条件);
<P>
<P>和
while循环最明显的区别,就是do...while循环中,判断是否继续循环的条件,放在后面。也就是说,就算是条件一开始就不成立,循环也要被执行一次。请比较以下两段代码,前者使用while循环,后者使用do...while循环。
<P>
<P>代码段一:
<P>int a = 0;
<P>while( a > 0 )
<P>{
<P> a--;
<P>}
<P>
<P>变量a初始值为 0,条件 a > 0 显然不成立。所以循环体内的 a--;语句未被执行。
<P>本段代码执行后,变量a值仍为0;
<P>
<P>代码段二:
<P>int a = 0;
<P>do
<P>{
<P> a--;
<P>}
<P>while( a > 0 );
<P>
<P>尽管循环执行前,条件 a > 0 一样不成立,但由于程序在运行到
do...时,并不先判断条件,而是直接先运行一遍循环体内的语句:a--。于是a的值成为 -1,然后,程序才判断 a > 0
,发现条件不成立,循环结束。
<P>
<P>do..while中的条件和while循环中的条件一样是:“允许继续循环的条件”,而不是“结束循环的条件”,这和Pascal语言中的do...until正好相反,学习过Pascal(Delphi)的学员可得注意。
<P>
<P>以笔者的经验,do..while循环用得并不多,大多数的循环用while...来实现会更直观。下面我们仅简单地将1到100的连加程序转换为用do...while实现:
<P>
<P>int sum =0;
<P>int i=1;
<P>
<P>do
<P>{
<P> sum += i;
<P> i++;
<P>}
<P>while(i<=100);
<P>
<P><B>例三:用 do...while实现可以多次统计的程序。</B>
<P>
<P>在例二中,我们做了一个统计程序。假如一个学生有三门成绩,如语文,数学,英语要统计总分,例二的程序可以方便地使用,但如果要连续统计一个班级每个学生的这三门成绩,我们就得不断地运行例二的成绩,这显然不方便。
<P>一个同学的三门成绩需要一层循环,要不断统计多个同学各自的成绩,就需要再套上一层循环。请看下面例子中,如何在原来的
while...循环上再加一层do...while循环。
<P>程序的思路是:统计完一遍后,就问一句是否要继续统计新同学的成绩,如果用户输入字母Y或y,表示需要统计一下位,否则,程序结束循环。
<P>这个程序是在例二的基础上进行功能改进,以下粗体部分为新加的代码。
<P>
<P>//---------------------------------------------------------------------------
<P>#include <iostream.h>
<P>#pragma hdrstop
<P>//---------------------------------------------------------------------------
<P>#pragma argsused
<P>int main(int argc, char* argv[])
<P>{
<P> float sum,score;
<P> int num; //num 用于存储有几个成绩需要统计。
<P> int i; //i 用于计数
<P>
<P><B> char c; //用来接收用户输入的字母</B>
<P>
<P><B> do</B>
<P><B> {</B>
<P><B> </B>//初始化:
<P> sum = 0;
<P> i = 1;
<P>
<P> cout << "====成绩统计程序====" <<
endl;<BR>
<P> //用户需事先输入成绩总数:
<P> cout << "请输入待统计的成绩个数:";
<P> cin >> num;
<P> cout << "总共需要输入"<< num
<< "个成绩(每个成绩后请加回车键):" << endl;
<P>
<P> while ( i <= num)
<P> {
<P> cout << "请输入第"
<< i << "个成绩:";
<P> cin >>
score;<BR>
sum +=
score;<BR>
i++;<BR>
}<BR><BR>
//输出统计结果:<BR> cout
<< "参加统计的成绩数目:" << num << endl;<BR>
cout << "总分为:" << sum <<
endl;
<P>
<P><B> //提问是否继续统计:</B>
<P><B> cout <<"是否开始新的统计?(Y/N)?";</B>
<P><B> cin >> c;</B>
<P><B> }</B>
<P><B> while( c == 'y' || c == 'Y');</B>
<P>}
<P>//---------------------------------------------------------------------------<BR>
<P>程序完成一次统计以后,会提问“是否开始新的统计”,用户输入一个字母,存到变量
c,然后程序在do...while的条件里检查c是否等于‘Y’或‘y’。如果不等于,就结束循环。
<P>由于程序在统计之后有一个提问的时间,所以,原来的getchar()就不再需要了。
<P>在这个例子,外层循环使用do...while是最好的选择,因为,用户运行本程序,多数情况下,他至少想统计一次。
<P>
<P>最后我们来看do...while循环的流程图,请和while的流程图对比。
<P>
<P><IMG height=284 src="第10章 循环语句.files/ls10.h5.gif" width=276 border=0>
<P>
<H3><A name=10.3>10.3</A> for 循环</H3>
<P>for
循环里在C,C++里用得最多,也是最灵活的循环语句。要学好它,需要从已经学过的while循环的身上,“挖掘”出有关循环流程的要素,这些要素隐藏在while,或do...while的背后,但它将直接体现在for循环的结构上。
<H4><A name=10.3.1>10.3.1</A> 循环条件三要素</H4>
<P>
<P>学习了两种循环,我们来挖掘一下循环流程中的“条件三要素”。
<P>
<P><B>第一、条件一般需要进行一定的初始化操作。</B>
<P>
<P>请看我们用while循环实现1到100累加的代码:
<P>
<P><I>int sum = 0; //变量sum将用于存储累加和,将它初始化为0,这很重要。</I>
<P><I>int i = 1; //i是每次要加的数,它从1开始。</I>
<P>
<P><I>while ( i<= 100)</I>
<P><I>{</I>
<P><I> sum += i;</I>
<P><I> i++;</I>
<P><I>}</I>
<P>
<P>这段代码中,循环的条件是 i <= 100;因此,一开始,i肯定需要一个确定的值。前面的:
<P>int i = 0;这一行代码,在声明变量i的同时,也为i赋了初始值:1。这样,条件 i <= 100 得以成立(因为i为1,所以 i
<= 100 当然成立)。
<P>
<P><B>第二、循环需要有结束的机会。</B>
<P>
<P>程序中最忌“死循环”。所谓的“死循环”就是指该循环条件永远为真,并且,没有另外的跳出循环的机会(后面将学到)。比如:
<P>
<P>//一段死循环的例子:
<P>while ( 2 > 1 )
<P>{
<P> cout << "死循环" <<endl;
<P>}
<P>
<P>执行这段代码,你会发现程序停不下来了。原因就是它的循环条件 2 > 1
永远为true。所以,一个最后可以变成不成立条件在大多数情况下是必需的。比如在while的那个例子:
<P><I>while ( i<= 100)</I>
<P>条件 i <= 100 ,由于 i 在循环中被改变,所以它至少在理论上有可能造成 i <= 100 不成立。
<P>
<P><B>第三、在循环中改变循环条件的成立因素</B>
<P>
<P>这一条和第二条互相配套。
<P>比如这段代码:
<P><I>int i=1;</I>
<P><I>while ( i<= 100)</I>
<P><I>{</I>
<P><I> sum += i;</I>
<P><I>}</I>
<P>同样是一段可怕的“死循环”。因为i没有被改变的机会,其值永远为1,从而循环条件
i<=100也就永远为真。所以在循环中最后一句(下面加粗部分),不可遗忘。
<P><I>while ( i<= 100)</I>
<P><I>{</I>
<P><I> sum += i;</I>
<P><I><B> i++;</B></I>
<P><I>}</I>
<P>当然,在这段程序里,i++除了起改变条件成立因素以外,同时也起上sum不断加递增的数,从而实现得到累加和。
<P>
<P>说完这一些,我们来看C,C++中最灵活循环结构:for循环。
<P>
<H4><A name=10.3.2>10.3.2</A> 三要素在for循环结构上体现</H4>
<P>
<P>for 循环的语法:
<P>
<P>for(条件初始化;条件;条件改变)
<P>{
<P> 需要循环执行的语句;
<P>}
<P>
<P>可见,for的结构中,不仅提供了的“条件”的位置,同时也提供了条件初始化,和条件改变的位置。这三者虽然在同一行上,但并不是依次连接地执行。
<P>
<P>条件初始化的表达式首先被执行(并且只被执行一次);
<P>然后程序检查条件是否成立,如果成立就执行循环体中的语句,否则直接结束循环。
<P>执行完一遍循环以后,程序执行“条件改变”语句。
<P>
<P>1到100整数累加的程序,改为for循环写,是最合适的了:
<P>
<P>int sum = 0;
<P>int i;
<P>
<P>for( i=1; i <= 100;i++)
<P>{
<P> sum += i;
<P>}
<P>
<P>程序先执行条件初始化语句:i=1;
<P>然后立即判断条件 i <= 100 吗?显示,此时该条件成立;
<P>于是程序执行循环体内的语句,此时只有一句: sum += i;
<P>然后,执行改变条件因子的语句: i++; 此时,i值变为 2;
<P>程序再次判断条件 i <= 100 ?,依然成立,于是开始第二遍循环……
<P>
<P>变量 i 可以初始化条件时才临时声明:
<P>for(int i = 1;i <= 100;i++) ……
<P>
<P>for
语句的复合结构,使得程序变得简捷。比如上面的例子中,原来 while或者do...while结构中,循环体内必须两句语句,现在只需一句(即:i++这一句被移到for的特定位置上),这样,我们可以去除花括号:
<P>for(int i=0;i <= 100;i++)
<P> sum += 100;
<P>当然,如果在其它情况下,for的循环体内仍需有多行语句时,{}仍是不可避免的。事实上,就算现在这种情况,我也建议大家使用花括号。这样可以让程序的结构看上去更清晰。
<P>
<P>在本例中,如果非要讲究简捷,我们还可以将循环体内的那惟一的一行移到“条件改变”的位置:
<P>for(int i=1; i<=100;sum += i,i++);
<P>sum += i和i++之间用逗号分开。而在for后面的()行末,则直接跟上分号,表示for不必再执行其它的语句。
<P>考虑到后置++的特性(在完成表达式的求值后,才进行加1操作),也可以将sum += i和i++合为一句:
<P>for(int i=1;i<=100;sum += i++);
<P>
<P>以上讲了for语句极尽合并之技巧,以求一个简捷。反过来,for语句也可以向 while或do...while语句一样拆开写:
<P>
<P>int i = 1;
<P>for(; i <= 100;)
<P>{
<P> sum += i;
<P> i++;
<P>}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -