1. 程式人生 > >Lisp語言:迴圈控制

Lisp語言:迴圈控制

瞭解了Lisp語言的條件判斷,讓我們看看Lisp語言的迴圈控制。對於稍有程式設計經驗的人來說,迴圈是比較容易理解的,一般語言裡面的迴圈無外乎for迴圈,while迴圈,do until迴圈等,有些語言的迴圈稍微複雜一點,也不過是一些變化形式。而Lisp語言裡的迴圈卻不是這麼簡單,查詢Lisp中loop的使用就可以發現一系列的資料,有關於loop的簡單使用的,有關於loop的高階使用的,仔細看起來會覺得學習loop的使用都像是在學習一門語言,而不是某中語言的一個關鍵字。究其根源,loop其實是一個巨集,是Lisp自我擴充套件的結果。有關於巨集的深入瞭解不是短短一篇文章可以完成的,也不是本文的目的,這裡暫時不作討論。

在不討論巨集的情況下,我們可以用一種簡單的方法來學習Lisp中的迴圈,就是列出一些常用的,容易理解的loop迴圈,直接當標準語法記住,就如同我們記住其它語言的for迴圈一樣。

Lisp中的for迴圈使用樣例如下:

(defun looptest1 ()
        (loop for i from 1 to 10  do
                (format *query-io* "*"))
)
上面迴圈語句的作用類似於c語言的for (i=1 ;i < = 10 ;i++)。


執行的結果是迴圈輸出*號。



Lisp中還用一種常用的loop迴圈是遍歷一個列表,樣例如下:

(defun looptest2 ()
        (setq i-list '(a b c d e f g))
        (loop for i in i-list  do
                (format *query-io* "~a  " i))
)


上面的Lisp語句設定變數i-list的值為列表(a b c d e f g),注意列表前面的單引號',這個符號表明後面的列表不要進行計算,這樣這個列表才能保持原樣賦予變數i-list。否則執行時Clisp會嘗試執行( a b c d e f g),認為a是一個函式,就會報錯。

然後loop迴圈會遍歷i-list這個列表,將i-list列表中的每一個值賦予變數i,然後進入迴圈體,以上語句會依次輸出“ A  B  C  D  E  ”

以上兩種loop迴圈都是由Lisp語言來控制迴圈的,開發人員不需要考慮步長,迴圈條件等因素,只需要考慮迴圈體內完成的工作就可以了。

下面兩種迴圈稍微麻煩一點,需要開發人員控制迴圈條件,就像平時我們使用while迴圈和do until迴圈一樣,需要在迴圈體內修改變數,使迴圈條件在某種情況下不滿足,從而退出迴圈。

下面的迴圈是while迴圈,迴圈條件是i 小於10,在迴圈體內對i進行累加,當i大於等於10的時候就會退出迴圈:

(defun looptest3 ()
        (setq i 1)
        (loop while (< i 10) do
                (format *query-io* "*")
                (setq i (+ i 1)))
)

而下面這種是do until迴圈,迴圈一直執行直到i大於10,同樣在迴圈體內對i進行累加,使i最終滿足大於10的條件:

(defun looptest4 ()
        (setq i 1)
        (loop until (> i 10) do
                (format *query-io* "*")
                (setq i (+ i 1)))
)

下面是程式執行過程的截圖,列出上面4個方法呼叫的結果。

細心的讀者可以數一數其中的星號個數,想一想為什麼幾個方法輸出的星號個數會不同。