打印阵列LISP的内容

时间:2012-02-13 02:22:47

标签: arrays multidimensional-array lisp common-lisp

为什么此代码不会打印出数组的内容 -


(defun loopfn (state)
       (loop for x from 0 to 2 do
        (loop for y from 0 to 2 do
             (aref state x y))))

这里我传递的是一个像这样构建的3x3矩阵 -

`(setq i (make-array '(3,3) :initial-contents '((0 1 3) (4 2 5) (7 8 6))))`

我正在打电话 - (loopfn i)

编辑-------- @格雷格 感谢您指出了这一点... 我有以下问题.. 为什么打印输出......

(defun loopfn ()
   (loop for x from 0 to 3 do
    (if (eq x 2)(return (list x)))))

这在哪里打印出来......

(defun loopfn ()
   (loop for x from 0 to 2 do
    (loop for y from 0 to 2 do
         (if (eq x 2)(return (list x y))))))

我正在打电话

(loopfn)

5 个答案:

答案 0 :(得分:2)

您的代码不会打印任何内容。这也是你想要的 - 通常。

但是你希望函数返回一些有用的东西。

因此,您需要了解打印与REPL打印返回值之间的区别。

CL-USER > 3
3

以上返回3. Read-Eval-Print-Loop打印返回值。

CL-USER > (print 3)

3 
3

上方打印newline,然后打印3两倍。为什么? 第一个是PRINT调用的副作用,它打印换行符然后打印其参数。 第二个是REPL打印返回值。

另请注意,EQ不适用于数字比较。请改用EQL。 请参阅:http://www.lispworks.com/documentation/lw50/CLHS/Body/f_eql.htm

答案 1 :(得分:2)

关于您的第二个问题,(return ...)相当于(return-from NIL ...),因此您只需从内部LOOP返回外部[11]> (defun loopfn () (loop for x from 0 to 2 do (loop for y from 0 to 2 do (if (= x 2) (return-from loopfn (list x y)))))) [12]> (loopfn) (2 0) 。请改用:

[36]> (defun loopfn ()
        (loop for x from 0 to 2 nconc 
          (loop for y from 0 to 2 
                if (= y 2) 
                collect (list x y))) )
LOOPFN
[37]> (loopfn)
((0 2) (1 2) (2 2))

另一种可能性是收集比一个更多的值,如

{{1}}

答案 2 :(得分:1)

这在this forum topic中得到了很好的介绍。

  

外部循环没有会导致返回值的子句。

该线程的一些代码示例:

(defun print-2d-array-as-table (array)
  (loop for i from 0 below (array-dimension array 0)
    do (loop for j from 0 below (array-dimension array 1)
             do (princ (aref array i j))
                (if (= j (1- (array-dimension array 1)))
                    (terpri)
                    (princ #\Space)))))

和一个循环:

(defun print-2d-array-as-table (array)
  (loop for i below (array-total-size array) do
    (if (zerop (mod i (array-dimension array 0)))
      (terpri)
      (princ #\Space))
    (princ (row-major-aref array i))))

答案 3 :(得分:1)

您对aref的调用是获取指定的元素,但您没有对其进行任何操作。您可以将其粘贴到列表中,然后返回:

(defun loopfn (state)
  (let ((result '()))
    (loop for x from 0 to 2 do
     (loop for y from 0 to 2 do
          (setf result (cons (aref state x y) result))))
   result))

或者你可以把它打印出来:

(defun loopfn (state)
  (loop for x from 0 to 2 do
       (loop for y from 0 to 2 do
        (format t "~a~%" (aref state x y)))))

前者更有用;你想要返回可以进一步处理的东西,并且会为你打印传递到顶层的任何内容。

只要您使用LOOP,就可以轻松地使用COLLECTAPPEND等来收集您的价值观,这是执行此操作的惯用方式。

答案 4 :(得分:0)

对于第二个问题,在未打印的循环中,(eq x 2)永远不会成立。您已将循环范围从0 to 3修改为0 to 2,因此x永远不会达到2。由于没有执行明确的(return ...),该函数返回nil