我想通过自学来学习clisp。但完全混淆了如何处理变量。下面给出一个递归函数“mul”,用于乘以两个整数(+或 - )并用适当的符号得到结果。 “mul”使用另一个递归函数“sum”。clisp中funcall的arg变化值
(defun sum (n1 n2)
"Returns the sum of two integers"
(assert
(and (numberp n1) (integerp n1))
(n1)
"N1 must be an integer,instead it's ~S"
n1)
(assert
(and (numberp n2) (integerp n2))
(n2)
"N2 must be an integer,instead it's ~S"
n2)
(cond ((zerop n1) n2)
((< n1 0) (sum (1+ n1) (1- n2)))
((> n1 0) (sum (1- n1) (1+ n2)))))
(defun mul (n1 n2)
"Returns the product of two integers"
(assert
(and (numberp n1) (integerp n1))
(n1)
"N1 must be an integer,instead it's ~S"
n1)
(assert
(and (numberp n2) (integerp n2))
(n2)
"N2 must be an integer,instead it's ~S"
n2)
(let* ((s (if (zerop n1) 0
(sum n2 (mul (if (< n1 0) (1+ n1) (1- n1)) n2))))(r s))
(if (or (and (> n1 0) (> n2 0)) (and (> n1 0) (< n2 0))) r
(if (or (and (< n1 0) (> n2 0)) (and (< n1 0) (< n2 0))) (- r) 0))))
当我运行
(MUL 4 4)或(MUL -3 4)
我得到正确与正确符号的结果。但
(MUL 3 -4)或(MUL -3 -4)
给出错误的-4和4分别结果。看起来else语句会在成功调用mul期间将n2的值更改为负值。有人可以解释我做错了什么,“-r”如何使n2消极。 在此先感谢。
下面是N1的不同值的跟踪和n2
MATCH> (mul 3 4)
1. Trace: (MUL '3 '4)
2. Trace: (SUM '4 '0)
2. Trace: SUM ==> 4
2. Trace: (SUM '4 '4)
2. Trace: SUM ==> 8
2. Trace: (SUM '4 '8)
2. Trace: SUM ==> 12
1. Trace: MUL ==> 12
12
MATCH> (mul 3 -4)
1. Trace: (MUL '3 '-4)
2. Trace: (SUM '-4 '0)
2. Trace: SUM ==> -4
2. Trace: (SUM '-4 '-4)
2. Trace: SUM ==> -8
2. Trace: (SUM '-4 '-8)
2. Trace: SUM ==> -12
1. Trace: MUL ==> -12
-12
MATCH> (mul -3 4)
1. Trace: (MUL '-3 '4)
2. Trace: (SUM '4 '0)
2. Trace: SUM ==> 4
2. Trace: (SUM '4 '-4)
2. Trace: SUM ==> 0
2. Trace: (SUM '4 '0)
2. Trace: SUM ==> 4
1. Trace: MUL ==> -4
-4
MATCH> (mul -3 -4)
1. Trace: (MUL '-3 '-4)
2. Trace: (SUM '-4 '0)
2. Trace: SUM ==> -4
2. Trace: (SUM '-4 '4)
2. Trace: SUM ==> 0
2. Trace: (SUM '-4 '0)
2. Trace: SUM ==> -4
1. Trace: MUL ==> 4
4
可以看出,只要N1是正MUL给出正确的结果。当n1为负值并且执行“else call”时会出现问题 - 然后调用n2变化的符号来求和。是因为(-r)吗?如果是的话为什么会发生?我的理解是,n2,s和r是三个单独的变量,r的值不应该改变n2。我对么 ? 如果不是,我会感激,如果有人向我解释他们的关系。我可能不会像usepa指出的那样使用这个复杂的代码,但这个解释对我理解lisp变量有很大的帮助。 在此先感谢。
你试过跟踪你的代码吗?既然你使用全局定义的递归函数,你可以简单地评估'(trace sum)'和'(trace mul)',然后当你调用时,例如'(mul 3 -4)',你会看到所有的调用'mul'和'sum',你应该能够识别出现错误的地方。 – 2014-10-07 12:59:37
是的。以下是(-3 4)和(3 -4)MATCH>(mul -3 4)的两条曲线:1. Trace:(MUL'-3'4) 2. Trace:(SUM'4'0) 2.跟踪:SUM ==> 4 2。Trace:(SUM'4'-4) 2. Trace:SUM ==> 0 2. Trace:(SUM'4'0) 2. Trace:SUM ==> 4 1. Trace:MUL == > -4 -4 MATCH>(mul 3 -4) 1.追踪:(MUL'3'-4) 2.追踪:(SUM'-4'0) 2.追踪:SUM ==> -4 2.跟踪:(SUM'-4'-4) 2.跟踪:SUM ==> -8 2.跟踪:(SUM'-4'-8) 2.跟踪:SUM ==> -12 1.跟踪:MUL ==> -12 -12 MATCH> – kkp 2014-10-08 04:50:54
由于所有缩进都丢失,所以在注释中无法读取。使用问题下的**编辑**按钮并将信息添加到您的问题。 – 2014-10-08 11:13:35