写一个遍历质数的程序
(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) 为真
中止循环