书籍下载地址:
Ansi Common Lisp 中文版|百度网盘
实用Common.Lisp编程 .pdf|百度网盘
LISP指令速查网站推荐:
Simplified Common Lisp reference (jtra.cz)
我制作的表格:
由于Common LISP命令很多,经常忘,所以做个这个表格,方便速查。
表格中命令的顺序基本为ANSI Common LISP这本书中命令出现的顺序。
命令含义例子T真NIL假+-*/加减乘除> (+ 2 3 4)
9>和</tdtd 大于和小于/tdtd> (> 2 1)
TCHAR字符比较**全局变量需要左右加上星号> (setf *print-array* t)
TZEROP为0时返回真CHARACTERP是否为字符/=不相等=判断相等(建议到这个网站查看具体解释)。仅能判断数字。> (= 4 4.0)
TEQ是否完全相同。内容相同但是内存位置不同也为不同。不用于数字。> (eq (cons 'a 'b) (cons 'a 'b))
NIL
> (eq 'a 'a)
TEQL与EQ相似。可以比较数字。EQUAL是否内容相同。内存位置可以不同。字符串大小写敏感> (equal (list 1 (cons 2 3)) (list 1 (cons 2 (+ 2 1))))
TEQUALP字符串大小写不敏感AND OR NOT逻辑与、或、非ODDP是否为奇数EVENP是否为偶数QUOTE(`)不求值> `(+ 1 2)
(+ 1 2)CONS构建一个长度为2的列表
(但第二个输入值可以是一个列表)> (cons 'a '(b c d))
(A B C D)CONSP判断是否为CONSLIST构建一个列表CAR获取列表第一个元素CDR获取列表第二个以及
之后的元素构成的列表THIRD获取列表第三个元素LISP判断输入是否为列表NULL判断是否为空表或NILIFIFDEFUN声明全局函数(defun our-third (x)
(car (cdr (cdr x))))
调用时:(our-third (1 2 3))(DEFUN的参数列表&rest剩余的参数。会被包装为列表。(defun our-funcall (fn &rest args)
(apply fn args))&optional可选参数(defun philosoph (thing &optional (property 'fun))
(list thing 'is property))&key关键字参数> (defun keylist (a &key x y z)
(list a x y z))
KEYLIST
> (keylist 1 :y 2)
(1 NIL 2 NIL))EQL相等判断FORMAT输出> (format t "~A plus ~A equals ~A. ~%" 2 3 (+ 2 3))
2 PLUS 3 EQUALS 5
NIL~A数据输出的位置,相当于C语言的%d~%换行符READ输入> let ((val (read))LET定义局部变量> (let ((x 1) (y 2))
(+ x y))
3DEFPARAMETER创建全局变量(变量需要加星号)> (defparameter *glob* 99)DEFCONSTANT定义全局常量(不需要星号)BOUNDP判断是否为全局变量或常量> (boundp '*glob*)
TSETF赋值(给全局或局部变量),可以创建全局变量INCF自加。相当于c的++REMOVE返回不包含这个对象的新列表,但不改变原列表> (setf lst '(c a r a t))
(C A R A T)
> (remove 'a lst)
(C R T)DELETEREMOVE的破坏性版本。但不能保证所需移除的元素都能移除。> (setf lst '(a r a b i a) )
(A R A B I A)
> (delete 'a lst )
(R B I)
> lst
(A R B I)DO循环
(DO (变量定义)
(结束条件 返回值)
循环主体)
其中变量定义为(变量名 变量初值 (变量变化语句))(defun show-squares (start end)
(do ((i start (+ i 1)))
((> i end) 'done)
(format t "~A A%" i (* i i))))DOTIMES循环次数(dotimes (x 5 x)
(format t "~A " x))
0 1 2 3 4
5;; 第一行第二个x是返回值,可以不加LOOP循环宏> (loop for x from 0 to 9
do (princ x))
0123456789
NIL
> (loop for x = 8 then (/ x 2)
until (< x 1)
do (princ x))
8421
NIL(defun sumx (n)
(loop for x from 1 to n
sum x));;返回从1加到n的结果> (loop for x from 1 to 5
collect (random 10))
(3 8 6 5 0)(defun even/odd (ns)
(loop for n in ns
if (evenp n)
collect n into evens
else collect n into odds
finally (return (values evens odds))))
> (even/odd '(1 2 3 4))
(2 4)
(1 3)PROGN接受任意数量的表达式,依序对它们求值,并返回最后一个值。DOLISTfor each...> (dolist (obj lst) 相当于C++的for(auto obj:lst){,相当于Python的for obj in lst:FUNCTION(#')把函数当做实参传入APPLY接受函数和实参列表,并返回把传入函数应用在后面实参的结果> (apply #'+ '(1 2 3))
6FUNCALL功能和APPLY相同,但实参不需要包装成列表。> (funcall #'+ 1 2 3)
6LAMBDALambda表达式(lambda (x y)
(+ x y))
> (funcall #'(lambda (x) (+ x 100)) 1)TYPEP判断是否为某种类型> (typep 27 'integer)
TCOPY-LIST返回列表的复制ATOM验证一个项是否为原子(即列表的一个项)APPEND返回列表串接> (append '(a b) '(c d) 'e)
(A B C D E)NCONC返回列表串接并更新第一个列表的最后一个 cons 单元的 next 指针。> (let ((l1 (list 1 2 3))
(l2 (list 4 5 6)))
(nconc l1 l2)
l1)
(1 2 3 4 5 6)NTH通过索引获取列表元素> (nth 0 '(a b c))
ANTHCDR找到第n个CDR> (nthcdr `(a b c d e))
(C D E)LAST返回列表最后一个CONS对象> (last '(a b c))
(C)LAST的CAR返回列表的最后一个元素> (car (last '(a b c)))
CSECOND返回第二个元素CADR返回第二个元素(相当于CDR的CAR)CADDR返回第三个元素(相当于CDR的CDR的CAR)可以无限加D。MAPCAR返回把函数应用到列表每个元素的结果> (mapcar #'(lambda (x) (+ x 10))
'(1 2 3))
(11 12 13)
MAPCAN类似MAPCAR。但它返回值是用NCONC拼接在一起的。MAPC把函数应用到列表每个元素,返回原来的列表MAP把函数应用到列表每个元素,可定义返回的类型。(map 'list (lambda (x) (+ x 10)) '(1 2 3 4))
(11 12 13 14)MAP-INTO把函数应用到列表每个元素,第一个参数不是一个序列类型,而是用来存储结果的。> (let ((a (list 1 2 3 4))) (map-into a #'* a a) a)
(1 4 9 16)
还可以:(setf v (map-into v #'1+ v))MAPLIST将列表的渐进的下一个 CDR传入函数> (maplist #'(lambda (x) x) '(a b c))
((A B C) (B C) (C))MEMBER判断元素是否为列表的成员。可以传入参数:TEST和:KEY> (member 'b '(a b c))
(B C)
> (member '(a) '((a) (z)) :test #'equal)
((A) (Z))
> (member 'a '((a b) (c d)) :key #'car)
((A B) (C D)) ;;在这个例子里,我们询问是否有一个元素的CAR是 aMEMBER-IF返回由满足条件的元素构成的列表> (member-if #'oddp '(2 3 4))
(3 4)ADJOIN如果对象还不是列表的,成员,构建对象至列表上> (adjoin 'b '(a b c))
(A B C)
> (adjoin 'z '(a b c))
(Z A B C)UNION并集INTERSECTION交集SET-DIFFERENCE补集> (set-difference '(a b c d e) '(b e))
(A C D)LENGTH返回元素的数目SUBSEQ获取列表的一部分,相当于其他语言的Slice> (subseq '(a b c d) 1 2)
(B)
>(subseq '(a b c d) 1)
(B C D)REVERSE列表反转NREVERSE使原列表反转?EVERY判断列表每个元素都满足条件> (every #'oddp '(1 3 5))
TSOME判断列表部分元素满足条件> (some #'evenp '(1 2 3))
TPUSH把元素插入列表的前端POP移除列表的第一个元素,并返回这个元素ASSOC返回列表中CAR为指定元素的列表> (setf min '((a b c) (b c) (c d)))
> (cdr (assoc 'a min))
(B C)MAKE-ARRAY构造数组> (setf arr (make-array '(2 3) :initial-element nil)) ;;构造了一个2x3的数组AREF通过索引获取数组元素> (setf (aref arr 0 0) 'b)
B>
(aref arr 0 0)
B#na表示字面常量的数组,其中n是数组的维度#2a((b nil nil) (nil nil nil))VECTOR向量> (vector "a" 'b 3)VECTOR-PUSH把元素插入向量的前端VECTOR-POP移除向量的第一个元素,并返回这个元素SVREF通过索引获取向量元素SORT字符串排序> (sort "elbow" #'char (concatenate 'string "not " "to worry")
"not to worry"TAILP如果第一个列表是第二个列表的一部分,则返回TELT通过索引获取任何种类的序列元素。针对特定类型的序列,特定的存取函数会比较快,所以使用 elt 是没有意义的,除非在代码当中,有需要支持通用序列的地方。POSITION返回序列中一个元素的位置,未找到元素时返回 nil。参数:start :end :test> (position #\a "fantasia")
1>
(position #\a "fantasia" :start 3 :end 5)
4
> (position 3 '(1 0 7 5) :test #' (position-if #'oddp '(2 3 4 5))
1FIND返回要寻找的对象> (find #\a "cat")
#\aFIND-IF返回要寻找的满足函数的对象> (find-if #'characterp "ham")
#\hREMOVE-DUPLICATES仅保留序列中每个元素的最后一次出现。REDUCE把序列压缩成一个值(reduce #'fn '(a b c d))等同于(fn (fn (fn 'a 'b) 'c) 'd)DEFSTRUCT定义结构体(defstruct point
x
y)MAKE-HASH-TABL创建哈希表,无需参数。> (setf ht (make-hash-table))GETHASH获取一个键值> (setf (gethash 'color ht) 'red)
REDREMHASH从一个哈希表中移除一个词条,若返回T,说明有词条被移除BLOCK块RETURN-FROM返回块> (block head
(format t "Here we go.")
(return-from head 'idea)
(format t "We'll never see this."))
Here we go.
IDEARETURN返回TAGBODYGO相当于其他语言的goto。需要在TAGBODY下使用> (tagbody
(setf x 0)
top
(setf x (+ x 1))
(format t "~A " x)
(if (< x 10) (go top)))
1 2 3 4 5 6 7 8 9 10
NILLET*相当于嵌套版本的LET,可以依赖一个表达式设立另一个变量。可以把x设为1,同时把y设为x+1.原版LET就不行。WHEN当测试为真时,对主体求值UNLESS仅在测试表达式返回假时,才对主体求值CASE相当于C语言的switch(defun month-length (mon)
(case mon
((jan mar may jul aug oct dec) 31)
((apr jun sept nov) 30)
(feb (if (leap-year) 29 28))
(otherwise "unknown month")))TYPECASE按照类型来switch(TYPECASE X
(NUMBER (* X 2)))VALUES返回多个值MULTIPLE-VALUE-BIND绑定多个值。如果变量的数量大于数值的数量,剩余的变量会是 nil 。如果数值的数量大於变量的数量,多余的值会被舍弃。CATCH捕获异常(defun super ()
(catch 'abort
(sub)
(format t "We'll never see this.")))
(defun sub ()
(throw 'abort 99))
> (super)
99THROW抛出异常ERROR抛出异常文字(ERROR "Oops!")UNWIND-PROTECT使程序不会被报错打断(UNWIND-PROTECTFBOUNDP是否有函数与给定符号绑定> (fboundp '+)
TSYMBOL-FUNCTION返回函数。可用于给函数配置某个名字。(setf (symbol-function 'add2)
#'(lambda (x) (+ x 2)))
> (add2 1)
3DOCUMENTATION获取函数的文档字串> (DOCUMENTATION #'+ 'function)
"sum of its arguments. With no args, returns 0."LABELS声明局部函数。用法与DEFUN一样。COND直到某个条件为真时才返回> (cond ((> 3 4) "variant 1")
((> 4 2) "variant 2")
(t "always valid variant"))
"variant 2"DECLARE(SPECIAL x)使x为动态作用域(详见ANSI COMMON LISP 76页)COMPILED-FUNCTION-P检查函数是否已被编译COMPILE编译函数COMPILE-FILE编译文件MAKE-PATHNAME新建一个路径。参数有host, device, directory, name, type 以及 version> (setf path (make-pathname :name "myfile"))OPEN打开文件流。需要一个路径和大量选择性关键字参数。> (setf str (open path :direction :output :if-exists :supercede)) ;;supercede表示取代。output表示写文件。input表示读文件。CLOSE关闭文件READ-LINE从文件流中读一行。若不指定文件流,则从标准输入中读一行,相当于READ。WITH-OPEN-FILE相当于Python的with,不需要close,保证文件能够关闭。(with-open-file (str path :direction :output
:if-exists :supercede)
(format str "Something~%"));;向文件写入Something\nPRIN1输出包含双引号。给程序产生输出。PRINC输出不包含双引号。给人类产生输出。SYMBOL-NAME获取符号名> (symbol-name 'abc)
"ABC"垂直杠之间的字符序列将被视为符号。SYMBOL-PLIST获取符号的属性列表(PLIST)> (setf (get 'alizarin 'color) 'red)
RED
> (get 'alizarin 'color)
RED
> (setf (get 'alizarin 'transparency) 'high)
HIGH
> (symbol-plist 'alizarin)
(TRANSPARENCY HIGH COLOR RED)DEFPACKAGE定义包(defpackage "MY-APPLICATION"
(:use "COMMON-LISP" "MY-UTILITIES")
(:nicknames "APP")
(:export "WIN" "LOSE" "DRAW"))
(in-package my-application)
这段代码定义了新包my-application,使用了两个包,COMMON-LISP和MY-UTILITIES,一个昵称为APP,这样背的包可以这样引用符号APP:WIN。包本身只输出三个符号"WIN"、"LOSE"和"DRAW"。IN-PACKAGE包结尾FLOAT将任何实数转换为浮点数TRUNCATE返回任何实数的整数部分FLOOR返回小于等于参数的最大整数CEILING返回大于等于参数的最小整数ROUND返回最接近参数的整数> (mapcar #'round '(-2.5 -1.5 1.5 2.5))
(-2 -2 2 2);;不做五入,而是取最近的偶数RANDOM接受一个整数或浮点数。返回一个小于n的数字SIGNUM返回参数的符号。可以返回-1,0或1FLOAT转换为浮点数> (/ 365 12)
365/12;;比值
> (float 365/12)
30.416666EXPT(expt x n) = x^nLOG(log x n) = \(\log_{n}x\), 若缺省n,则n默认为eEXP(exp x) = e^xSQRT平方根SIN、COS、TAN三角函数ASIN、ACOS、ATAN反三角函数SINH、COSH、TANH双曲函数ASINH、ACOSH、ATANH反双曲函数PI常数πshort-float短浮点、single-float单精度浮点、double-float双精度浮点、long-float长浮点MOST-POSITIVE-FIXNUM最大整数、MOST-NAGATIVE-FIXNUM最小整数(不同实现下不同)EVAL与Python的eval功能相同。可把列表视作代码> (eval '(+ 1 2 3))
6DEFMACRO声明宏(defmacro nil! (x)
(list 'setf x nil))
也可定义为:
(defmacro nil! (x)
`(setf ,x nil))
> (nil! x)
NIL
> x
NILMACROEXPAND-1展开宏(用于测试)> (macropexpand-1 '(nil! x))
(SETF X NIL)
T,在反引号表达式中重启求值> (setf a 1 b 2)
2>
> `(a is ,a and b is ,b)
(A IS 1 AND B IS 2),@与逗号相似,但将其(本来应该是列表的)参数扒开。> (setf lst '(a b c))
(A B C)
> `(lst is ,lst)
(LST IS (A B C))
> `(its elements are ,@lst)
(ITS ELEMENTS ARE A B C)GENSYM自由符号。保证宏定义的变量不会与外面的变量重名。(defmacro ntimes (n &rest body)
(let ((g (gensym))
(h (gensym)))
`(let ((,h ,n))
(do ((,g 0 (+ ,g 1)))
((>= ,g ,h))
,@body))))DEFCLASS声明类(defclass circle ()
(radius center));;这说明类circle的实例包含两个槽,分别名为radius和center.MAKE-INSTANCE创建类的实例> (setf c (make-instance 'circle))SLOT-VALUE槽的值> (setf (slot-value c 'radius) 1)(槽的属性:accessor、:writer、:reader可读写、可写、可读(defclass circle ()
((radius :accessor circle-radius)
(center :accessor circle-center)))
> (setf c (make-instance 'circle))
#
> (setf (circle-radius c) 1)
1
> (circle-radius c)
1:initarg定义参数名:initform定义缺省值(defclass circle ()
((radius :accessor circle-radius
:initarg :radius
:initform 1)
(center :accessor circle-center
:initarg :center
:initform (cons 0 0))))
> (setf c (make-instance 'circle :radius 3))
#
> (circle-radius c)
3
> (circle-center c)
(0 . 0):acclocation :class定义类变量(defclass tabloid ()
((top-story :accessor tabloid-story
:allocation :class)))
> (setf daily-blab (make-instance 'tabloid)
unsolicited-mail (make-instance 'tabloid))
#
> (setf (tabloid-story daily-blab) 'adultery-of-senator)
ADULTERY-OF-SENATOR
> (tabloid-story unsolicited-mail)
ADULTERY-OF-SENATOR)DEFMETHOD定义方法。支持重载,甚至可以对单一的对象做特化。(defmethod combine ((x number) (y number))
(+ x y)
(defmethod combine ((x (eql 'powder)) (y (eql 'spark)))
'boom):before :after :around标准方法组合机制(standard method combination)规定,调用一个函数会调用:around方法,如果有的话;否则,依序调用:before方法、主方法、:after方法DECLARE、DECLAIM声明(局部、全局)。DECLARE(OPTIMIZE (SPEED 3) (SAFTEY 0))编译参数。speed 0~3。3最快。作用在函数里。(declaim (optimize (speed 3)
(compilation-speed 0)
(safety 0)
(debug 0)));;这块代码让所有代码在任何情况下都尽可能更快。(DECLAIM(INLINE x))使函数x为内联函数。能提高运行速度。递归函数不能内联。(declaim (inline single?))
(defun single? (lst)
(and (consp lst) (null (cdr lst))))(DECLAIM (FIXNUM x))声明x为定长数(整数)。(defun poly (a b x)
(declare (fixnum a b x))
(+ (* a (expt x 2)) (* b x)))(declare (type (vector fixnum 20) v));; 声明了一个仅含有定长数,企鹅长度固定为20的向量。(常见函数及其破坏性版本安全破坏性appendnconcreversenreverseremovedeleteremove-ifdelete-ifremove-duplicatesdelete-duplicatessubstnsubstsubst-ifnsubst-ifunionnunionintersectionnintersectionset-differencenset-difference)DEFTYPE定义类型标识符(deftype multiple-of (n)
`(and integer (satisfies (lambda (x)
(zerop (mod x ,n))))))
> (type 12 '(multiple-of 4))
T;;定义了4的倍数的标识符PACKAGE-NAME返回包的名字FIND-PACKAGE返回一个给定名称的包> (find-package "COMMON-LISP-USER")
#SYMBOL-PACKAGE接受一个符号并返回该符号被 interned 的包EXPORT使符号对其他包可视(可用单冒号访问,不可视时只能用双冒号访问)IMPORT导入包USE-PACKAGE使用包TRACE追踪函数,用于调试,可在每次函数调用时显示输入的参数UNTRACE取消追踪函数
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |