【问题标题】:SICP's description of pointersSICP对指针的描述
【发布时间】:2016-05-09 12:05:28
【问题描述】:

这句话来自SICP,我认为这是在谈论编程语言中的指针/引用。

正如我们所看到的,对提供了一种原始的“粘合剂”,我们可以使用它来构造复合数据对象。图 2.2 显示了一种可视化配对的标准方法——在本例中,配对由 (cons 1 2) 组成。在这种称为框和指针表示法的表示中,每个对象都显示为指向框的指针。原始对象的框包含对象的表示。例如,数字框包含一个数字。一对的盒子实际上是一个双盒子,左边的部分包含(指向)这对的汽车,右边部分包含 cdr。

在这种情况下,本书讨论的是对(例如(cons 1 2))以及它们是如何表示的。但是我们也可以使用对来构造一个这样的列表:

(cons 1 (cons 2 '()))

虽然 box-and-pointer-notation 只是一种表示法而且没用,但我认为这看起来很像一个链表。据我了解,链表是一种数据结构,其中包含一个值和指向另一个链表的指针。话虽如此,我认为 cons 可以像链表一样构造。我很困惑:

一对的盒子实际上是一个双盒子,左边的部分包含(指向)这对的汽车,右边部分包含 cdr。

我最初认为指针应该在 cdr 上,因为如果我们通过对构造一个列表,那将是下一个列表。

我认为这可能是一种不同类型的指针。在这种情况下,指针到底意味着什么?我知道的唯一指针是 c 中使用的指针。 SICP 有没有提到 c 指针?

【问题讨论】:

    标签: c pointers linked-list lisp sicp


    【解决方案1】:

    我最初认为指针应该在 cdr 上,因为如果我们通过对构造一个列表,那将是下一个列表。

    一个 cons 单元格有两个值,一个 car 值和一个 cdr 值。您放入其中的内容不受限制。你可以把任何东西放进去。

    您可以使用 cons 单元构建不同的数据结构。单链表只是其中之一。它可以是二叉树、通过键和值提供访问的 cons 单元的关联列表、循环数据结构等等。

    如果我们这样做

    (cons
          (cons :foo 10)
          (cons :bar 5))
    

    ... 那么从 cons 单元格到它的 car 值的引用是如何完成的,对程序员来说几乎是隐藏的。大多数实现将在下面具有某种数据结构,其中包含从 cons 单元到其 carcdr 组件的指针。通常会对字符和小整数 (fixnums) 等小对象进行优化——这些也可以直接存储在 carcdr 中,而不是使用指向字符对象的指针。

    总结

    cons 单元格有两个值:carcdr。两者都是完全不受约束的:您可以引用任何其他对象/值。

    大部分实现都是隐藏的。在 Lisp 中,您所得到的只是具有基本功能的以下界面:

    • (consp thing) :如果 thing 是一个 cons 单元格,则谓词返回 T
    • (car cons-cell) : cons cell 的 car 值
    • (cdr cons-cell) : cons 单元格的 cdr 值
    • (cons thing-0 thing-1) :创建一个 cons 单元格,thing-0thing-1 可以是任何东西。

    列表由 cons 单元格组成。但是还有其他数据结构可以由 cons 单元格组成。

    【讨论】:

    • “大部分实现是隐藏的。” - 我能看到那些隐藏的东西吗,比如在书中进一步阅读的指针?
    • @morbidCode 实现取决于您使用的 Lisp 实现。如果你想弄清楚,你必须阅读它的源代码/手册。但作为程序员,这对你来说真的无关紧要。请记住,conses 由两个指针组成,并相应地遍历/操作基于它们的数据结构。
    • @morbidCode SICP 提供了cons 的几个可能的实现;它们都不是实用的,但更多的是为了说明 lambda 演算和消息传递的目的。但重点是:没关系!除非您正在制作自己的编译器。
    • @mobiuseng 我认为第 5 章是关于编译器的。我本以为至少他们会在该部分中提供一个 cons 实现。
    • @morbidCode 老实说,我还没有开始那一章,所以可能有一个合适的cons 实现。
    【解决方案2】:

    是的,你是正确的,cons 单元用于在 Lisps 中构建链表。

    左边部分包含缺点的值。它是一个指针,因为它的值可能是一个数字、一个对象、另一个缺点(例如在树的情况下)或其他任何东西。

    您也正确,右侧部分 cdr 包含指向列表中下一个 cons 的指针。

    所以(54 "foobar" 3) 的列表如下所示:

                (car cdr)
                 /     \
                54      (car cdr)
                         /     \
                      "foobar"  (car nil)
                                 / 
                                3
    

    【讨论】:

    • 谢谢。但是在这种情况下,“指针”这个词有什么用呢?这本书是否要求我考虑将指针作为对象的对,这些对象像在 c 或 c++ 中那样保存内存地址?或者这只是图表中的纯粹符号,与配对没有真正的关系?
    • @morbidCode 作为指向内存地址的指针。 cons/list 不像数组那样存储为连续的块,而是作为指向 value/next 部分所在位置的指针。
    • 那么“盒子”代表什么?我很好奇,因为我不明白既然对的项目实际上是指针,为什么还要费心制作这种盒子和指针符号呢?
    • @morbidCode 这些框只是绘制 cons 单元格的一种方式。 cons 基本上是一个由两个指针组成的数组,所以框表示它。然后箭头指向指针指向的内容。
    • @morbidCode 只是在前面的评论中添加:围绕cons-cell“画一个盒子”的整个想法是让它“一件事”:而不是两个指针(甚至是对象,在这一点上这无关紧要)现在我们有一对。 PS:而且car 还包含一个指针——cons-cells 比单链表更通用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    相关资源
    最近更新 更多