位元詩人 [Common Lisp] 程式設計教學:宣告和使用變數 (Variable)

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

前言

在電腦程式中,資料存在於記憶體。變數本身不是資料,而是資料的標籤。電腦程式藉由變數存取資料。本文介紹在 Common Lisp 中使用變數的方式。

宣告全域變數 (Global Variable)

雖然 Common Lisp 是函數式語言,必要時還是可以使用全域變數來控制程式的狀態。使用 defvar 可宣告變數。

以下範例宣告全域變數 *v*,其值為 5.0

(defvar *v* 5.0)

注意變數 *v** (星號,asterisk) 也是變數的一部分。Common Lisp 對識別字 (identifier) 的建立規則比一般程式語言還寬鬆,詳見下文。

依照慣例,在 Common Lisp 中建立全域變數時,會在變數中加上一對 * 符號。雖然這沒有強制性,這是一種常見的風格。這種寫法讓別的 Common Lisp 一看就知道該變數是全域變數。

如果要更動變數的值,可以用 setq 指令。承上,我們修改全琙變數 *v* 的值:

(setq *v* 7.0)

在 Common Lisp 中,有數個內建的全域變數,用來調整程式的設置。像是 *load-verbose* 變數可用來控制載入 Lisp 命令稿時,是否要輸出文字訊息。

宣告局部變數 (Local Variable)

比起全域變數,寫 Common Lisp 程式時更常使用局部變數。局部變數對程式的影響僅限於特定指令所在處,不太會因不當修改造成 bug。

當我們需要局部變數,但不需要從該區域回傳值時,可以用 prog 指令。參考以下範例:

(prog ((x 3))
  (write-line (princ-to-string x)))

相對來說,當我們需要從區域回傳值時,則會改用 let 指令。參考以下範例:

(let ((x 3)
      (y 4))
  (+ x y))

宣告常數 (Constant)

當我們希望變數的值在整個程式中固定不變時,可以用 defconstant 指令宣告常數,這時候 Common Lisp 編譯器會協助程式設計者檢查該變數是否有被修改到,並發出錯誤訊息。

例如,圓周率歐拉數的值是固定不變的,就很適合宣告成常數。以下程式碼片段宣告歐拉數 (Euler's number):

(defconstant e 2.7182818284 "The base of natural logarithm")

Common Lisp 的識別字 (Identifier) 建立規則

在程式語言中,識別字是有特定意義的符號。除了程式語言內建的識別字外,程式設計者可藉由多種指令建立新的識別字。識別字可能代表變數、運算子、函式、類別、巨集等。Lisp 家族語言不嚴格區分運算子、函式、巨集等語法,比 Algol 家族語言 (註) 自由得多。

(註) 即 C 家族語言。

Common Lisp 的識別字的規則比其他程式語言寬鬆得多,其規則如下:

  • 不是數字
  • 不是套件名稱 (package marker) (註)
  • 不全由 . (dot) 組成

(註) 以 : 開頭的符號,如 :cl

實務上,大多數識別字會以小寫英文字母和 - (hyphen) 組成。雖然 Common Lisp 不區分大小寫,以小寫英文字母撰寫程式碼比較容易閱讀。

以下是一些例子:

  • amount:單一字
  • circle-area:複合字
  • integer-or-null-p:複合字,(慣例上) 用來命名 predicate
  • 1+:非數字
  • +:非文字符號
關於作者

身為資訊領域碩士,位元詩人 (ByteBard) 認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

位元詩人喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,位元詩人將所學寫成文章,放在這個網站上和大家分享。