QBasic/子程式和函式
子程式和函式是將程式碼分解成可重複使用的“塊”的方法。它們允許程式設計師透過呼叫適當的過程或函式來重複使用一組常見的指令。
例如,假設你需要列印多個值表。一種方法是直接在需要它們的地方輸入所有表列印命令。但是,這不僅會使程式非常大,還會使除錯或更改表的“樣式”更加困難。更簡單的方法是建立一個“打印表”過程,並在其中輸入所有列印命令。然後,每次需要打印表時,只需使用要列印的值列表“呼叫”“打印表”過程即可。
過程執行某項操作,不向程式設計師返回任何內容。例如,過程可以用於設定螢幕模式和調色盤。
函式執行某項操作並返回一個值。例如,如果需要找到兩個值的平均值,可以編寫一個函式,該函式接受兩個數字並返回平均值。
GOTO 和 GOSUB 語句是建立子程式的最初方法。它們在較舊的 Basic 實現中最為常見,並出於相容性原因保留下來;但是,在其他程式語言或大型專案中不建議使用它們,因為 GOTO 使跟蹤程式流程變得更加困難,並且 GOSUB 不會“隔離”對任何變數的更改。
這兩個命令依賴於標籤,標籤有兩種形式。第一種也是較舊的形式是在每行開頭寫入行號(通常以 10 為增量)。較新的方法與其他程式語言類似,即一個單詞後跟一個冒號。
GOTO 語句很簡單;它只是將執行點移動到給定的標籤。
GOSUB 語句將控制權轉移到給定的標籤,但是當遇到 RETURN 語句時,執行將返回到 GOSUB 語句後面的行。對 GOSUB 中進行的任何更改都將是對“主”程式碼中使用的實際變數的更改。
ON ERROR 允許你為程式定義錯誤處理程式;當發生錯誤時,它立即跳轉到給定的標籤。當程式到達 RESUME 語句時,控制權返回,RESUME 語句可以將控制權返回到同一位置、下一條語句或任何其他所需的標籤。
在 Qbasic 中,錯誤處理程式不能位於任何子程式中。因此,任何錯誤檢查或標誌都必須透過使用與主模組共享的變數來處理。
注意:如果你的錯誤處理例程中沒有“resume”語句(即你嘗試使用 gotos 完成所有操作),錯誤處理只會起作用一次 - 下一個“on error”將被忽略,程式將結束,就像你沒有“on error”語句一樣。這個問題似乎在任何文件中都沒有提到。我花了三個小時才弄清楚為什麼兩個幾乎相同的程式部分的行為如此不同。
宣告子程式的更好方法是使用 SUB 語句塊,因為(預設情況下)在退出時將丟棄子程式中使用的任何新變數。
在 QBasic IDE 中,這樣做會將 SUB 塊移動到它自己的視窗中,以防止意外刪除模組,並允許更容易地組織程式程式碼。
呼叫子程式就像編寫子程式的名稱(傳遞任何必需的引數)一樣簡單。如果你願意,可以使用 CALL 語句來指示其他程式設計師它是一個子程式。
SUB name (params)
{SHARED variables 'if any}
'{code to execute}
' ...
' ...
{STATIC variables 'if any, to be saved for use next time}
END SUB
雖然傳遞給子程式的引數是按“引用”傳遞的(即它們在 SUB 中採用新的名稱),但對值進行的任何更改都將“反映回”原始值。預設情況下,在到達 END SUB 時(或執行 EXIT SUB 時)將丟棄 SUB 中使用的所有其他變數,除了以下情況:-
要“保留”SUB 中使用的變數的值以在下次呼叫時重新使用,請在末尾使用 STATIC 關鍵字。
如果需要訪問變數(沒有作為引數傳遞),請使用 SHARED 關鍵字在子程式開始時定義每個變數(共享變數保留其名稱)。
函式是返回值的子程式形式。定義子程式中適用的所有內容也適用於函式。在函式中,返回值是透過將函式名用作變數來建立的 - 當到達有效的退出或結束呼叫時,返回值將傳遞給呼叫表示式。有兩種方法可以從函式返回,一種方法是到達 END FUNCTION 語句,另一種方法是呼叫 EXIT FUNCTION。END FUNCTION 和 EXIT FUNCTION 之間的區別在於,只能有一個 END FUNCTION,它必須出現在函式的所有其他程式碼之後,因為它表示程式碼塊的結束。EXIT FUNCTION 可以多次出現,可以放置在任何認為合適的地方。
FUNCTION name (params)
' Shared variable declarations
name = result
' ...
END FUNCTION
函式的宣告方式與變數相同 - 它返回定義為返回的變數型別,與定義變數包含其指定型別的方式相同。預設情況下,它是一個數字,但附加一個美元符號表示它返回一個字串。
函式只能在表示式中呼叫;與子程式不同,它們不是獨立的語句。