條件式控制流

for-in迴圈的特性是可以重複性的做一樣的指令,在我們確定知道某個指令要做幾次,或者要做的次數存放在某個常數或變數裡的時候,for-in迴圈是很好的選擇,但在不清楚某個指令有可能做幾次的情況下,使用這種迴圈的程式碼就比較難撰寫了。

考慮一個問題:假設我們正在寫一個模擬營運類型的遊戲,在我們的架構中,有一個整數變數coins:Int,用來存放玩家目前有多少金幣,現在要為商店加入一個功能,在玩家購買某個價值為整數變數price:Int的商品時,可以選擇只買一次,或者連續購買直到金幣不夠用為止,由於事先不知道玩家在進入商店時有多少錢,也不知道商品多貴,我們目前學過的所有指令和for-in迴圈的組合,是很難寫出程式碼的。

接著我們介紹的第二種迴圈,就非常適合這種情況,它叫做while迴圈。

while 條件 {
    // 程式碼
}

while迴圈會檢查條件是否成立,當條件成立的時候,執行{}包裹的程式碼一次,執行完後再次檢查條件是不是仍然成立,在條件成立的情況下,電腦會不斷的重複{}包裹的程式碼,直到某次檢查時條件不成立為止,迴圈結束。

這時候大家就開始頭痛了,條件是什麼東西?

我們先介紹第五種基礎型態:Bool,這是一種邏輯類型,它只有可能是true(真)或false(假)。

let 檸檬不酸:Bool = false
let 教主很帥:Bool = true

let 這個算式正確嗎:Bool = (2 > 1) // 其值為 true,因為電腦認為2確實大於1

我們命令電腦計算像是(2 > 1)這樣的式子時,回傳的就會是一個Bool,如果電腦認為式子正確,就會回傳true,否則會回傳false。關於這種「條件式計算式」,將在下一小節做更詳細的說明,現在先讓我們開始想像一下,怎麼利用條件判斷來完成文章開頭敘述的購買功能。

var coins:Int 
var price:Int
// ...
// 玩家進行了一段時間的遊戲,可能得到一定數量的金幣...
coins = 1500   // 假定目前玩家擁有 1500 金幣
price = 135    // 這可能是從某個商店的功能得到的商品價格,假定要價 135 金幣

while (coins >= price) {  // 條件:當玩家所持金幣大於物品價格...
    coins = coins - price // 將玩家所持金幣扣掉物品的價錢,完成花費購買動作
    // ...
    // 撰寫將商品增加至玩家的物品欄之類的程式碼
    // ...
    print("玩家成功購買了 xxx 商品!")
}
print("玩家現在剩下", coins, "金幣")

執行這段程式碼,將會列印出 11 次玩家成功購買了商品的訊息,直到剩下 15 金幣時,while迴圈內的式子變成false(此時這個比較式子的內容是15 >= 135,其值當然為false),玩家無法繼續購買商品,迴圈結束,並且電腦也會正確的印出玩家剩餘的金幣。

教學進行到這邊,貪玩的你或許會突發奇想地想做一些嘗試...

while (true) {
    print("電腦,你給我列印到地球毀滅!")
}

和你想的一樣,電腦將會忠實地將這個迴圈的內容永無止盡的執行下去,因為每次執行完一圈進行檢查時,電腦得到的永遠都是true,最後依照裝置平台的不同,有可能發生當機、記憶體耗盡、Runtime Error等等不同的悲慘結局。這種迴圈稱為「無窮迴圈」,是程式設計師必須去極力避免的,發生時不僅是很差的使用者體驗(因為裝置通常會發生嚴重的延遲),也不是正確的電腦使用方式。

最後介紹另一種while迴圈的型態,repeat-while,這是一種比較少使用的型態,電腦將會立即執行{}包裹的程式碼一次,之後才判斷while後面的條件,如果是true就回頭繼續執行,如果是false就結束迴圈。因此即使while後面的條件式子一開始就是false,迴圈仍然會恰好執行一次。

repeat {
    // 程式碼
} while 條件

思考看看,什麼時候會使用到repeat-while

results matching ""

    No results matching ""