【问题标题】:What is the Definition of a Lisp Cons Cell?Lisp Cons 单元的定义是什么?
【发布时间】:2010-11-21 23:13:45
【问题描述】:

Common Lisp Cons Cell 的具体定义是什么? Cons Cell 与标准链表项有何不同?毕竟,cons 单元格和链表项都有一个值和一个指向下一个单元格或项的指针……还是这种理解是错误的?

【问题讨论】:

  • 每个列表(nil 除外)都是一个 cons 单元格,但不是每个 cons 单元格都是一个列表(如果它的 cdr 不是一个列表)
  • 我只是想澄清一下,我在上面比较了一个 Common Lisp List 及其 Cons Cells 和一个常规 Lisnked List 及其项目,它们是用 C、C++ 或 Java 等语言实现的。

标签: lisp linked-list common-lisp


【解决方案1】:

Cons 单元格通常包含两个可以指向任何内容的指针。一般的用法当然是用左边指向一个“值”,用“右边”指向另一个 Cons 单元格(或 nil)。

【讨论】:

  • cons 单元格也可以直接保存值,而无需保存指针。由 (cons 1 2) 制成的 Ac cons 单元格将具有指向数字的指针,但可以直接存储它们(对于其他一些小项目,如字符也是如此)。
【解决方案2】:

cons 单元比链表节点更接近二叉树节点。 car 和 cdr 返回两个孩子,可以是 nil、atoms 或其他 cons 单元。

【讨论】:

  • 为了强调这里的区别,不要求第二个元素必须是另一个 cons 单元格。 ('tofu . 1) 是一个有效的 cons 单元格。
【解决方案3】:

在 Lisp 中,一个 cons 单元格包含一对值。如果 cons 单元格在变量 c 中,则 (car c) 返回第一个值,(cdr c) 返回第二个值。

按照惯例,列表由 cons 单元格组成,其中单元格的 car 包含节点值,cdr 包含对下一个节点的引用或 nil(空列表)以指示列表的结尾.当原始函数返回或接受列表时,这就是列表的呈现格式。

因此,对于列表l(car l) 给出第一个元素(第一个 cons 单元格中的值),(cdr l) 返回列表的尾部(列表中的下一个 cons 单元格)。

【讨论】:

    【解决方案4】:

    cons 单元格是由 conscarcdr 组成的合约的三分之一,要求它们成对运行,正如其他人所提到的那样。

    从这个定义中省略“引用”、“指针”等词的原因是要认识到这些是实现细节。如果您愿意,您可以像 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 的定义和函数世界中,甚至不会停下来考虑对象是存储为值还是引用;然而这些可以作为原始对象的替代品(不考虑可变性或其他特殊用途)。

    【讨论】:

      【解决方案5】:

      我认为这里的其他答案虽然准确,但对一件事并不明确。

      在传统的 C++ 链表实现中,这两个字段(例如,valnext)是类型化的next 定义为指向列表中的另一个节点,null 是终止符。你不能用next指向任何东西但是另一个节点。

      Lisps 是动态类型的,因此 cons 单元格中的任一字段都可以是 anything(原子或引用)。您可以使用 cons 单元实现链表(这就是 Lisp 列表的全部内容:带有 nil 终止符的 cons 单元链),但您也可以在每个字段中放置任意值,使用 cons 单元作为坐标对,树节点等。

      您甚至可以将这些组合起来;例如,xy 坐标列表:

      ;; (cons foo (cons bar nil)) == (list foo bar)    
      (cons
        (cons 5 4)
        (cons (cons 9 10) nil))
      =>
      ((5 . 4) (9 . 10))
      

      因此,cons 单元格比链表节点更一般;可以这么说,它更接近“应用对”。所有标准列表处理函数(mapdolist 等)都是假设您将值放入 car 并将另一个列表放入 cdr 的简单函数。 p>

      所有这一切意味着——如果你愿意——你可以定义列表向后car 指向下一个 cons 单元格,cdr 指向值!要使用链表节点执行此操作,您必须重新定义类或数据结构以更改类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-08
        • 2013-07-28
        • 2013-05-12
        • 1970-01-01
        • 1970-01-01
        • 2016-06-28
        • 1970-01-01
        相关资源
        最近更新 更多