函数调用栈溢出

Function call stack overflow

我在 运行 我的代码中收到以下错误消息。下面的代码添加了不为零的元素。

(summit2 '(0 nil 1 2))

Error: Received signal number -3 (function call stack overflow (delayed response))
[condition type: ASYNCHRONOUS-OPERATING-SYSTEM-SIGNAL]

我试过把null改成nil。我还尝试使用 eq 而不是 eql。

(defun summit2 (lst)
    (if (eql (car lst) null)
        (summit2 (cdr lst))
      (+ (car lst) (summit2 (cdr lst)))))

预期的输出应该是3,即列表中不为nil的元素之和

首先,nil 的检查应该使用 NULL 函数来完成,因此在您的情况下是 (null (car lst))。其次,你的递归缺少基本情况(你得到的错误表明由于无限递归导致堆栈溢出)。现在你只区分下一个元素是nil还是非nil。您需要第三种情况来处理空列表。这建议使用 COND。例如,您可以执行以下操作:

(defun summit2 (lst)
  (cond 
    ((null lst)
     0)
    ((null (car lst))
     (summit2 (cdr lst)))
    (t
     (+ (car lst) (summit2 (cdr lst))))))

一些评论

  • 您可以拼写您的列表 list,无需将其缩写为 lst
  • 您代码中的所有分支都会导致对 summit 的递归调用,您不会停止计算结果。这种无限计算会占用堆栈 space,这就是它最终因堆栈溢出而停止的原因。
  • 请以常规方式缩进您的代码(阅读示例 this style guide

请注意,元素为 nil 的情况与输入列表为空的情况没有太大区别。使用以下代码,两者的处理方式相同:

(defun sum (val)
  (if (consp val)
      (+ (sum (car val))
         (sum (cdr val)))
      (or val 0)))

这也意味着代码能够做的比预期的多,即您可以对树中的数字求和:

(sum '(0 1 2 nil 4 5 7 (1 2)))
=> 22

当输入只是一个数字时它也有效:

(sum 5)
=> 5