如何修复 Lisp 中的堆栈溢出错误
How to fix a stack overflow error in Lisp
我这里有一个代码,它试图获得低于给定数字的所有素数的总和。当我 运行 它时,我不断收到堆栈溢出错误,仅此而已,我似乎找不到哪里出错了。
(format t "Enter your number ~%")
;global variables
(defvar *number* (read))
(defvar *conditional-check* nil)
(defvar *prime* nil)
;sum-of-primes function
(defun sum-of-primes (x)
(defvar sum 0)
(primeCheck x 2)
(if (equal *prime* 'yes)
(progn
(setf sum (+ sum x))
(setf z (- x 1))
(conditional z)
(if (equal *conditional-check* 'yes) (sum-of-primes z) ()))
(and (setf z (- x 1)) (sum-of-primes z)))
)
;conitional function
(defun conditional (z)
(if (>= z 1) (setf *conditional-check* 'yes) (setf *conditional-check* 'no))
)
;prime number check
(defun primeCheck (*number* y)
(if (and (>= *number* y) (not (= (mod *number* y) 0)))
(progn
(setf z (+ y 1))
(primeCheck *number* z)
(setf *prime* 'yes))
(setf *prime* 'no))
)
;function call
(sum-of-primes *number*)
Whosebug 表示称为堆栈的内存部分已达到其限制。澄清一下,在堆栈上存储了函数调用。现在,如果存储函数调用的内存部分达到了它的限制,那就意味着发生了太多的函数调用。这通常意味着无限递归。想象一个只调用自身的函数。现在,如果您调用该函数,那么该调用将存储在堆栈中。但是,该函数调用自身,并且第二个调用也存储在堆栈中。而第二次调用是第三次调用该函数,入栈等。
递归的这种错误使用可以通过查看代码的特定区域来解决,在这些区域中函数本身被调用,或者更广泛地说,如果函数已经在堆栈中,但是又被调用了。
这是您需要的理解,以便找到解决当前问题的方法并避免将来出现类似问题。
sum-of-primes
缺少一些 基本条件 ,这会结束递归调用。这是主要问题,但是您的代码非常混乱并且包含许多无用的全局变量。您应该避免使用全局变量并使用局部变量(由 let 或函数调用创建)。对于这个例子,你根本不需要任何全局变量。
(defun sum-of-primes (num)
(sum-of-primes-help 0 num))
(defun sum-of-primes-help (i num)
(cond ((= i num) 0)
((primep i) (+ i (sum-of-primes-help (+ i 1) num)))
(t (sum-of-primes-help (+ i 1) num))))
(defun primep (num)
(primep-help 2 num))
(defun primep-help (i num)
(cond ((= num 0) nil)
((= num 1) nil)
((= i num) t)
((= 0 (mod num i)) nil)
(t (primep-help (+ i 1) num))))
(defun program ()
(format t "Enter your number ~%")
(format t "Sum of primes is: ~s"
(sum-of-primes (read))))
那你就打电话给(program)
.
我这里有一个代码,它试图获得低于给定数字的所有素数的总和。当我 运行 它时,我不断收到堆栈溢出错误,仅此而已,我似乎找不到哪里出错了。
(format t "Enter your number ~%")
;global variables
(defvar *number* (read))
(defvar *conditional-check* nil)
(defvar *prime* nil)
;sum-of-primes function
(defun sum-of-primes (x)
(defvar sum 0)
(primeCheck x 2)
(if (equal *prime* 'yes)
(progn
(setf sum (+ sum x))
(setf z (- x 1))
(conditional z)
(if (equal *conditional-check* 'yes) (sum-of-primes z) ()))
(and (setf z (- x 1)) (sum-of-primes z)))
)
;conitional function
(defun conditional (z)
(if (>= z 1) (setf *conditional-check* 'yes) (setf *conditional-check* 'no))
)
;prime number check
(defun primeCheck (*number* y)
(if (and (>= *number* y) (not (= (mod *number* y) 0)))
(progn
(setf z (+ y 1))
(primeCheck *number* z)
(setf *prime* 'yes))
(setf *prime* 'no))
)
;function call
(sum-of-primes *number*)
Whosebug 表示称为堆栈的内存部分已达到其限制。澄清一下,在堆栈上存储了函数调用。现在,如果存储函数调用的内存部分达到了它的限制,那就意味着发生了太多的函数调用。这通常意味着无限递归。想象一个只调用自身的函数。现在,如果您调用该函数,那么该调用将存储在堆栈中。但是,该函数调用自身,并且第二个调用也存储在堆栈中。而第二次调用是第三次调用该函数,入栈等。
递归的这种错误使用可以通过查看代码的特定区域来解决,在这些区域中函数本身被调用,或者更广泛地说,如果函数已经在堆栈中,但是又被调用了。
这是您需要的理解,以便找到解决当前问题的方法并避免将来出现类似问题。
sum-of-primes
缺少一些 基本条件 ,这会结束递归调用。这是主要问题,但是您的代码非常混乱并且包含许多无用的全局变量。您应该避免使用全局变量并使用局部变量(由 let 或函数调用创建)。对于这个例子,你根本不需要任何全局变量。
(defun sum-of-primes (num)
(sum-of-primes-help 0 num))
(defun sum-of-primes-help (i num)
(cond ((= i num) 0)
((primep i) (+ i (sum-of-primes-help (+ i 1) num)))
(t (sum-of-primes-help (+ i 1) num))))
(defun primep (num)
(primep-help 2 num))
(defun primep-help (i num)
(cond ((= num 0) nil)
((= num 1) nil)
((= i num) t)
((= 0 (mod num i)) nil)
(t (primep-help (+ i 1) num))))
(defun program ()
(format t "Enter your number ~%")
(format t "Sum of primes is: ~s"
(sum-of-primes (read))))
那你就打电话给(program)
.