2012-02-13 238 views
3

为什么这个代码不打印出数组的内容 -打印内容

 

(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) 
+1

你忘了实际打印输出的一部分吗?像'(print(aref ...))'? – 2012-02-13 02:27:43

+0

谢谢你指出... – Fox 2012-02-13 02:31:16

+0

@Greg Hewgill你能清楚我的问题的第二部分...我编辑它... – Fox 2012-02-13 02:39:16

回答

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,等等,这是惯用的方式做到这一点你的价值观。

+0

嗨,感谢您的信息.......我修改了我的代码..... defun loopfn(状态目标) (循环为x从0到2 做(循环为y从0到2) \t做(如果(eq(aref状态xy)目标)(princ(list xy))))))但是输出就像(2 1)Nil ...我的问题是如何仅输出列表(2 1)而不是nil .... – Fox 2012-02-13 03:38:57

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)))) 
+0

嗨,感谢您的链接.......我修改了我的代码..... defun loopfn(状态目标) (循环为x从0到2 做(循环y从0到2 (2)没有...我的问题是如何只输出列表(2 1)如果(输出(国家xy)而不是零.... – Fox 2012-02-13 03:33:11

+0

默认情况下,即使只是'nil',也要返回一些东西,但如果调用'(values)',它什么也不返回。 – 2012-02-13 05:14:50

0

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

+0

这是“0到2”,而不是“从0下面2开始”,尝试(从0到2的x循环收集x)并查看X在循环内部获得的值。 – Vatine 2012-02-13 15:34:16

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

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))