【Lua 筆記】迴圈 - part 4
【Lua 筆記】迴圈 - part 4
由於有款遊戲叫做 CSO(Counter-Strike Online),內建模式創世者模式(Studio)新增使用 Lua 及其遊戲的 API,所以突發奇想製作這個筆記。
這個筆記會在一開始先著重純粹的程式設計自學,在最後的章節才會與 CSO 遊戲 API 進行應用。
迴圈(loop)
迴圈即一個循環。
很多時候我們會需要重複執行一個動作,以生活舉例,像是平時上廁所(無論小便、大便)會是一個迴圈,因為這是我們不斷持續在做的事情。又或者是在長跑時,跑了好幾圈操場,這也是一種迴圈。
回到正題,Lua 共支援以下幾種迴圈語法:
- while
- for
- repeat…until
- break
- goto
while、for 一定是每個程式語言基本配備,接下來讓我們先來看看 while 迴圈:
while 迴圈
while 是一種具有條件判斷的迴圈,格式如下:
1 | while (condition) do |
當 condition 這個條件成立,也就是 condition = true 的時候,迴圈才會執行。
至於執行什麼內容呢?執行 statements 裡面的內容。如果裡面都沒有設定可以讓條件變成 false 的機制,則會形成一個無窮迴圈,就會一直循環下去。
condition 可以是任意的運算式。
1 | a = 10 |
輸出結果:
1 | The value of a is: 10 |
可以看到上面的程式碼當中,當 a < 20 它才會執行 while 裡面的內容,然後裡面有設定不斷累加的機制,使條件變成 false 後才能離開迴圈。
無限迴圈
無限迴圈即意味著一個迴圈指令判斷永遠都是 true。
1 | while (true) do |
輸出結果:
1 | Hi |
備註:按下 ctrl + C 在終端上表示中斷執行結果。
for 迴圈
for 迴圈的機制宛如等差數列,而以下是它的格式:
1 | for var=exp1,exp2,exp3 do |
這有點像 C 語言的寫法:
1 | for (i; i < 10; i++){ |
不過如果沒學過 C 語言的話,可以不用鳥這個東西。
exp1,是作為 var 的初始值,這邊要注意的是 var 是個變數,你想怎麼叫它都行,不過通常我們會用 i 來表示。
i 即 iteration,表示迭代,也就是重複的意思。
exp2,表示從 exp1 這個數值開始,要重複到 exp2 這個數值。
exp3,表示在當 exp1 重複到 exp2 的過程中,每次增加的數值,預設為 1,也可以不加 exp3。
看了這個解釋,如果你還是霧煞煞的話,我們來看個範例:
1 | for i=1,10 do |
輸出結果:
1 | 1 |
for 就是個等差數列,上面程式碼的意思就是從 1,遞增 1 直到 10 結束。
使用 while 迴圈可以這樣表達:
1 | i = 1 |
接下來我們來做個範例,從 2x1 ~ 2x10 的程式碼:
1 | for i = 1, 10 do |
輸出結果:
1 | 2 |
repeat…until
for 和 while 迴圈的條件語句在目前迴圈執行開始時判斷,而 repeat…until 迴圈的條件語句在目前迴圈結束後判斷。
語法格式:
1 | repeat |
什麼意思?來看例子就知道(Lua repeat…until 循环 | 菜鸟教程):
1 | a = 10 |
輸出結果:
1 | a is : 10 |
欸?如果我們改用 while 迴圈寫的話會怎樣?我們一樣來試試看:
1 | a = 10 |
輸出結果:
1 | a is : 10 |
其實 Lua 語言的設計都很直觀,像是 repeat … until,「重複直到」。以上面例子就是,a 不斷 + 1 直到 a > 15。
而前面所述 for、while 迴圈的判斷都在迴圈執行時就馬上判斷了,也可以從上面例子看出來。
程式語言連結:repeat … until 其實像是 C 的 do … while。
break 語句
break 語句相當於打斷的意思,打斷什麼呢?打斷一個迴圈,所以它的功用就是能夠在迴圈途中打斷執行。
我們來做個範例:
1 | for i=1,10 do |
輸出結果:
1 | 1 |
可以發現原本迴圈要遞增至 10 才會結束,而使用判斷式判斷如果 i == 5,執行 break 語句,使整體迴圈馬上結束,接著繼續執行後續的程式碼。
goto 語句
goto 語句是筆者認為 Lua 當中數一數二特別的語法,因為它能將控制流程無條件地轉到被標記的語句處。
什麼意思呢?待會解釋。
首先它的語法格式長這樣:
1 | goto Label |
Label 的格式:
1 | :: Label :: |
這個標籤後面可以放上要執行的程式碼,像是下面這個例子:
1 | ::Label:: print("Hello") |
輸出結果:
1 | Hello |
再來做這個例子(Lua goto 语句 | 菜鸟教程):
1 | a = 1 |
輸出結果:
1 | --- goto label --- |
為什麼會輸出兩次?這是你我都會疑惑的問題,別忘了 goto 被執行時會「跳轉」到標籤的語句處,也就是程式碼將會在 ::label:: print("--- goto label ---") 這邊開始重複執行,這就是 goto 神奇的地方了。
最後,我們做完這個例子就放學了(Lua goto 语句 | 菜鸟教程):
1 | for i=1, 3 do |
輸出結果:
1 | 1 yes continue |
因為 lua 當中沒有 continue 這個語句,但是我們可以透過 goto 來還原,同樣能達到 continue 的效果,只是稍嫌麻煩而已。
備註:[[i’m end]] 的原來寫法格式為 [[…]],為什麼要這樣寫?因為原本寫 print(“i’m end”) 是會發生錯誤的,因為一個字串裡面只能有兩個成對的單雙引號,而用這個兩個中括號的格式寫,就能夠容許有引號或任何字元的出現。
字元:”一個”中文字、符號、英文字母等等都稱為字元。
字串:一串字元的結合體。
另外,標籤不一定只能夠設定單一條程式碼而已,如下範例(Lua goto 语句 | 菜鸟教程):
1 | i = 0 |
輸出結果:
1 | 0 |
總結
迴圈就是一個循環,一個 circle。
Lua 共支援以下幾種迴圈語法:
- while
- for
- repeat…until
- break
- goto
while 是一個有條件判斷的迴圈:
1 | while (condition) do |
無限迴圈即意味著一個迴圈指令判斷永遠都是 true。
1 | while (true) do |
for 迴圈的格式:
1 | for var=exp1,exp2,exp3 do |
exp1 -> 初始值
exp2 -> 到哪個值停下
exp3 -> 等差數列的公差
repeat … until 語法格式:
1 | repeat |
break -> 用於中斷迴圈執行的指令。
goto -> 能夠透過自定義的標籤,並且移轉到該標籤的地方,從此開始執行。
最後小提醒,雖然本篇沒有講到巢狀迴圈,但其實概念都是相同的,在這邊就不再贅述,備註:巢狀迴圈比巢狀條件判斷還重要哦。
參考資料
【30天Lua重拾筆記15】基礎2: Label and Goto - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
Day7 開機學習 Lua - 條件判斷與迴圈控制 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天



