3
> (cons 2 3) 
(2 . 3)

Lisp 环境只需要分配一个 cons 单元来连接这两个项目。

以上来自 Lisp 书籍“Land of Lisp”。我不明白为什么这对只位于一个缺点单元格中。这些数据的内存是什么样的?

4

4 回答 4

12

一个 cons 单元格始终包含两个值,称为carcdr

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

为了表示一个 cons 单元格,Lisp 有“点符号”:

(car . cdr)

该函数cons从它的两个参数创建这样一个 cons 单元格:

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

可以这样想:

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

cons 单元格的值也可以是指向其他事物的“引用”或“指针”。例如,那些其他东西可以是其他 cons 单元格:

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

这将是(1 . (2 . nil))点符号。这个链接在 Lisp 中用于表示列表。由于列表用于表示代码,因此它们对于 Lisp 很重要。因此,它们有一个更短的符号:(1 2).

于 2011-07-20T07:55:40.423 回答
5

CONS 单元格是具有两个字段的记录。

在许多 Lisp 实现中,有针对 cons 单元的特殊优化。一个典型的例子是 fixnum 数字直接存储在字段中 - 没有指针。只要数据适合内存,就可以直接存储。例如,这也可能是字符的情况。也可以存储具有两个字符的 cons 单元格,以便将字符编码到字段中。

对于其他更大的数据,有指向该数据的指针存储在 cons 单元中。

然后还要注意以下之间的区别:

(cons 1 2)

(list 1 2)

(cons 1 2)创建单个 cons 单元格。(list 1 2)创建两个 cons 单元格。第一个 cons 单元包含 1 和指向第二个的指针。第二个 cons 单元格包含 2 和 NIL(列表结束标记)。

因此,作为一种优化,通常在键/值对中,只使用 cons 单元格而不是列表。

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

对比

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

后者使用了另外两个 cons 单元。

于 2011-07-20T07:56:44.637 回答
1

我认为 lisp 的缺点是什么(仅用于解释,而不是真正的代码)

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

这就是“单一缺点”的意思。

于 2011-07-20T07:20:30.023 回答
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)))

看马,不需要记忆!

(只是在开玩笑)

于 2011-12-12T22:00:07.477 回答