2011-07-20 80 views
3
> (cons 2 3) 
(2 . 3) 

Lisp環境只需要分配一個單元格來連接兩個項目。Lisp中的內存分配

上面是來自Lisp的書「Lisp的土地」。我不明白爲什麼這一對只位於一個單一的反應池中。這些數據的內存是什麼樣的?

回答

11

甲cons單元總是成立的兩個值,稱爲carcdr

+-----+-----+ 
| car | cdr | 
+-----+-----+ 

要表示cons單元,Lisp有 「點表示法」:

(car . cdr) 

功能cons創建這樣來自其兩個論點的反思小組:

(cons 1 2) 
=> (1 . 2) 

可以這樣想:

+-----+-----+ 
| 1 | 2 | 
+-----+-----+ 

一個cons單元格的值也可以是「引用」或「指針」的其他東西。其他的事情可以,例如,是其他缺點細胞:

+-----+-----+  +-----+-----+ 
| 1 | ------->| 2 | nil | 
+-----+-----+  +-----+-----+ 

這將是(1 . (2 . nil))點標記。這個鏈接用於Lisp來表示列表。由於列表用於表示代碼,因此它們對於Lisp非常重要。因此,他們的記法較短:(1 2)

1

我認爲在口齒不清的利弊是一樣的東西(只是爲了說明,而不是真正的代碼)

typedef struct _cons 
{ 
    void* car; 
    void* cdr; 
} cons; 

這就是「單利弊」的意思。

5

CONS單元格是具有兩個字段的記錄。

在許多Lisp實現中,對cons單元進行了特殊優化。一個典型的例子是fixnum數字直接存儲在字段中 - 沒有指針。只要數據適合內存,它們可以直接存儲。這例如也可以是字符的情況。具有兩個字符的cons單元也可以被存儲,使得字符被編碼到字段中。

對於其他更大的數據,指向存儲在cons單元中的數據的指針。

然後還要注意區別:

(cons 1 2) 

(list 1 2) 

(cons 1 2)創建一個單一的利弊細胞。 (list 1 2)創建兩個cons單元。第一個單元格包含1和一個指向第二個單元格的指針。第二個單元格包含2和NIL(列表標記的結尾)。

因此,作爲一種優化,通常在鍵/值對中,只使用cons單元而不使用列表。

((age . 22) (name . "Barbara)) 

((age 22) (name "Barbara")) 

後者使用兩個缺點細胞。

1

記憶是一種幻覺:

(define (cons a d) 
    (lambda (f) (f a d))) 

(define (car x) 
    (x (lambda (theCar theCdr) theCar))) 

(define (cdr x) 
    (x (lambda (theCar theCdr) theCdr))) 

看馬,無需記憶!

(只是在開玩笑)

+0

難道你沒有看到「只是在開玩笑」嗎? – blabla999