?? 教學(xué)--第十章 循環(huán)語句.htm
字號(hào):
<H3><A name=10.2>10.2</A> do ... while 循環(huán)</H3>
<P>
<P>語法形式:
<P>
<P>do
<P>{
<P> 需要循環(huán)執(zhí)行的語句;
<P>}
<P>while(條件);
<P>
<P>和
while循環(huán)最明顯的區(qū)別,就是do...while循環(huán)中,判斷是否繼續(xù)循環(huán)的條件,放在后面。也就是說,就算是條件一開始就不成立,循環(huán)也要被執(zhí)行一次。請(qǐng)比較以下兩段代碼,前者使用while循環(huán),后者使用do...while循環(huán)。
<P>
<P>代碼段一:
<P>int a = 0;
<P>while( a > 0 )
<P>{
<P> a--;
<P>}
<P>
<P>變量a初始值為 0,條件 a > 0 顯然不成立。所以循環(huán)體內(nèi)的 a--;語句未被執(zhí)行。
<P>本段代碼執(zhí)行后,變量a值仍為0;
<P>
<P>代碼段二:
<P>int a = 0;
<P>do
<P>{
<P> a--;
<P>}
<P>while( a > 0 );
<P>
<P>盡管循環(huán)執(zhí)行前,條件 a > 0 一樣不成立,但由于程序在運(yùn)行到
do...時(shí),并不先判斷條件,而是直接先運(yùn)行一遍循環(huán)體內(nèi)的語句:a--。于是a的值成為 -1,然后,程序才判斷 a > 0
,發(fā)現(xiàn)條件不成立,循環(huán)結(jié)束。
<P>
<P>do..while中的條件和while循環(huán)中的條件一樣是:“允許繼續(xù)循環(huán)的條件”,而不是“結(jié)束循環(huán)的條件”,這和Pascal語言中的do...until正好相反,學(xué)習(xí)過Pascal(Delphi)的學(xué)員可得注意。
<P>
<P>以筆者的經(jīng)驗(yàn),do..while循環(huán)用得并不多,大多數(shù)的循環(huán)用while...來實(shí)現(xiàn)會(huì)更直觀。下面我們僅簡(jiǎn)單地將1到100的連加程序轉(zhuǎn)換為用do...while實(shí)現(xiàn):
<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實(shí)現(xiàn)可以多次統(tǒng)計(jì)的程序。</B>
<P>
<P>在例二中,我們做了一個(gè)統(tǒng)計(jì)程序。假如一個(gè)學(xué)生有三門成績(jī),如語文,數(shù)學(xué),英語要統(tǒng)計(jì)總分,例二的程序可以方便地使用,但如果要連續(xù)統(tǒng)計(jì)一個(gè)班級(jí)每個(gè)學(xué)生的這三門成績(jī),我們就得不斷地運(yùn)行例二的成績(jī),這顯然不方便。
<P>一個(gè)同學(xué)的三門成績(jī)需要一層循環(huán),要不斷統(tǒng)計(jì)多個(gè)同學(xué)各自的成績(jī),就需要再套上一層循環(huán)。請(qǐng)看下面例子中,如何在原來的
while...循環(huán)上再加一層do...while循環(huán)。
<P>程序的思路是:統(tǒng)計(jì)完一遍后,就問一句是否要繼續(xù)統(tǒng)計(jì)新同學(xué)的成績(jī),如果用戶輸入字母Y或y,表示需要統(tǒng)計(jì)一下位,否則,程序結(jié)束循環(huán)。
<P>這個(gè)程序是在例二的基礎(chǔ)上進(jìn)行功能改進(jìn),以下粗體部分為新加的代碼。
<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 用于存儲(chǔ)有幾個(gè)成績(jī)需要統(tǒng)計(jì)。
<P> int i; //i 用于計(jì)數(shù)
<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 << "====成績(jī)統(tǒng)計(jì)程序====" <<
endl;<BR>
<P> //用戶需事先輸入成績(jī)總數(shù):
<P> cout << "請(qǐng)輸入待統(tǒng)計(jì)的成績(jī)個(gè)數(shù):";
<P> cin >> num;
<P> cout << "總共需要輸入"<< num
<< "個(gè)成績(jī)(每個(gè)成績(jī)后請(qǐng)加回車鍵):" << endl;
<P>
<P> while ( i <= num)
<P> {
<P> cout << "請(qǐng)輸入第"
<< i << "個(gè)成績(jī):";
<P> cin >>
score;<BR>
sum +=
score;<BR>
i++;<BR>
}<BR><BR>
//輸出統(tǒng)計(jì)結(jié)果:<BR> cout
<< "參加統(tǒng)計(jì)的成績(jī)數(shù)目:" << num << endl;<BR>
cout << "總分為:" << sum <<
endl;
<P>
<P><B> //提問是否繼續(xù)統(tǒng)計(jì):</B>
<P><B> cout <<"是否開始新的統(tǒng)計(jì)?(Y/N)?";</B>
<P><B> cin >> c;</B>
<P><B> }</B>
<P><B> while( c == 'y' || c == 'Y');</B>
<P>}
<P>//---------------------------------------------------------------------------<BR>
<P>程序完成一次統(tǒng)計(jì)以后,會(huì)提問“是否開始新的統(tǒng)計(jì)”,用戶輸入一個(gè)字母,存到變量
c,然后程序在do...while的條件里檢查c是否等于‘Y’或‘y’。如果不等于,就結(jié)束循環(huán)。
<P>由于程序在統(tǒng)計(jì)之后有一個(gè)提問的時(shí)間,所以,原來的getchar()就不再需要了。
<P>在這個(gè)例子,外層循環(huán)使用do...while是最好的選擇,因?yàn)椋脩暨\(yùn)行本程序,多數(shù)情況下,他至少想統(tǒng)計(jì)一次。
<P>
<P>最后我們來看do...while循環(huán)的流程圖,請(qǐng)和while的流程圖對(duì)比。
<P>
<P><IMG height=284 src="教學(xué)--第十章 循環(huán)語句.files/ls10.h5.gif" width=276
border=0>
<P>
<H3><A name=10.3>10.3</A> for 循環(huán)</H3>
<P>for
循環(huán)里在C,C++里用得最多,也是最靈活的循環(huán)語句。要學(xué)好它,需要從已經(jīng)學(xué)過的while循環(huán)的身上,“挖掘”出有關(guān)循環(huán)流程的要素,這些要素隱藏在while,或do...while的背后,但它將直接體現(xiàn)在for循環(huán)的結(jié)構(gòu)上。
<H4><A name=10.3.1>10.3.1</A> 循環(huán)條件三要素</H4>
<P>
<P>學(xué)習(xí)了兩種循環(huán),我們來挖掘一下循環(huán)流程中的“條件三要素”。
<P>
<P><B>第一、條件一般需要進(jìn)行一定的初始化操作。</B>
<P>
<P>請(qǐng)看我們用while循環(huán)實(shí)現(xiàn)1到100累加的代碼:
<P>
<P><I>int sum = 0; //變量sum將用于存儲(chǔ)累加和,將它初始化為0,這很重要。</I>
<P><I>int i = 1; //i是每次要加的數(shù),它從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>這段代碼中,循環(huán)的條件是 i <= 100;因此,一開始,i肯定需要一個(gè)確定的值。前面的:
<P>int i = 0;這一行代碼,在聲明變量i的同時(shí),也為i賦了初始值:1。這樣,條件 i <= 100 得以成立(因?yàn)閕為1,所以 i
<= 100 當(dāng)然成立)。
<P>
<P><B>第二、循環(huán)需要有結(jié)束的機(jī)會(huì)。</B>
<P>
<P>程序中最忌“死循環(huán)”。所謂的“死循環(huán)”就是指該循環(huán)條件永遠(yuǎn)為真,并且,沒有另外的跳出循環(huán)的機(jī)會(huì)(后面將學(xué)到)。比如:
<P>
<P>//一段死循環(huán)的例子:
<P>while ( 2 > 1 )
<P>{
<P> cout << "死循環(huán)" <<endl;
<P>}
<P>
<P>執(zhí)行這段代碼,你會(huì)發(fā)現(xiàn)程序停不下來了。原因就是它的循環(huán)條件 2 > 1
永遠(yuǎn)為true。所以,一個(gè)最后可以變成不成立條件在大多數(shù)情況下是必需的。比如在while的那個(gè)例子:
<P><I>while ( i<= 100)</I>
<P>條件 i <= 100 ,由于 i 在循環(huán)中被改變,所以它至少在理論上有可能造成 i <= 100 不成立。
<P>
<P><B>第三、在循環(huán)中改變循環(huán)條件的成立因素</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>同樣是一段可怕的“死循環(huán)”。因?yàn)閕沒有被改變的機(jī)會(huì),其值永遠(yuǎn)為1,從而循環(huán)條件
i<=100也就永遠(yuǎn)為真。所以在循環(huán)中最后一句(下面加粗部分),不可遺忘。
<P><I>while ( i<= 100)</I>
<P><I>{</I>
<P><I> sum += i;</I>
<P><I><B> i++;</B></I>
<P><I>}</I>
<P>當(dāng)然,在這段程序里,i++除了起改變條件成立因素以外,同時(shí)也起上sum不斷加遞增的數(shù),從而實(shí)現(xiàn)得到累加和。
<P>
<P>說完這一些,我們來看C,C++中最靈活循環(huán)結(jié)構(gòu):for循環(huán)。
<P>
<H4><A name=10.3.2>10.3.2</A> 三要素在for循環(huán)結(jié)構(gòu)上體現(xiàn)</H4>
<P>
<P>for 循環(huán)的語法:
<P>
<P>for(條件初始化;條件;條件改變)
<P>{
<P> 需要循環(huán)執(zhí)行的語句;
<P>}
<P>
<P>可見,for的結(jié)構(gòu)中,不僅提供了的“條件”的位置,同時(shí)也提供了條件初始化,和條件改變的位置。這三者雖然在同一行上,但并不是依次連接地執(zhí)行。
<P>
<P>條件初始化的表達(dá)式首先被執(zhí)行(并且只被執(zhí)行一次);
<P>然后程序檢查條件是否成立,如果成立就執(zhí)行循環(huán)體中的語句,否則直接結(jié)束循環(huán)。
<P>執(zhí)行完一遍循環(huán)以后,程序執(zhí)行“條件改變”語句。
<P>
<P>1到100整數(shù)累加的程序,改為for循環(huán)寫,是最合適的了:
<P>
<P>int sum = 0;
<P>int i;
<P>
<P>for( i=1; i <= 100;i++)
<P>{
<P> sum += i;
<P>}
<P>
<P>程序先執(zhí)行條件初始化語句:i=1;
<P>然后立即判斷條件 i <= 100 嗎?顯示,此時(shí)該條件成立;
<P>于是程序執(zhí)行循環(huán)體內(nèi)的語句,此時(shí)只有一句: sum += i;
<P>然后,執(zhí)行改變條件因子的語句: i++; 此時(shí),i值變?yōu)?2;
<P>程序再次判斷條件 i <= 100 ?,依然成立,于是開始第二遍循環(huán)……
<P>
<P>變量 i 可以初始化條件時(shí)才臨時(shí)聲明:
<P>for(int i = 1;i <= 100;i++) ……
<P>
<P>for
語句的復(fù)合結(jié)構(gòu),使得程序變得簡(jiǎn)捷。比如上面的例子中,原來 while或者do...while結(jié)構(gòu)中,循環(huán)體內(nèi)必須兩句語句,現(xiàn)在只需一句(即:i++這一句被移到for的特定位置上),這樣,我們可以去除花括號(hào):
<P>for(int i=0;i <= 100;i++)
<P> sum += 100;
<P>當(dāng)然,如果在其它情況下,for的循環(huán)體內(nèi)仍需有多行語句時(shí),{}仍是不可避免的。事實(shí)上,就算現(xiàn)在這種情況,我也建議大家使用花括號(hào)。這樣可以讓程序的結(jié)構(gòu)看上去更清晰。
<P>
<P>在本例中,如果非要講究簡(jiǎn)捷,我們還可以將循環(huán)體內(nèi)的那惟一的一行移到“條件改變”的位置:
<P>for(int i=1; i<=100;sum += i,i++);
<P>sum += i和i++之間用逗號(hào)分開。而在for后面的()行末,則直接跟上分號(hào),表示for不必再執(zhí)行其它的語句。
<P>考慮到后置++的特性(在完成表達(dá)式的求值后,才進(jìn)行加1操作),也可以將sum += i和i++合為一句:
<P>for(int i=1;i<=100;sum += i++);
<P>
<P>以上講了for語句極盡合并之技巧,以求一個(gè)簡(jiǎn)捷。反過來,for語句也可以向 while或do...while語句一樣拆開寫:
<P>
<P>int i = 1;
<P>for(; i <= 100;)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -