2012-02-13 122 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))