代码之家  ›  专栏  ›  技术社区  ›  λ Jonas Gorauskas

Lisp-Cons单元的定义是什么?

  •  11
  • λ Jonas Gorauskas  · 技术社区  · 15 年前

    一个常见的lisp-cons单元的定义是什么?cons单元格与标准链接列表项有何不同?毕竟,cons单元格和链接列表项都有一个值和一个指向下一个单元格或项的指针…或者这种理解是错误的?

    5 回复  |  直到 15 年前
        1
  •  19
  •   Zed    15 年前

    cons单元格通常有两个指针,可以指向任何东西。当然,一般的用法是指向左边的“value”,指向右边的另一个cons单元格(或nil)。

        2
  •  13
  •   Jim Lewis    15 年前

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

        3
  •  7
  •   ReWrite    15 年前

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

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

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

        4
  •  5
  •   Josh Lee ZZ Coder    15 年前

    cons 单元格是由以下内容组成的合同的三分之一 欺骗 , car cdr 如其他人所述,要求它们成对工作。

    从这个定义中省略“引用”、“指针”等词的原因是要认识到这些是实现细节。如果你想,你可以建立一个 欺骗 空气稀薄,就像亚伯森和苏斯曼那样:

    (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
  •  3
  •   Rich    15 年前

    我认为这里的其他答案虽然准确,但一点都不明确。

    在传统的C++链表实现中,这两个字段( val next 比如说 类型化的 . 下一个 定义为指向列表中的另一个节点, null 做终结者。你不能指向任何东西 但是 另一个节点 下一个 .

    lisp是动态类型的,因此cons单元格中的任何字段都可以 任何东西 (原子或参考)。您可以实现一个带有cons单元格的链接列表(这就是lisp列表的全部内容:带有 nil 但也可以在每个字段中放置任意值,使用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 .

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