第四章 決策敘述
4-1 if
4-2 if..else
4-3 case
4-4 綜合範例
人類的生活必須不斷的面臨選擇、決策問題,連我家一個不到三歲的小孩,也常要思考他手裡的十元是要坐電動車還是買棒棒糖。程式語言是協助人類解決問題的工具,當然也包含決
策敘述,Delphi依決策點的多寡,分為以下三種決策敘述:
第一是單一分岐決策的if,例如肚子餓了就吃飯
第二是雙向分岐決策if else,例如肚子餓了就吃飯,否則繼續前進;
第三是多向分岐決策的case,例如你身上有5000元,走進一家五星級的大飯店用餐,你的分岐點就很多,可選擇自助餐、中式套餐、日本料理、泰國餐點等等分岐點。
本章的重點即是探討Delphi的決策敘述。
4-1 if
if通常用於單一分岐的決策,它的使用時機為“假如~則~”,也就是條件成立時,則執行某項工作,若條件不成立時,將不予理會。
其語法如下:
if 運算式 then
begin
敘述區塊 ;
end;
以上語法說明如下:
1.若所要執行的敘述區塊只有一個,則可以省略上下的begin與end,只寫為:
if 運算式 then
單一敘述 ;
2. 若運算式的值為True(條件成立),則執行敘述區塊;運算式的值若為False(條件不成立),該敘述則不會被執行,其
圖如下:
例如,以下敘述,當a的值大於60分時,可設定b為及格。
if a>=60 then
begin
b:="及格" ;
end;
其次,因為條件成立時,只有執行一個敘述,所以begin...end可省略,如以下述。
if a>=60 then
b:='及格';
範例4-1a
請輸入一個成績,若此成績大於等於60分,則輸出“及格”。
本例即是單一分岐決策的典型範例,當條件成立時則執行某個敘述。
本例的if敘述區塊,僅有一個敘述,所以上下的begin與end讀者可自行省略。
範例4-1b
同上範例,但及格時背景以黃色呈現。
範例4-1c
請輸入兩數,並求其較大值
[演算法則]
1.輸入第一數,本例以實數a儲存。
2.輸入第二數,本例以實數b儲存。
3.設定極大值(max)為第一數。
max=a
4.當第二數(b)大於極大值時,極大值即以b取代。
if b > max then
max:=b;
5.輸出極大值(max)即為所求。
自我練習
請輸入兩個數,並求其最小值。
範例4-1d
請輸入三個數,並求其最大值
[演算法則]
1.輸入第一個數,本例以實數a儲存。
2.輸入第二個數,本例以實數b儲存。
3.輸入第三個數,本例以實數c儲存。
4.設定極大值(max)為第一數。
max:=a;
5.當第二數(b)大於極大值時,極大值即以b取代。
if b> max then
max:=b;
6.當第三數(c)大於極大值時,極大值即以c取代。
if c> max then
max:=c;
7.輸出極大值max。
自我練習
1.請輸入四個數,並求其最小值。
2.請輸入五個數,並求偶數的個數。
範例4-1e
請輸入兩個數,並將此二數交換後輸出
[演算法則]
1.輸入第一個數,本例以實數a儲存。
2.輸入第二個數,本例以實數b儲存。
3.設定暫存的實數t。
4.將實數a指定由實數t儲存。
t:=a
5.將實數b指定由實數a儲存。
a:=b
6.將實數t指定由實數b儲存。
b:=t
7.輸出a,b兩數,即為交換後的結果。
範例4-1f 請寫一個程式,
可以輸入三個數,並由小而大輸出
〔演算法則〕
1.分別以a、b及c表示欲排序的資料。
2.假如a大於b,則a與b交換
3.假如b大於c,則b與c交換
4.假如a大於b,則a與b交換,排序完成 並需進行3次的比較與交換
〔補充說明〕
1.以下是將資料交換寫成程序,關於程序的用法請看8-1節
2.若有4筆資料要排序,則共需進行6次比較與交換
3.若有5筆資料要排序,則共需進行10次比較與交換
4.以上為3,4或5筆資料的比較與排序,其比較與交換的次數尚可克服,但若欲排序的資料超過5個,例如20筆資料欲排序,則應待迴圈與陣列敘述介紹之後,才有較快速的解法。
自我練習
1.請寫一個程式,可以輸入4個數,並由小而大排序。
2.請寫一個程式,可以輸入5個數,並由大而小排序。
4-2 if..else
上一節的if僅適合單一分岐的決策,當條件成立時執行某一敘述,當條件未成立時,則未做任何處理。但在日常生活領域,常出現“假如~則~,否則~”,此種決策模式有兩種解決問題的
,故稱為雙向分岐決策,此時可使用if..else敘述,其敘述語法如下:
if 運算式 then
begin
敘述區塊1 ;
end;
else
begin
敘述區塊2 ;
end;
以上語法說明如下:
1.若敘述區塊內只有單一敘述,則begin與end可以予以省略,如下所示。請留意敘述1之後不用加分號(;),因為整個if敘述尚未結束。
if 運算式 then
敘述1
else
敘述2 ;
2.運算式的值若為True,則執行敘述區塊1;運算式的值若為False,則執行敘述區塊2
3.以下程式片段可依a的大小評量其及格與否。
if a>=60
b="及格"
else
b=“不及格”;
4.敘述區塊內可以放置任何合法敘述,當然也可以再放置if。if中有if,稱為巢狀if。
例如,以下敘述除可判斷a是否及格,更可判斷其是否優等。
if a>=60 then
begin
b='及格";
if a>=90 then
c:='優等';
end;
範例4-2a
同上範例,加上當成績小於60時,也要印出"不及格"。
本例是典型的雙向分岐決策,此時可用if…else實現程式的要求。
本例的if及else敘述區塊均只有一個敘述,所以begin與end可自行省略。
範例4-2b
請寫一個程式,完成以下要求:
輸入一個0~100的分數。
當分數大於90分時,輸出A。
當分數介於80~89分時,輸出B。
當分數介於70~79分時,輸出C。
當分數介於0~69分時,輸出D。
以上每一個決策點,都有兩個分岐點,所以適用if...else,每一個else後面均需再放置if作進一步決策。
範例4-2c
同上範例,但90分以上時,背景以黃色顯示;分數低於70分時,背景以紅色顯示
補充說明:
Delphi的語法是承繼Pascal,其是否加分號的規則表面上看起來比較亂,此點在後續的程式語言如C/C++、Java均已有改進。
自我練習
請寫一個程式,可以輸入(x,y)座標而得其所在象限。例如,輸入(3,4)輸出"Ⅰ";輸入(-5,2)輸出"Ⅱ"。
4-3 case
一個決策點若同時擁有三個或三個以上的解決方案,此稱為多向分岐決策。多向分岐決策雖也可使用範例4-2b的巢狀if ...else解決,但卻增加程式的複雜度、及降低程式可讀性。
若決策點能找到適當的運算式,能使問題同時找到分岐點,則可使用case敘述,其語法如下:
case 運算式 of
結果1 :
begin
敘述區塊1;
end;
[結果2 :
begin
敘述區塊2;
end;]
.
.
.
[else:
begin
敘述區塊n;
end;]
end ; //此處的分號代表一個case敘述的結束。
語法說明:
1. case的運算式必須可以得到一個序數(Ordinal)的型態,例如 整數3或字元'B'。
2. 每一個結果也必須是序數型態(整數或字元),但可以是連續 的序數,例如3、3..6、'B'或'B'..'E'等。
3. 程式將依運算式的結果,尋找適當的敘述區塊。
4. 以下敘述,可將所輸入的a值,轉為對應的星期幾。
case a of
0:
b:= '星期一';
1:
b:= '星期二';
2:
b:= '星期三';
3:
b:= '星期四';
end;
5.若沒有適當的“結果”可以執行,程式將會自動離開case敘述。
為了避免發生這種情況,可以在程式的最後面加上else,使得
即使沒有任何結果符合時,也可以執行else後面的敘述。例如,以下敘述,若使用者輸入的值不在0與6之間,則會顯示
“輸入錯誤”。
case a of
0:
b:= '星期一';
1:
b:= '星期二';
6:
b:= '星期日';
else
b:= '輸入錯誤';
end;
6. 敘述區塊內可放置任何合法的敘述,當然也可放置 switch或if
範例4-3a
試以case重作範例4-2b。
補充說明:
case敘述內的每一個結果,若要執行兩個以上的敘述時,則要使用begin與end圍起來、且要以分號(;)結束。
範例4-3b
請寫一個紅綠燈的模擬程式,其要求如下:
(1)當輸入是0,1,2,3,4時,輸出"綠燈"。
(2)當輸入是5,6,7,8,9,10時,輸出"綠閃"
(3)當輸入是11,12時,輸出"黃燈"。
(4)當輸入是13,14,15,16,17時,輸出"紅燈"
範例4-3c
同上範例,但改為每按一次按鈕,輸入值自動遞增,並輸出相對的燈號。
〔操作步驟〕
1.本例為使a值流通於各事件副程式,所以宣告於表單的變數宣告區,如以下敘述。
Var
Form1:TForm1;
a:integer;
2.交通號誌的三個燈號,本例使用三個shape(位於Additional標籤)元件。
其name屬性分別設為sppgreen,shpyellow及shpred,其shape屬性均點選stCircle,其Brush.color則分別點選clGreen,clYellow及clRed。
3.本例將"綠閃"再分為"綠減"與"燈燈",待下一範例即有綠閃的效果
範例4-3d
同上範例,但改為自動遞增輸入值。
〔操作步驟〕
1.本例新增一個Timer元件(位於System標籤),其Name屬性預設值為Timer1,並設定其interval屬性為1000(表示每1000ms自動產生一個OnTimer事件。)
2.將上例TForm1.btn startClick副程式的內容剪下,並貼至TForm1.Timer1副程式,如以下的程式列印。
3.關於Timer元件的詳細用法,請看12-12節。
4-4 綜合範例
一元二次方程式
解一元二次方程式的演算法如下:
1. 設有一元二次方程式如下:
ax2 + bx + c = 0
2. 若a = 0則應輸出“輸入錯誤”
3. 令d=b2-4ac
4. 若d = 0,則方程式有唯一解 ;
若d > 0,則方程式有二解: , ,
否則無實數解。
範例4-4a 請設計一個程式,
可以解一元二次方程式
1. 使用edia、edib及edic分別輸入方程式的三個係數a、 b及c。
2. 使用lblOut輸出結果。
程式說明:
1. Delphi並無次方與根號運算子,若欲使用次方或根號運算,則應使用intpower、power或sgrt等數學函式,且應於uses連結檔宣告區中,引用數學函式如下:
uses
Math;
2. intpower、power或sgrt等數學函式,計算結果均傳回實數的Extended型態,請特別留意資料型態的一致。
二元一次方程式
解二元一次方程式的演算法如下:
1. 設二元一次方程式如下:
1
2
2. 令 (表示d = a1b2 - a2b1)
3. 假如 則方程式無限多解,且程式結束
4.假如d = 0,則程式無解,且程式結束
5.
6.
範例4-4b
請設計一個程式,可以解二元一次方
程式。
三角形面積
若已知三角形三邊長,計算三角形三邊長的演算法下:
1. 輸入三角形三邊長a、b、c。
2. 將三邊長由小而大重新排列,最小的放入a,其次 放入b,最大的放入c。
3. 最小的兩邊之和若小於等於第三邊,則此三邊未 能構成三角形,程式提早離開。
4. 假如則為銳角三角形,否則,假如則為直角三角 形,否則此三角形為鈍角三角形。
5. 令
6. 三角形面積
範例4-4c
請輸入三角形三邊長,首先判斷是否構成三角形。
其次,判別三角形的種類,最後計算其面積。
程式說明:
1.設有a,b,c三數,欲由小而大排列,則其演算法如下:
a,b比較,若a>b,則兩者交換。
b,c比較,若b>c,則兩者交換,此時c一定最大。
a,b再比較,若a>b,則兩者交換,此時a一定最小。
共比較三次,即可由小而大排列。
2.假如有兩杯水a,b要交換,則其交換演算法如下:
先找一個空杯子t。
將a的水暫時倒入空杯子t(t := a)。
將b的水倒入a杯子(a := b)。
將t的水倒入b杯子(b := t),而完成兩杯水的交換。
如果未找來空杯子t,而直接將a倒入b,則原來b杯子的水就不見了。
3.本例使用power函式,要記得引用數學函式(uses Math)。
閏年 閏年的判斷
1.西元的閏年為每400年必須有97次閏年,其規劃方式如下:
(1) 4的倍數。依此條件共有100次。
(2) 於(1)的條件,扣掉100的倍數。依此條件,共有96次。
(3) 於(2)的條件,再加回400的倍數。所以共有97次。
2. 測試資料如下:
西元年分 性質 流程路線
3 平年 (1)
4 閏年 (2)
100 平年 (3)
200 平年 (3)
300 平年 (3)
400 閏年 (4)
600 平年 (3)
1200 閏年 (4)
2000 閏年 (4)
範例4-4d
閏年的判斷。
習題
1.試寫一程式由使用者輸入一數值,並由電腦判斷其為奇數或偶數
2.假設所得稅稅率法則如下:
淨所得30萬以下6%。
淨所得30~80萬之間13%。(前面的30萬仍扣6%,超過30萬的部分稅率為13%,不是全部都扣13%)
淨所得80~200萬之間21%。
淨所得超過200萬30%。
試寫一程式可以輸入淨所得,並計算應繳稅額。
例如淨所得若為40萬,則其納稅金額計算如下:
30×6% + 10×13% = 21000
(超過30萬的部份稅率為13%,不是全部40萬都是13%)
3.寫一程式輸入x值,並印出其所對應的值,其函數對應如下: x+3 x>3
x2 1<=x<=3
y=f(x)= x 0