局部变量保存先前执行的数据

时间:2012-03-17 07:54:39

标签: common-lisp clisp

使用下面的代码,即使(我相信)我只在每个函数中使用局部变量,运行多次后的结果看起来数据保留在变量中,最终添加旧的&新结果。有什么问题?

(defun funcC (target res)
  (cond
   ((null res) (list (list target 1)))
   ((equal (car (car res)) target)
    (setf (cadr (car res)) (+ (cadr (car res)) 1))
    res)
   (t (setf (cdr res) (funcC target (cdr res))) res)
  ))
(defun funcB (l res)
  (cond ((null l) nil)
    ((atom l) (funcC l res))
    ((atom (car l)) 
     (funcB (car l) res)
     (funcB (cdr l) res))
    ((listp (car l)) (funcB (car l) res))
    (t (funcB (cdr l) res)))
  res
)
(defun funcA (l)
  (cdr (funcB l '(())))
)

结果:

Break 27 [30]> lb
(10 7 7 7 4 3 7 3 10 10)
Break 27 [30]> (funcA lb)
((10 3) (7 4) (4 1) (3 2))   ; I want this result to repeat in the next run but...
Break 27 [30]> (funcA lb)
((10 6) (7 8) (4 2) (3 4))   
Break 27 [30]> (funcA lb)
((10 9) (7 12) (4 3) (3 6))  ; Each run adds up to results from previous run

环境:Ubuntu 11.10,GNU CLISP 2.49

1 个答案:

答案 0 :(得分:3)

这是一个经常被问到的问题。在stackoverflow上应该有这个问题的副本(原文如此!)。

您的funcA包含文字数据。此数据每次都传递到funcB并在那里进行修改。

您应该为每次运行制作该数据的新副本。使用COPY-TREE

另请注意,根据Common Lisp标准,修改文字数据可能会产生不确定的后果。想象一下,例如一个编译器将所有文字数据放在只读数据存储器段中,或想象一个编译器在几个地方重用类似的文字数据以节省空间。