一、畫正方形
如果想要寫程式控制小貓,畫出如附圖的正方形,並且將這段程式製作成函式,請問該如何設計程式呢?
上圖的正方形是由四個等長的邊所組成,所以只要控制小貓畫出一條線段並且轉彎90度準備畫下一條線段,接著再重複以上步驟3次(連同第1次總共4 次),就可以畫出正方形。
提示(1)
畫一個正方形的程式片段如下:
提示(2)
接著將這段程式包裝成新的函式積木方塊,請由函式積木分類中找到【建立一個積木】,自訂函式積木名稱為「正方形」。
提示(3)
系統自動產生一個函式積木的定義起始點,請在起始點之下接著設計畫正方形的程式內容。同時在函式積木分類裡面,也會多了一個正方形的函式積木。
撰寫程式
若要畫一個紅色及一個黃色的正方形,我們可以呼叫「正方形」函式積木2次,並在呼叫函式前設定畫筆顏色。
當程式執行到呼叫「正方形」函式積木時,控制權會轉移到實際定義「正方形」的程式去執行。
執行完畢後,會再回到原先的呼叫點的下一行程式,繼續執行下去。
左邊的程式區塊也可稱為主程式,右邊的函式則可以稱為副程式。
進階練習(1)
右圖是畫正三角形的程式碼,請將這段程式包裝成函式積木方塊,命名為正三角形。接著撰寫一段主程式呼叫函式畫出正三角形。
進階練習(1)-答案
進階練習(2)
右圖是畫正五邊形的程式碼,請將這段程式包裝成函式積木方塊,命名為正五邊形。接著撰寫一段主程式呼叫函式畫出正五邊形。
進階練習(2) -答案
二、有參數的函式
問題說明
前一單元,我們學會如何設計一個畫正方形的函數,並且用主程式呼叫它。但若要畫出不同大小的正方形,例如:邊長10 的正方形,邊長50的正方形,以及邊長100 的正方形,就得要分別設計單獨的函數。
接著在主程式內分別呼叫這些函式,才能畫出三個不同大小的正方形。
但是這三個函式幾乎是一樣的,只有移動距離不同,有沒有什麼方法可以簡化程式呢?
提示
若要解決這個問題,可以在函式增加輸入參數,利用輸入參數控制邊長。
提示(1)
滑鼠右鍵點選函式積木【正方形】,點選編輯。
提示(2)
點選【添加輸入方塊】,增加一個輸入參數,命名為「邊長」。
提示(3)
原本定義正方形函式積木的起始處,多了一個「邊長」參數,請直接拖拉到函式內邊長的位置,取代原本的常數,如此這個函式積木,就能依照當時傳入的「邊長」參數,畫出指定邊長的正方形。
撰寫程式
紅色路徑代表第一次呼叫函式積木的執行流程。
藍色、綠色路徑分別代表第二次、第三次的執行流程。
最後畫完的圖形:
進階練習(1)
請修改正三角形函式積木的程式碼,增加一個邊長參數,並且畫出如附圖(非實際大小)三個正三角形(邊長分別是10、50、100)。
進階練習(1)-答案
進階練習(2)
請修改正五邊形函式積木的程式碼,增加一個邊長參數,並且畫出如附圖(非實際大小)三個正五邊形(邊長分別是10、50、100)。
進階練習(2) -答案
進階練習(3)
請修改正方形函式積木的程式碼,再增加兩個座標參數X、Y,分別代表下筆的座標位置。
接著撰寫如右圖的主程式,呼叫4次正方形函式,在指定的座標位置上畫出四個邊長等於5的小正方形。
畫出來的結果如對圖。
進階練習(3)-答案
進階練習(1)
請設計一個函式積木【正多邊形】,附帶三個參數「邊長」、「邊數」、「角度」,可以根據參數畫出指定邊數的正多邊形。
例如:若要畫三角形,可以呼叫函式積木
例如:若要畫正方形,可以呼叫函式積木
例如:若要畫正五邊形,可以呼叫函式積木
進階練習(1)-答案
進階練習(2)
第一題練習需要輸入三個參數「邊長」、「邊數」、「 角度」,再想想看能否只用兩個參數「邊長」、「邊數」,達成一樣的效果呢?
進階練習(2) -答案
三、自訂函式-計算BMI
還記得七年級提到的身體質量指數(BMI)嗎?BMI 是用來衡量肥胖程度的指標,計算公式如下:
當時練習寫過計算BMI 的程式:
程式執行後看到的結果:
請將以上計算BMI 程式改寫成函式,只要輸入身高、體重兩個參數,就能夠計算出BMI 值。
參考程式
問題說明
以下是10 位同學的身高與體重資料,請建立身高陣列、體重陣列以及BMI 陣列,接著使用「計算BMI」函式,分別算出這10 位同學的BMI 值,存放到BMI 陣列內。
提示
想想看,輸入資料是什麼?輸出結果是什麼?
該如何將身高、體重資料從陣列內取出後,計算出BMI 值再存放回BMI 陣列內?
請回憶第1-1-2 節「利用重複結構快速存取陣列內容」的方法:
執行步驟流程圖
撰寫程式
請先宣告需要使用到的變數、陣列,並且匯入預先輸入好的資料檔案「身高.txt、體重.txt」。
詳細程式如下圖,左方是主程式,右方是【計算BMI】函式。
主程式內先準備索引變數(初值是1),隨著迴圈重複執行10 次,索引變數也逐次遞增1,這樣就可藉由索引變數取出資料陣列的每個元素,接著呼叫函式計算得到BMI 值,最後將結果存放到陣列內即可。
四、自訂函式-交換陣列元素
假設有甲、乙兩個杯子,裡面分別存放紅色、橘色果汁,若要將這兩個杯子內的果汁交換,請問該怎麼做?
作法是多準備一個空杯子(可稱為暫存杯),然後將甲杯子內的紅色果汁先倒進暫存杯內,清空甲杯。
接著將乙杯的橘色果汁倒入甲杯,清空乙杯。
最後再將暫存杯內的紅色果汁倒回乙杯內。
這樣就完成交換。
問題說明
如果我們想要交換陣列內任意兩個元素的內容,該怎麼做呢?要如何用函式來寫這段程式呢?
交換陣列內任意兩個元素的方法,就如同交換杯子內的果汁程序,陣列元素就如同是杯子,裡面存放的數值就是果汁,交換時需要額外準備一個暫存變數(暫存杯),並且按照交換果汁的步驟進行。
撰寫程式(1)
假設有一個資料陣列有五個元素,存放的內容如下圖。
若想要將其中第1元素(內容是5)與第4元素(內容是2)互相交換,必須宣告一個暫存變數,並且撰寫程式片段如下:
撰寫程式(2)
如果要交換第2元素與第5元素,則要撰寫類似的程式片段:
撰寫程式(3)
比較以上這兩段交換資料的程式碼的異同處,重新改寫為函式積木,此函式附帶「參數1」、「參數2」兩個參數,用來指明要交換陣列元素的索引值。
撰寫程式(4)
之後若要交換第1元素與第4元素(或是交換第2元素與第5元素),就可以直接呼叫函式:
撰寫程式(5)
完整程式:
五、使用函式隨機擺放資料
問題說明
班上有30 名同學,若要隨機重排全班的座號順序,作為擔任值日生的順序,該如何解決這個問題呢?
提示
這個問題就是要將陣列內原本依序擺放的資料:
重新亂擺
如果任意選取陣列內的兩個元素,再將這兩個元素對調,接著不斷前述步驟,那麼陣列內資料就會愈來愈亂,慢慢地就能達成目的。
接下來問題就是要怎麼選取陣列內的兩個元素?
如果希望每個元素都要被交換過,可設計一個迴圈,依序拜訪每個元素,並且隨機任選另一個元素互相交換,如此可確保每個元素都會被交換至少一次以上。
假設已經設計好【交換陣列元素】函式,想想看該怎麼使用這個函式,將陣列內的元素順序弄亂?請將你的程式流程圖畫出來。
參考流程圖:
撰寫程式(1)
初步想法是準備一個陣列,包含30個元素依序存放1,2,3⋯⋯30號碼,接著再隨機對調這些號碼的順序,這樣就可以達成隨機重排座號的效果。
撰寫程式(2)
接著寫一個迴圈,依序巡視每個元素,同時隨機挑選另一個元素交換資料內容。
撰寫程式(3)
程式執行後,由右圖結果可見資料陣列內的數值完全被打亂,而且每個座號只會出現一次。
撰寫程式(4)
接著再宣告一個結果變數,利用迴圈把資料陣列內的每個元素,都串接到結果字串,最後將結果字串顯示在舞台區,這樣就解決這個問題了。
程式片段如下圖:
進階練習
樂透開獎方式是在1 ∼ 49 號內任選7 個不重複的號碼當作中獎號碼,請寫一個程式,能夠自動產生7 個不重複的號碼,模擬中獎號碼。
(提示:直接以亂數選取不重複的號碼,已在單元1-2-6 介紹過了,所以此處請使用陣列、交換函式來解決此問題。)
進階練習-答案
六、使用函式重排資料
問題說明
前一個練習是將資料陣列打亂,如果要讓陣列內的元素恢復次序(不論是由小到大,或是由大到小),這就是資料排序。
想想看如何利用【交換陣列元素】函式,撰寫程式將陣列內的元素由小到大排序完畢?
提示
前一個練習是隨機取得索引值,無條件交換陣列元素達成攪亂的目的。
但是若從陣列第一個元素開始,依序取出連續兩個元素值來比較大小,依照比較結果交換元素值讓較大值放在後面,慢慢的就能將大的數值移動到陣列的最末端。
提示(1)
從陣列前端開始(索引變數指向第一個元素),依序比較陣列相鄰兩個元素(例如4、6這兩筆資料,按照規則:[較小值放左邊,較大值放右邊]調整資料所在位置,因為4小於6,所以這兩筆資料擺的位置是正確的)。
提示(2)
接著將索引變數指向第二個元素,比較相鄰兩個資料(也就是6與3),將較大的元素放在框中右邊的位置,因為6大於3,所以要交換6與3的位置。
提示(3)
如此不斷重複以上步驟,直到索引移動到陣列倒數第二元素,此時索引是陣列長度-1,剛好陣列全部元素都檢視一遍。
參考流程圖:
撰寫程式(1)
請執行以下程式一次,觀察程式執行完畢後,最末項是否存放最大值。
撰寫程式(2)
接著再執行第二次,會發現程式將次大值移動至倒數第二個元素。請同學們多執行幾次程式,觀察陣列最末端元素內數值的變化。
顯然每執行一次程式,就可以將較大值的資料往陣列末端移動。例如右圖就是執行四次後,最後的四個元素內容就是最大的四個數值(27,28,29, 30)。
撰寫程式(3)
如果要將陣列內30個數值全部排列完畢,請問應該要執行幾次程式?
答案是29次(也就是陣列長度-1次)。
原因是執行到第29次時,已經將29個數值全部放到正確的位置,最後一個數值自然也會在正確位置,所以只要執行29次就好了。