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