我想通過自學來學習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