Download presentation
Presentation is loading. Please wait.
1
第五章 迴圈敘述 5-1 for 5-2 while與repeat 5-3 goto 5-4 with
2
人類的生活有許多事都是具有重複性的,例如一天有24小時、一星期有七天、同一門課要上18次才能拿到學分。程式設計的目的是要解決日常生活中可預期的事件,為了解決其重複性,Delphi的迴圈敘述如下:
1. for 2. while、repeat 3. goto 4. With for的使用時機為程式設計階段已知執行次數,請看5-1節。若未知執行次數,則應使用while或repeat,請看5-2節。goto則為非結構化語言的遺留產物,原則上它應已走入歷史,很多人建議應將goto敘述從結構化語言移除,但又擔心有些程式無法適應,所以目前goto敘述還是繼續存在,請看5-3節。with的功能為同時設定同一記錄的多個欄位、或是同一物件的多個屬性與方法,請看5-4節。
3
5-1 for 若於程式設計階段已知要執行的次數,則可使用for敘述,Delphi的for敘述語法如下:
for變數 := 計數初值 <to/downto> 計數終值 do begin [敘述區塊1 ;] [break ;] [continue ;] [敘述區塊2 ;] end ; 以上語法說明如下: 1. for敘述的計數變數必須是序數變數,且又分為遞增計數與遞減計數。遞增計數時,採用to;遞減計數時,則使用downto。 2. 程式若執行到break,則會提早離開for迴圈。
4
3. 程式若執行到continue,則會略過continue下面的敘述區塊2,繼續執行下一個計數變量,請看範例5-1c。
for for begin begin 敘述區塊1; 敘述區塊1; break; continue; 敘述區塊2; 敘述區塊2; end; end; 4.以下程式片段可統計1至10的和。 sum:=0 for i:=1 to 10 do sum:=sum+i; 5.敘述區塊內可以放置任何合法的敘述,當然也可含有for。for內再含有for稱為巢狀迴圈,請看範例5-1e。
5
乘法 若沒有乘法運算子,則應如何計算乘法呢?答案是可用累加的方式來計算。例如62 x 38,亦就是62連續相加38次的結果,請看以下程式說明。
6
範例5-1a 請用for迴圈完成乘法運算。
7
〔自我練習〕 1.請寫一程式,可以輸出任一指定數字的九九乘法。
8
範例5-1b 試求2.1+1.9+1.7+…+(-7.1)之和。 程式說明:
1. Canvas是一個無圖示的物件,所以元件盤上並沒有Canvas元件的圖示,若要使用Canvas物件,直接在程式中鍵入物件名稱“Canvas”即可。Canvas的功能是輸出字串與繪圖,詳細說明請看第十三章的繪圖。 2. TextOut是輸出字串的程序,語法如下,其中x、y是顯示字串的座標位置。 Text (x,y,字串) 3. Delphi的計數變數只可以為序數型態,所以計數變數不可為小數。
9
範例5-1c 示範break及continue敘述。
10
質數的判斷 一個整數除了1及本身外,若無任何數可以整除它,則稱此數為質數。欲判別輸入的整數N是否為質數,最直接的方法就是將N連續使用2至N-1去除,若均無法整除,則N即為質數。像這種重複某一項工作,且有明確的起始值及終值的演算法,最適合使用for迴圈。
11
範例5-1d 示範質數的判斷。
12
巢狀迴圈 for的迴圈中又含有for的迴圈稱為巢狀迴圈,以下的程式片段可求10次1至20的和
procedure TForm1.btnStartClick(Sender: TObject); var n,i:integer; s:string; begin n:=StrToInt(Edit1.Text); s:= '是質數'; for i :=2 to n-1 do if (n mod i) =0 then s:='不是質數'; break; //exit 是離開 procedure end; Label1.Caption:=s;
13
〔自我練習〕 請寫一個程式,可以印出費式數列的指定項目(不可使用陣列)。 例如 : 輸入4,則輸出 1,1,2,3
輸入4,則輸出 1,1,2,3 輸入5,則輸出 1,1,2,3,5 輸入6,則輸出 1,1,2,3,5,8
14
範例5-1e 請使用迴圈輸出如下: 1. 本例共6列,所以外迴圈i為1至6。
* * * * * * * * * * * * * * * * * * * * * 程式說明: 1. 本例共6列,所以外迴圈i為1至6。 2. 內迴圈j處理星星的個數,與外迴圈i的關係 為j = i,所以內迴圈j為1至i。
15
自我練習 1.請寫一程式,輸出結果如下: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
16
自我練習 請寫一程式,輸出結果如下: 1 A 2 2 B B 3 3 3 C C C 4 4 4 4 D D D D
E E E E E E E E E E D D D D C C C B B A
17
範例5-1f 試寫一程式,找出三位數的“阿姆斯壯數”。所謂阿姆斯壯數是指一數等於各位數的立方和,例如153=13+53+33。
程式說明: 本例使用三個迴圈i、j及k,i迴圈從1至9代表百位數、j迴圈從0到9代表十位數、k迴圈從0到9代表個位數,逐一檢驗100至999的三位數是否滿足阿姆斯壯數的條件。
18
〔自我練習〕 1.請寫一個程式,找出四位數中,滿足以下條件者。 abcd=a4+b4+c4+d4
19
5-2 while與repeat 上一節的for是用於已知迴圈次數,但有些情況我們於程式設計階段時並不知迴圈的執行次數,此時即可使用while或repeat敘述,其中while稱為前測試迴圈、repeat稱為後測試迴圈。而其差別在於,while是先測試條件運算式為真時,繼續執行迴圈,此種前測試迴圈有可能不執行迴圈內容便直接離開;repeat則是先執行迴圈,待條件運算式為真時再離開迴圈,也就是迴圈內容至少執行一次。
20
while 前測試迴圈的while語法如下: begin 敘述區塊1 ; break ; [敘述區塊2 ;] end ; 以上語法說明如下:
while運算式 do begin 敘述區塊1 ; break ; [敘述區塊2 ;] end ; 以上語法說明如下: 1.運算式結果為真時,繼續執行迴圈敘述。 2. break敘述可提早離開迴圈。 3. 以下程式片段,可求1至10的和。 i:=1; sum:=0; while i<=10 do sum:=sum+i; i:=i+1;
21
repeat 後測試迴圈的repeat語法如下: while運算式 do repeat [敘述區塊1 ;] [break ;]
[敘述區塊2 ;] write運算式 ; 以上語法說明如下: 1. 運算式結果為真時,離開迴圈。 2. break敘述可提早離開迴圈。 3. 以下程式片段,可求1至10的和。 i:=1; sum:=0; sum:=sum+i; i:=i+1; until i>=11;
22
除法 假如沒有除法運算子,該如何完成除法運算呢?可以將被除數連續減去除數、並計算可減去幾個除數,則可減去的除數個數即為商、剩下的被減數即為餘數,其演算法如下: 1. a =被除數。 2. b =除數。 3. 商數q = 0。 4. 所謂的商就是被除數a共可減去幾個除數b,也就是只要a大於等於b,就要執行以下敘述: a=a-b; q=q+1; 5. 本例以8除以3,實際演練如下: 1 a=8;b=3 a>=b成立,所以執行迴圈敘述 a=a-b=5 q=q+1=1 2 a=5;b=3 a=a-b=2 q=q+1=2 3 a=2;b=3 a>=b不成立,所以離開迴圈 q=2(商) a=2(餘數)
23
範例5-2a 示範以上除法運算。
24
進位數的轉換 一個十進位數a要轉為n進位數,其方法是將a連續除以n,直到整數商為0,其餘數的字串累加即為n進位數的值。
以上說明其演算法如下: 1.a為待轉換的十進位數。 2.n為某進位數。 3.r為餘數。 4.strn為n進位數的值。 5.將a連續除以n,直到整數商為0(也就是a>0,則要繼續除),其餘數的字串累加,即為n進位數的值。
25
6.本例以11轉為二進位,實際演練如下: (1) a=11;n=2;strn=' '; r=a%n=1; a=a/n=5; strn='1'; a>0成立,所以繼續迴圈。 (2) a=5;n=2;strn='1'; a=a/n=2; strn='11'(剛出爐餘數的1,要放在原strn的左邊) (3) a=2;n=2;strn=‘11’; r=a%n=0; a=a/n=1; strn='011'; (剛出爐餘數的0,要放在原strn的左邊) (4) a=1;n=2;strn='011'; a=a/n=0; (整數商已經為0;可離開迴圈) strn='1011'; (剛出爐的餘數1,要放在原strn的左邊) a>0不成立,所以離開迴圈。
26
以上演算法的原理解說如下: 1.若要將十進位的a轉為二進位,則以數學式表示如下:
(a)10=a0+a121+a222+a323+a424--- =a0+2(a1+a221+a322+a423---)//a1以後,提出2 2.上式的a0為a除以2後所得的餘數,a1+a221+a322…則為a除以2而得的整數商,重複上式,直至整數商等於零為止 3.最先產生的餘數應放在2進位的最右邊 (a)10=(an…a3a2a1a0)2 以上演算法正適用前測試迴圈的while,請看以下範例說明
27
範例5-2b 請將10進位數轉為b進位數(本例暫討論b範圍為b<=9其餘,b>=11待陣列介紹後再論)。
28
輾轉相除法 輾轉相除法可以求兩數的最大公因數,其處理方式是將大數除以小數,若餘數為0,則小數即為最大公因數;若不為0,改以原小數為被除數、原餘數為除數,繼續相除,直到餘數為0,而促使餘數為0的除數,即為此兩數的最大公因數。演算法說明如下: 1. 輸入a、b兩數。 2. 假如b>a,則兩者交換。 3. r=餘數。 4. 將a除以b,得餘數r。假如,餘數不為0,則以原除數為被除數、原餘數為除數,重複執行a除以b,直到餘數為0,促使餘數為0的除數,即為最大公因數。 5. 本例以a=21,b=9,實際演練如下: (1) a=21;b=9; r=a%b=3; a=b=9; b=r=3; r=0不成立,所以繼續執行迴圈。 (2) a=9;b=3; r=a%b=0; a=b=3; b=r=0; r=0成立,所以離開迴圈,最大公因數為a=3。 以上演算法正適用repeat..until,請看以下範例說明。
29
範例5-2c 請寫一程式完成輾轉相除法,求兩數的最大公因數。
30
二分猜值法 求方程式的解時,若其解必在兩數之間(本例假設兩數為x1與x2),則可使用二分猜值法求解。其方法是先猜兩數的一半(本例假設為x)為方程式的解,將x代入原方程式,若使得原方程式值太大,表示解猜得太大,而正確解必在x1與x之間;反之,表示猜得太小,正確解必在x與x2之間。重複以上二分猜值法步驟,則每次均可將正確解的範圍縮小一半,等到x1與x2之間的距離非常小時(例如 與 ),則此時的x1或x2都可為該方程式的解。
31
二分猜值法的演算法如下: 1. 設求解的正數為x2,則其平方根必在x1=0與x2之間。 2. 首先猜x1+x2之和的一半x。
1. 根必在0與9之間。 2. 首先猜4.5,因4.5的平方大於9,表示猜得太大,所以縮小範圍為〔0,4.5〕。 3. 其次猜2.25,因2.25的平方小於9,表示猜得太小,所以縮小範圍為〔2.25,4.5〕。 4. 重複以上動作,直到猜值的範圍很小時,此範圍內的任意數即為解
32
範例5-2d 請寫一程式完成以上二分猜值法求任一正數的平方根。
33
5-3 goto 前面二節已介紹了結構化程式設計所需使用的迴圈敘述for 、while與repeat,原則上使用以上敘述再配合break及continue,即可解決程式設計所遇到的問題。goto是一種非結構化程式設計所遺留的產物,原則上是一個不該鼓勵使用的敘述,且目前的開發工具Java已將goto去除,所以強烈建議讀者不要刻意學習goto的用法,但還是擔心有人不習慣沒有goto的窘境,因此本節介紹goto用法。 使用goto之前必須宣告跳躍點的標記,其宣告語法如下,其中標記命名方式同識別字的命名。 Label 標記; 其次是標記的使用,其語法如下,跳躍點的標記可在goto的上面或下面,但不可跳離自己的程序、亦不可跳進別的迴圈。 goto標記; 標記 : //跳躍點的標記可在goto的上面或下面
34
範例5-3a 請以goto重作範例5-1a。
35
範例5-3b 請以goto重作範例5-2a。
36
範例5-3c 請以goto重作範例5-2c。
37
5-4 with 若我們要同時設定一個物件或記錄(記錄請看6-3節)的多個屬性或方法,可使用with敘述。例如以下程式片段可同時設定Form1物件的Color、Cursor、Width及Caption等屬性,其執行結果請自行開啟檔案e5-4ap。 with Form1 do begin Color:=clYellow; Cursor:=crCross; Width:=400; Caption:='with 示範 ' end;
38
習題 1.請用雙迴圈印出如下的執行結果: (1) 1 (2) 1 2 3 4 5 1 2 2 3 4 5 1 2 3 3 4 5
(1) (2) (3) (4) E D D D C C C C C B B B B B B B A A A A A A A A A (5) * (6) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
39
2.請用雙迴圈印出如下的執行結果: (1) 19 29 20
40
請用雙迴圈印出如下的執行結果: (2) 11 12 22
41
請用雙迴圈印出如下的執行結果: (3) 101 92 102
42
請用雙迴圈印出如下的執行結果: (4) 99 109 110
43
4.寫程式求以下數列之和(n可任意輸入),此級數(數列之和稱為級數)是收斂或發散?(當n繼續增大 時,數列之和是否持續增大)
3. 寫程式計算下列結果: (1) s=7^2+10^2+13^2…+83^2。 (2) s=(1-1/2)(1-1/3)(1-1/4)+…(1-1/N) 。 (要先輸入N值) (3) s=1-1/2^2+1/3^2-1/4^2+…+(-1)^N/N^2。(要先輸入N值) 4.寫程式求以下數列之和(n可任意輸入),此級數(數列之和稱為級數)是收斂或發散?(當n繼續增大 時,數列之和是否持續增大)
44
6. ,請寫程式估算sinx之值,精確度達小數第五位。此級數是收斂或發散?(x要用弳度量)
45
9. 請寫一個程式,輸入一正整數,將其質因數分解後印出其式子,例如:
9. 請寫一個程式,輸入一正整數,將其質因數分解後印出其式子,例如: 輸入:319 輸出:319=11*19 輸入:19 輸出:19=質數 輸入:521752 輸出:521752=2^3*7^2*11^3 10. 請寫一程式,可以判斷其是否為質數。 11. 請找出小於等於100的所有質數。 12. 請寫一程式,可以累加所輸入的數字,設計階段並不知數字個數,直到輸入值是-1時,印出所輸入數字的最大值、最小值及平均。
46
13. 請寫一個程式,可以處理分數的加減乘除運算,運算之後的結果應約分化為最簡分數或整數。例如:
13. 請寫一個程式,可以處理分數的加減乘除運算,運算之後的結果應約分化為最簡分數或整數。例如: 14. 請寫一程式,可以協助使用者將任意小數轉為分數,例如, 0.3= = (可以約分時要約分) 15. 同第四章第7題,若該公司有五種產品,且每一顧客可能一次購買1至5種產品,請寫一程式,可以列出其購買明細及總金額。
Similar presentations