Transcript CHppt\ch5
第五章 控制結構 陳維魁 博士 [email protected] 儒林圖書公司 1 大綱 結構化程式設計 結構化程式設計的基本結構 反覆結構 流程圖 精選習題 2 結構化程式設計 定義 注意事項 當採用結構化程式設計法來設計程式時,應當儘量避 免使用GOTO命令,以避免破壞程式的可讀性及結構性。 優點 從事程式設計的過程中,依照程式的邏輯特性將程式 細分成幾個較小的問題,再將這些較小的問題同樣依 照程式的邏輯特性再往下細分成更小的問題,依此類 推直到很容易編寫程式的單元時為止。 程式可分工、容易除錯、可讀性較高及較易維護 缺點 程式碼較長及執行時間較久 3 結構化程式設計的基本結構 基本結構共有三類 循序結構(sequential structure) 敘述會按照先後順序來執行 選擇結構(selection structure) 單路選擇 雙路選擇 多重選擇 反覆結構(iteration structure) 前測迴路 後測迴路 4 循序結構 循序執行的程式段即為循序結構 範例 敘述-1; 敘述-2; … 敘述-n; 以上n條敘述按照敘述-1、敘述-2、…、敘 述-n的順序執行 5 選擇結構 選擇結構可分為 單路選擇 雙路選擇 多重選擇 6 單路選擇結構 意義 條件成立時有相對應的敘述必須被處理,但是當條件 不成立時則沒有相對應的敘述要處理,因此稱為單路 選擇 範例 Pascal語言 if 條件 then 敘述 C/C++/Java語言 if (條件) 敘述 Basic語言 if 條件 then 行號或敘述 Algol 60語言 if 條件 then敘述 以上的單路選擇敘述均代表條件成立時執行對應之敘述,但若條件不 成立則直接執行if的下一條敘述 7 雙路選擇結構 意義 條件成立時有相對應的敘述必須被處理,而且當條件 不成立時也有相對應的敘述要處理,因此稱為雙路選 擇 範例 Pascal if 條件 then 敘述1 else 敘述2 C/C++/Java if (條件) 敘述1;else 敘述2 BASIC if 條件 then 行號或敘述 else 行號或敘述 Algol 60 if 條件 then敘述1 else敘述2 8 範例 若A=-5,B=5,則執行完下列程式後,A、B變成多 少?(A)5,5 (B) -5,-5 (C) 5,-5 (D) 15,5 if (A<0) if (B<0) A=B; else B=A; else A=B+10; 執行B=A A不變=-5, B=-5 9 範例 (1)執行下列程式所印出之值為何? G=2 (2)若將S的值改為85,則印出之值又將為何? (3)又若將S的值改為65,則結果為何? S=30; G=2; IF S> =60 THEN IF S> =70 THEN G=4 ELSE G=6; WRITELN(G); 1.Pascal ELSE和第二個IF一起,都沒執行,因此G=2 2.85>=70 G=4 3. 65小於70,執行ELSE G=6 10 範例 執行右側的Java程 式,可能得到幾種 不同的V值,分別 為何?使V值為1的 條件為何?(將條件 盡量簡化) !L and !S !C and !S V=1; if (C && L) V=2; else if (! C) { if (S && Y) V=3; else if (S && (! Y)) V=4; } 11 範例 底下的C程式會讓變數X之值為何? if (((3>2) && (2<2))∣∣(5==6)∣∣((5>4) && 3)) x=3; else x=4; 只要其中一個成立就可以成立,((3>2) && (2<2))成立 因此執行x=3 12 多重選擇結構 多重選擇結構一般是指case結構 Algol W首創case結構 13 多重選擇結構 -- Algol W Algol W的case結構語法如下: case <整數運算式> of begin exp 1; exp 2; ... exp n; end; 其中case的選擇項一定必須是整數運算式,此點 大大限制了case敘述的使用彈性。當選擇項的值 為1時執行exp 1,為2時執行exp 2,...,為n時則執行 exp n 14 多重選擇結構 -- Pascal Pascal語言提供的case敘述語法如下: case <選擇運算式> of <選擇標記1>: 敘述1; <選擇標記2>: 敘述2; ...... <選擇標記n-1>: 敘述(n-1) 〔else 敘述n〕 end; 以上case敘述代表當<選擇運算式>=<選擇標記1>時執行“敘述1”,若<選擇運算式>=<選擇標記2>時執行“敘述-2”,….,若< 選擇運算式>=<選擇標記n-1>時執行“敘述-(n-1)” 但若<選擇運算式>與所有的<選擇標記>皆不符合時則執行時執 行“敘述-n”(假如“else”部份存在) Pascal語言的case敘述屬於內隱分歧(implicit branch)結構 運算式的型態:整數,布林值,字元、列舉式資料型態或子範圍 皆可 15 Case number of 1,3,4 : begin oddnumber:=oddnumber+1 oddsum:=oddsum+number end; 2,4,6 : begin evennumber:=evennumber+1 evensum:=evensum+number end else writeln(‘error input’) End; 16 多重選擇結構 – C/C++/Java C/C++/Java 語言提供的多重選擇結構語法 switch (<選擇運算式>) { case(選擇標記1): 敘述1; break; case(選擇標記2): 敘述2; break; ..... case(選擇標記n-1): 敘述(n-1); break; [default: 敘述n;] } 以上switch敘述代表,當<選擇運算式>=<選擇標記1>時執行“敘述1”,若<選擇 運算式>=<選擇標記2>時執行“敘述2”,….,若<選擇運算式>=<選擇標記n-1> 時執行“敘述(n-1)” 但若<選擇運算式>與所有的<選擇標記>皆不符合時則執行時執行“敘述n”(假如 “default”部份存在)。 switch敘述屬於外顯分歧(explicit branch)結構 switch結構中之敘述為單一或複合敘述皆可 17 Switch (number) { case(1,3,5):{ oddnumber=oddnumber+1; oddsum=oddsum+number; } break; case(2,4,6):{ evennumber=evennumber+1; evensum=evensum+number; } break; default:printf(“error input”); } 18 多重選擇結構 – ADA Ada語言的case結構之語法結構 case 運算式 is {when 選擇 {∣選擇}敘述} end case “運算式”可為整數或列舉式資料的型態 可利用“others”來減少未定義之情況 19 多重選擇結構設計時應注意的事項 選擇運算式允許的型態為何? 是否允許由 CASE 標記內,跳出到外部結 構? 是否允許外部結構跳入 CASE 標記內? 標記間是否必須彼此互斥 (disjoint)? 是否提供“default”或“else”等未定義情 況? 20 反覆結構 定義 反覆結構(iteration structure)是指讓一個或一群 敘述能夠反覆的執行之敘述群 種類 前測迴路 後測迴路 21 前測迴路(pre-test loop) 特性 迴圈執行的最少次數是0次 最多次數是無限多次 一般程式語言常見的前測迴路可分為二類 while-loop for-loop 22 Pascal 的 while-loop 語法 while <條件> do begin 迴圈敘述 end; 執行while loop時會先測試<條件>是否成立, 當<條件>成立時,才會進入迴圈敘述執行, 否則跳出迴圈結構,所以while loop可能一 次也不執行 23 C/C++/Java 的 while-loop 語法 while (<條件>) { 迴圈敘述 } 執行while loop時會先測試<條件>是否成立, 當<條件>成立時,才會進入迴圈敘述執行, 否則跳出迴圈結構,所以while loop可能一 次也不執行 24 Basic 的 while-loop 語法 while <條件> 迴圈敘述 wend 執行while loop時會先測試<條件>是否成立, 當<條件>成立時,才會進入迴圈敘述執行, 否則跳出迴圈結構,所以while loop可能一 次也不執行 25 while loop 重要特性 迴圈執行之次數事先可不知 26 i:=0; While i<=20 do i:=i+5; Writeln(i); i執行的值0,5,10,15,20最後變成25時候 不再進入迴圈 27 範例 右側程式段執行完畢 後,S=? I從7開始每次加3直到 127 共41次 S的值7+10+13….+127 S = 0; I = 7; while (I <= 127) { S := S+I; I := I+3; } 28 Pascal 的 for-loop 第一種 for 控制變數 := <初值> to <終值> do begin 迴圈敘述 end; 第二種 for 控制變數 := <初值> downto <終值> do begin 迴圈敘述 end; 變數每次遞增之值需在程式中控制,而非在“for statement”中控制 29 S:=0; For i:=1 to10 do S:=S+1 S:=0; For i:=10 downto 1 do S:=S+1; 30 J:=10; for i:=3 to 13 do J:=J+i Writeln(j); i執行的值3,4,5…13共11次 J=10+3+4…+13 31 C/C++/Java 的 for-loop 語法 for (exp1;exp2;exp3) { 迴圈敘述 } exp1:設定控制變數之初值 exp2:設定迴圈執行時,控制變數之範圍 exp3:設定控制變數變化的情況 32 For (i=1;i<=5;i++) { } 共執行五次 33 SUM=0; For (I=-5;I<=154;I=I+3) SUM=SUM+I; I的值-5,-2,1…154 共執行54次 34 S=0; For (I=7;I<=127;I=I+3) S=S+I; S的值7,10…127執行41次 35 Basic 的 for-loop 語法 FOR 控制變數 = 初值 TO 終值 STEP 遞增量 迴圈敘述 NEXT 控制變數 當遞增量>=0時,控制變數<=終值,執行 迴圈敘述 當遞增量<0時,控制變數>=終值,執行迴 圈敘述 36 範例 BASIC程式片段 如右,試計算 出當程式執行 後,何數將被 印出? I=11,18…123 執行17次 S=11+18….123 1139 10 S = 0 20 FOR I = 11 TO 123 STEP 7 30 S = S+I 40 NEXT I 50 PRINT S 37 範例 右列BASIC程式 中K=K+I*J將 被執行多少次? I=1,4 J=5,3,1 共執行6次 10 FOR I=1 TO 6 STEP 3 20 FOR J=5 TO 0 STEP-2 30 K=K+I*J 40 NEXT J 50 NEXT I 38 範例 10 S=0 20 FOR I=7 TO 127 STEP 3 30 S=S+I 40 NEXT I 50 PRINT S 60 END 請問S=? I執行7,10,13,…127 共41次 S=7+10….127=2747 39 Fortran 77 的 DO-loop Fortran 77“DO-loop”即一般高階語言的“for-loop” 語法 Do label控制變數=初值,終值,增值 迴圈敘述 label continue DO loop的特性為控制變數的型態可以是整數、單精確度 型態 控制變數在Do loop中可變更,僅能由Do敘述進入Do loop 中(即“單一入口”之規定) Fortran 77的Do loop結構中的迴圈敘述可能一次也未能執行, 也就是說Fortran 77的DO loop是前測迴路 40 DO 100 I=10,30,5 I執行10,15,20,25,30共五次 41 K=0 DO 10 I=1,6 IF (K) 1,2,3 1 K=K+4 GOTO 10 2 K=K-3 GOTO 10 3 K=3*K-1 10 CONTINUE K<0 goto 1 K=0 goto 2 K>0 goto 3 I從1到6執行 I=1 K開始0 執行2 K=-3 I=2 K=-3 執行1 K=1 I=3 K=1 執行3 K=2 I=4 K=2 執行3 K=5 I=5 K=5 執行3 K=14 I=6 K=14 執行3 K=41 42 Algol 60 的 for-loop 語法 for敘述::=for控制變數:= <list-element> {,<list-element>}do <stmt> <list-element>::= <exp>∣<exp> step <exp> until <exp>∣<exp> while <Boolean-exp> Algol 60“for loop”的特性為前測迴路 控制變數的型態可以是整數或實數 控制變數在Do loop中能改變 可利用GOTO敘述跳躍至迴圈敘述內 43 Ada 的 for-loop 語法 for 控制變數 in 〔reverse〕 範圍 loop 迴圈敘述 end loop 控制變數的型態必須是整數或列舉式資料型態 控制變數在Do loop中不能改變 不可利用GOTO敘述跳躍進入迴圈敘述 44 For I in 1…100 Loop SUM:=SUM+I; End loop SUM=1+2…100 45 PL/1語言的 for-loop語法 (1) DO控制變數=初值 TO 終值 BY 增值 (2) DO I =1 TO 100 END; (3) DO I=1 BY 1 無窮迴圈 (4) DO I=1,3,5,7,9 END; I 在這五個值執行 46 後測迴路 (post-test loop) 特性 迴圈執行的最少次數是1次 最多次數是無限多次 47 Pascal 的後測迴路 語法 repeat 迴圈敘述 until <條件> 先執行迴圈敘述再檢查<條件>,<條件>不 成立時執行迴圈敘述,當<條件>成立時將 離開迴圈結構 48 C/C++/Java 的後測迴路 語法 do { 迴圈敘述 } while (<條件>) 先執行迴圈敘述再檢查<條件>,<條件>成 立時執行迴圈敘述,當<條件>不成立時將 離開迴圈結構 49 Fortran IV 的 DO-loop 語法 Do label控制變數=初值,終值,增值 迴圈敘述 label continue 控制變數的型態必須是整數 控制變數在Do loop中不能改變 可利用GOTO敘述離開迴圈敘述 最特別的是Fortran IV的Do loop結構中的迴圈敘述至少會 執行一次,也就是說Fortran IV的DO loop其實是後測迴路, 這種作法,大大地違背了程式設計師的習慣用法,因此在 Fortran 77便已將“DO loop”改為前測迴路 50 流程圖(flow chart) 主要的功用是發展程式時可利用流程圖來 做為分析的工具,而且讓維護工作較容易 且容易除錯 51 常見的流程圖符號 開始/結束符號 輸入/輸出符號 敘述符號 連接符號 副程式 流向符號 條件判斷符號 52 精選習題 請簡述GOTO敘述的分類 (a) 非條件的GOTO: 即不需檢查條件是否成立,而執行GOTO敘述後之標記 (label)所指定的敘述稱之。 例:GOTO 10 即直接跳躍到標記10的地方執行。 (b) 條件的GOTO: 當條件成立時才跳到GOTO敘述後之標記所指到的敘述執行 。 例:IF <條件> THEN GOTO 10 在條件成立時才會跳躍到標記10的地方執行 53 GOTO結構有何利弊,舉出四種可以 取代GOTO結構的流程控制敘述指令 (1) GOTO結構的優點: a. 在小程式中,使用GOTO敘述可簡化程式的製作。 b. 可與硬體指令JUMP配合,所以執行效率較高。 c. 可以改變任何一種控制結構。 d. 易學、易用。 (2) GOTO結構的缺點: a. 程式中敘述的順序與執行的順序不能互相對應,所以破壞了程式的結構性。 b. 由於程式不具結構性所以程式的可讀性,可靠性皆低,更重要的是不易維護。 (3) 可替代GOTO結構的流程控制如下: a. case structure b. while loop 其結構如下: while <條件> do begin end c. repeat...until 其結構如下: repeat until <條件> d. for loop for <變數>=<初值> TO <終值> Step <增值> do begin end 54 試舉一例說明何謂無窮迴路(infinite loop)? 以Pascal語言為例: while true do begin end; 上例中由於while loop中的條件式恆成立 (true)所以為一無窮迴路。 55 6. 執行底下的C程式後,變數Z的值為何? x=50; y=0; for(i=1;i<=10;i++) y+=i; z=(x > y) ? x+y : x-y; (20分) x=50; y=0; for(i=1;i<=10;i++) y+=i; 執行以下程式後,y=55 所以答案為-5。 56 . 設以下為一Pascal程式則輸出結果sum? sum:= 0; for k:= 1 to N-1 for i:= k+1 to N for j:= k+1 to N sum:= sum+1 已知N=0 已知N=0 ∴程式可知為 sum:=0; for k=1 to –1 for I = k+1 to 0 for j = k+1 to 0 sum:=sum+1 ∴for loop一次也不執行 故sum=0 57 計算下列各程式片段執行之次數 for i = 1 to n do j=1 for k = j+1 to n do x=x+1 end end n×(n-1) 58 請寫出下列BASIC程式的執行結果: 10 DIM X(3, 4) 20 LET L = 1 30 FOR I = 1 TO 3 這是一個雙層的for loop程式段,內 40 FOR J =1 TO 4 層的for loop會執行4次(當J=1~4 50 X(I,J) = L 時),外層的for loop則會執行3次 60 PRINT X (I,J); (當I=1~3時),所以整個loop共會 70 LET L =L + 1 執行12次(3*4)。而每次當loop敘 述被執行時均會設定X(I , J)的值為 80 NEXT J L並將其值印出而由於輸出敘述為 90 NEXT I “PRINT X(I , J);”其中含有 100 PRINT “;”表示輸出結果後不換行,因 110 END 此答案為 1 2 3 4 5 6 7 8 9 10 11 12。 59 10 K=0 20 FOR I=3 TO 38 30 K=K+I 40 NEXT I 50 WRITE K 問 (1) (a)執行完後30敘述共執行幾次?(b) K值為何? (2) 若20敘述改為FOR I=-3 TO –9,問結果K為何,20敘述共 執行幾次? (3) 若改為FOR I=-6 TO 6問結果K為何,20敘述共執行幾次? (4) 若改為FOR I=3 TO 36 STEP 3,問結果K為何,20敘述共 執行幾次? 60 (1) a. 因為FOR敘述的計數控制由3~38,∴30敘述會執行 38-3+1=36次。 b. K=738 (2) For I=-3 TO –9 會使得初值>終值,所以loop一次也不執行,故K=0,而20敘述則 會執行一次。 (3) For I=-6 To 6 K=-6+(-5)+(-4)+…+(-1)+0+1+…+4+5+6 = 0 而20敘述則會執行14次(須加上一次不合的I值測試) (4) For I=3 To 36 STEP 3 K=3+6+…+36 利用等差級數公式求項數 已知an = a1+(n-1)×d 其中an是末項,a1是首項,n是項數,d是公差。 ∴36=3+(n-1)×3 33=(n-1)×3 ∴n=12 61 ∴K=234,而20敘述會執行12+1=13次 說明FORTRAN IV和FORTRAN 77 之DO迴 圈的不同之處。 Fortran IV和Fortran 77都是Fortran語言僅是版本不同而 已。 Fortran 77是較新的版本其較Fortran IV所增加的功能如下 : (1) 多增加了Block-IF instruction故較Fortran IV具結構 化的概念。 (2) I/O instruction允許算術運算式存在。 (3) 具有Free Format的I/O指令。 分析Fortran IV與Fortran 77迴圈的作法知Fortran IV至少 會執行其迴圈敘述一次,而Fortran 77則可能一次也不執行62 試問C語言和Pascal語言的for loop有何 不同?二種語言不同設計的主要理由 為何? (1) C語言的for敘述之語法:請參考本章之內容。 (2) Pascal語言的for敘述之語法:請參考本章之 內容。 (3) 結論:C語言允許for loop中控制變數之值的 變化較有彈性,而Pascal語言則只允許for loop中 控制變數之值的變化情形為加一或減一因此較為單 純。 63 下列FORTRAN迴圈執行幾次?結果K值為 何? DO 100 I=5, 40,7 K=0 K=K+I 100 CONTINUE (1) 當I=5, 12, 19, 26, 33, 40時執行loop,故共執行了 六次。 (2) 每次進入迴圈皆將K值重新設定為0 ∴K=K+I→K=I,所以最後結果K=40。 64 將下列部份程式寫成部份流程圖: 50 IF 布耳算式 1 THEN 敘述 1: GOTO 70 60 IF 布耳算式 2 THEN 敘述 2 ELSE 敘述 3 70 敘述 4 65