寫一個遍曆質數的程式
(defun primep (number) (when (> number 1) (loop for fac from 2 to (isqrt number) never (zerop (mod number fac)))))(defun next-prime (number) (loop for n from number when (primep n) return n))
說明:
primep:判斷一個數是否為的質數
next-prime:計算下一個大於或等於實參的質數
執行代碼中使用Do迴圈:
CL-USER> (do ((p (next-prime 0) (next-prime (1+ p)))) ((> p 16)) (format t "~a~t" p))2 3 5 7 11 13 NIL
主要解析Do迴圈代碼
(do ((p (next-prime 0) (next-prime (1+ p))))
((> p 16))
(format t "~a~t" p))
2 3 5 7 11 13
理解
(p (next-prime 0) (next-prime (1+ p))
語義
p 相當於for(i=0;i<10;i++)中的變數i
(next-prime 0) 相當於i的初始值0
(next-prime (1+ p)) 相當於i++ 不過它不只是每次迴圈後加1,而是每次迴圈後先加1,然後再將P+1的值傳到 (next-prime)函數中,從 (next-prime)中返回下一個質數的值作為下次迴圈初始值。
程式執行流程如下
第一次迴圈:
(next-prime 0)先求值 為2
(do ((p (next-prime 0) (next-prime (1+ p))))
變為
(do ((p 2 (next-prime (1+ p))))
判斷 ((> p 16) 為假
執行 (format t "~a~t" p)) 輸出2
第二次迴圈:
迴圈之前通過(next-prime (1+ p))計算出下次執行迴圈時p的值為3
(do ((p (next-prime 0) (next-prime (1+ p))))
變為
(do ((p 3 (next-prime (1+ p))))
判斷 ((> p 16) 為假
執行 (format t "~a~t" p)) 輸出 3
第三次迴圈:
迴圈之前通過(next-prime (1+ p))計算出下次執行迴圈時p的值為5
(do ((p (next-prime 0) (next-prime (1+ p))))
變為
(do ((p 5 (next-prime (1+ p))))
判斷 ((> p 16) 為假
執行 (format t "~a~t" p)) 輸出 5
第四次迴圈:
迴圈之前通過(next-prime (1+ p))計算出下次執行迴圈時p的值為7
(do ((p (next-prime 0) (next-prime (1+ p))))
變為
(do ((p 7 (next-prime (1+ p))))
判斷 ((> p 16) 為假
執行 (format t "~a~t" p)) 輸出 7
第五次迴圈:
迴圈之前通過(next-prime (1+ p))計算出下次執行迴圈時p的值為11
(do ((p (next-prime 0) (next-prime (1+ p))))
變為
(do ((p 11 (next-prime (1+ p))))
判斷 ((> p 16) 為假
執行 (format t "~a~t" p)) 輸出 11
第六次迴圈:
迴圈之前通過(next-prime (1+ p))計算出下次執行迴圈時p的值為13
(do ((p (next-prime 0) (next-prime (1+ p))))
變為
(do ((p 13 (next-prime (1+ p))))
判斷 ((> p 16) 為假
執行 (format t "~a~t" p)) 輸出 13
第七次迴圈:
迴圈之前通過(next-prime (1+ p))計算出下次執行迴圈時p的值為17
(do ((p (next-prime 0) (next-prime (1+ p))))
變為
(do ((p 17 (next-prime (1+ p))))
判斷 ((> p 16) 為真
中止迴圈