Common Lisp入门笔记(三)条件和循环
摘自 《Lisp语言- 陈光喜》
一、条件
在Lisp中用原子t 表示真,nil表示假。 一般说来,函数名以字母 p 的 lisp 函数用于检验对象具有某种属性。例如,symbolp,listp,keywordp,boundp,fboundp,numberp,typep,oddp,evenp,zerop。
像这一类返回值为真或假的函数称为微词 predicate 。
1、typep 用于测试某个对象是否具有指定的类型。
如:> (typep 12 integer) > T
2、用于条件测试的函数包括 eq,,>,<,= 等等。逻辑联结词有 not,and,or 含义分别为非,且,或。
(1)Common Lisp 中最简单的条件操作符是 if,用法如下: (if test exp1 exp2)
如:> (if (listp (cons a nil)) (* 2 3) (* 3 3)) > 6
表达式 exp2 可以省略。但是如果此时 test 值为假,则整个表达式返回 nil。 > (if (> 3 2) (format nil " ~A > ~A" 3 2)) " 3 > 2" > (if (< 3 2) (format nil " ~A > ~A" 3 2)) NIL
需要注意的是,exp1和exp2都是单一表达式。如果需要使用多个表达式完成多个处理,可以使用progn。用法是:
(progn
exp21
exp2
...
exp2k)
它将这k个表达式组合成一个表达式。
二、循环
do 是最基本最重要的循环操作符。Do 与 let 类似,可以定义局部变量。标准用法如下: (do ((var1 init1 updt1) (var2 init2 updt2) …(varn initn updtn)) (endtest exp1 exp2 … expk) exps) 其中 var1,…,varn 是循环变量,init1,…,initn 是循环变量对应的初值表达式;updt1,…,updtn是变量每个循环步循环变量修改为的新值,允许省略,若该值省略,则对应循环变量不重新赋值;endtest 是循环终止的测试条件,若其值为 nil,循环继续进行,执行循环体 exps;否则,顺次执行结果语句组 exp1,…,expk,并返回 expk 的值,循环终止。
例1,计算1到10的平方:
CL-USER> (let ((b nil)) (do ((a 1 (+ a 1))) ((> a 10) b) (setf b (cons (* a a) b ))) ) (100 81 64 49 36 25 16 9 4 1)
对于表 list 中元素的循环处理,Common Lisp 提供了一种更简洁的循环方式。用法如下: (dolist (var list result) exps) 其中 var 是循环变量,它每个循环步顺次取 list 中的值。 result 是一个表达式,循环终止时将 result的值作为循环语句返回值。exps 为循环体。
例2,计算1到10的平方根之和:
CL-USER> (let ((b (1 2 3 4 5 6 7 8 9 10))(c 0) d) (dolist (v b c) (setf d (sqrt v)) (setf c (+ c d)))) 22.468277
例3,计算1到10之和:
CL-USER>(let ((a (1 2 3 4 5 6 7 8 9 10))(b 0)) (dolist (v a b) (setf b (+ v b)))) 55