字符打印两次以上(通用Lisp)

字符打印两次以上(通用Lisp),lisp,common-lisp,Lisp,Common Lisp,我正试图打印出一个基于条件语句的字符 (defvar enctext) (defun encrypt(enctext) (if (eq 'A (first enctext)) (princ 'H))) 这是我用来执行函数的 (load "lisptest.lisp") ;; Loading file lisptest.lisp ... ** - Continuable Error DEFUN/DEFMACRO(ENCRYPT): #<PACKAGE POS

我正试图打印出一个基于条件语句的字符

(defvar enctext)

   (defun encrypt(enctext) 
     (if (eq 'A (first enctext))
      (princ 'H)))
这是我用来执行函数的

(load "lisptest.lisp")
;; Loading file lisptest.lisp ...
** - Continuable Error
DEFUN/DEFMACRO(ENCRYPT): #<PACKAGE POSIX> is locked
If you continue (by typing 'continue'): Ignore the lock and proceed
The following restarts are also available:
SKIP           :R1      skip (DEFUN ENCRYPT # ...)
RETRY          :R2      retry (DEFUN ENCRYPT # ...)
STOP           :R3      stop loading file         /home/students/cante008/cs351/lisptest.lisp
ABORT          :R4      Abort main loop
Break 1 [2]> continue
WARNING: DEFUN/DEFMACRO: redefining function ENCRYPT in
     /home/students/cante008/cs351/lisptest.lisp, was defined in C
 ;; Loaded file lisptest.lisp
T
[3]> (setf x '(A))
(A)
[4]> (encrypt x)
H
H
(加载“lisptest.lisp”)
;; 正在加载文件lisptest.lisp。。。
**-连续误差
DEFUN/DEFMACRO(加密):#已锁定
如果继续(通过键入“继续”):忽略锁并继续
以下重新启动也可用:
跳过:R1跳过(取消加密#…)
重试:R2重试(取消加密#…)
停止:R3停止加载文件/home/students/cante008/cs351/lisptest.lisp
中止:R4中止主循环
中断1[2]>继续
警告:DEFUN/DEFMACRO:在中重新定义函数ENCRYPT
/home/students/cante008/cs351/lisptest.lisp在C中定义
;; 加载的文件lisptest.lisp
T
[3] >(setf x'(A))
(A)
[4] >(加密x)
H
H
最后,角色“H”打印了两次,我不知道为什么


这是执行Caesar密码的第一步,因为您使用的是REPL,所以会打印每个表达式的值

(encrypt x)
的值(在本例中)最终是
(princ'H)
的值,即
H

另外,
(princ'H)
打印
H


这与您在计算
(setf x'(A))
后看到
(A)
时使用REPL的原因相同,因此会打印每个表达式的值

(encrypt x)
的值(在本例中)最终是
(princ'H)
的值,即
H

另外,
(princ'H)
打印
H

这与您在计算
(setf x'(A))

一个字符

当你写像
'A
'H
这样的东西时,你不是在处理字符,而是在处理符号。字符是这样写的:
\A
\Space
。要比较字符是否相等,请使用

[…]打印两次[…]

Lisp中的大多数函数都返回(至少)一个值。当您在REPL(read evaluate print循环)上调用函数时,正如“REPL”中的“P”所示,调用该函数的返回值将被打印出来。函数的返回值要么是
NIL
(如果未使用
if
),要么是
princ
返回的任何值。看看这本书,我们可以知道:

princ对象和可选输出流
=>
对象

这可以理解为
princ
接受一个必需的参数(要打印的某个对象)和一个可选参数(要打印的流),并且返回一个对象,该对象(尽管我找不到显式写入的对象)与传递给它的对象相同

因此,第一个
H
来自
princ
,第二个来自自动打印返回值的REPL

最后一句话:您对
defvar
的使用可能表明了对Common Lisp中变量的误解:
defvar
声明了(粗略等效)其他语言中的“全局”变量。函数参数或传递参数不需要它

一个字符

当你写像
'A
'H
这样的东西时,你不是在处理字符,而是在处理符号。字符是这样写的:
\A
\Space
。要比较字符是否相等,请使用

[…]打印两次[…]

Lisp中的大多数函数都返回(至少)一个值。当您在REPL(read evaluate print循环)上调用函数时,正如“REPL”中的“P”所示,调用该函数的返回值将被打印出来。函数的返回值要么是
NIL
(如果未使用
if
),要么是
princ
返回的任何值。看看这本书,我们可以知道:

princ对象和可选输出流
=>
对象

这可以理解为
princ
接受一个必需的参数(要打印的某个对象)和一个可选参数(要打印的流),并且返回一个对象,该对象(尽管我找不到显式写入的对象)与传递给它的对象相同

因此,第一个
H
来自
princ
,第二个来自自动打印返回值的REPL


最后一句话:您对
defvar
的使用可能表明了对Common Lisp中变量的误解:
defvar
声明了(粗略等效)其他语言中的“全局”变量。函数参数或传递参数不需要它。

您没有真正测试它

CL-USER 3 > (defun test ()
              (encrypt '(a))
              (encrypt '(a))
              (encrypt '(a))
              'lalala)
TEST

CL-USER 4 > (test)
HHH
LALALA

CL-USER 5 > (defun test1 ()
              (test)
              (test)
              (test)
              'mmmmmm)
TEST1

CL-USER 6 > (test1)
HHHHHHHHH
MMMMMM

你没有真正测试它

CL-USER 3 > (defun test ()
              (encrypt '(a))
              (encrypt '(a))
              (encrypt '(a))
              'lalala)
TEST

CL-USER 4 > (test)
HHH
LALALA

CL-USER 5 > (defun test1 ()
              (test)
              (test)
              (test)
              'mmmmmm)
TEST1

CL-USER 6 > (test1)
HHHHHHHHH
MMMMMM

吹毛求疵:您可以用
(值)
返回零值,即使这没有什么区别。@coredump谢谢。我几乎知道我写这篇文章的时候错了,但是我想不起
(值)
:尽管在大多数上下文中,返回
(值)
的结果与返回
nil
是无法区分的。挑剔:你可以用
(值)
返回零值,尽管没什么区别,谢谢。我几乎知道写这篇文章的时候我错了,但是我想不起
(值)
:尽管在大多数上下文中,返回
(值)
的结果与返回
nil
是无法区分的。