Common Lisp Cons Cell的定义究竟是什么? Cons Cell如何与标准链表项不同?毕竟,缺点单元格和链接列表项都有一个值和一个指向下一个单元格或项目的指针......或者这种理解是错误的吗?
答案 0 :(得分:20)
缺点单元格通常包含两个可以指向任何东西的指针。一般用法当然是指左边的一个“值”,另一个指向“右”的Cons单元格(或者nil)。
答案 1 :(得分:14)
cons单元比链表节点更靠近二叉树节点。汽车和cdr返回两个孩子,可以是零,原子或其他利弊细胞。
答案 2 :(得分:7)
在Lisp中,cons单元格拥有一对值。如果cons单元格位于变量c
中,则(car c)
会返回第一个值,(cdr c)
会返回第二个值。
按照惯例,列表由cons单元组成,其中单元格的car
包含节点值,cdr
包含对下一个节点的引用或nil(空列表)以指示列表的末尾。当基元函数返回或接受列表时,这是列表显示的格式。
因此,对于列表l
,(car l)
给出第一个元素(第一个cons单元格中的值),(cdr l)
返回列表的尾部(下一个cons单元格)清单)。
答案 3 :(得分:6)
cons
单元格是由cons
,car
和cdr
组成的合同的三分之一,其要求是它们的行为与其他人一样提及。
从该定义中省略“引用”,“指针”等词语的原因是要认识到那些是实现细节。如果你愿意的话,你可以像Abelson和Sussman那样凭空建立一个cons
:
(define (cons a b) (lambda (x) (x a b)))
(define (car x) (x (lambda (a b) a)))
(define (cdr x) (x (lambda (a b) b)))
这个定义完全存在于Lisp的定义和函数世界中,甚至不停止考虑对象是存储为值还是引用;然而,这些可以作为原始对象的替代品(不考虑可变性或其他特殊用途)。
答案 4 :(得分:4)
我认为这里的其他答案虽然准确,但对于一件事并不明确。
在传统的C ++链接列表实现中,两个字段(例如val
和next
)是类型。 next
被定义为指向列表中的另一个节点,null
是终结符。您不能指向任何但另一个next
的节点。
Lisps是动态类型的,因此cons单元格中的任何一个字段都可以是任何(原子或引用)。您可以使用cons单元实现链接列表(所有Lisp列表都是:带有nil
终止符的cons单元链),但您也可以使用cons单元格作为坐标在每个字段中放置任意值对,树节点等
你甚至可以将这些结合起来;例如,x
y
坐标列表:
;; (cons foo (cons bar nil)) == (list foo bar)
(cons
(cons 5 4)
(cons (cons 9 10) nil))
=>
((5 . 4) (9 . 10))
因此,cons单元格比链表节点更通用;它更接近“应用对”,可以这么说。所有标准列表处理函数(map
,dolist
等)都只是假设您将值放在car
中的函数和另一个列表中的函数cdr
。
所有这些意味着 - 如果您愿意 - 您可以向后定义列表 ,car
指向下一个cons单元格,cdr
指向该值!要使用链接列表节点执行此操作,您必须重新定义类或数据结构以更改类型。