SICP

时间:2015-07-30 17:52:43

标签: scheme lisp sicp

图3.16和3.17中的计算机程序结构和解释(SICP)的方框图指针看起来并不等同(纯粹是关于价值,而不是内存),即使它们是这样的。 (“当被视为列表时,z1z2都代表”相同“列表,((a b) a b))”,第258页

(define x (list 'a 'b))
(define z1 (cons x x))
(define z2 (cons (list 'a 'b) (list 'a 'b)))

SICP如下所示绘制对z1:

enter image description here

和z2是这样的:

enter image description here

对中的箭头z1,似乎都没有指向整个对x。他们甚至没有指出相同的事情,尽管两者都收到了相同的(记忆和价值)对。 我会将第一个图表评估为(a b),将第二个图表评估为((a b) a b)

我猜可能每个箭头实际上都指向整个对x,但在第98页的图2.3中:

enter image description here

通过指向侧面或两个项目之间非常清楚地指向整个框。

我是否正确地理解了盒子和指针图表或完全不了解其他内容?

2 个答案:

答案 0 :(得分:10)

你读得太多了。 :-)如果它指向任何地方的框,假设它是指向该cons单元格的指针。您不能专门指向它的carcdr部分。

答案 1 :(得分:6)

你最后的假设是正确的。点表示指针值的位置,箭头指向的整个双框是目标。如果它指向侧面,顶部中间,左上角或右上角并不重要。它是整个对,它是对象的“地址”。

如果没有使用carcdr访问其部分,则无法指向对象的一部分。第二个你这样做,你有任何指向,而不是间接指针。 (car '(a b)) ; ==> aa在收集垃圾之前没有任何指向它的列表的本质。

我们可以这样说明:

[=#1|#3|#2]
[=#2|#3|()] 
[=#3|a |#4]
[=#4|b |()]

=#的第一个值是框本身的位置,而接下来的两个是carcdr。在上方,x指向地址#3,z1指向#1。我们来z2

[=#5|#6|#8]
[=#6|a |#7] 
[=#7|b |()] 
[=#8|#9|()]
[=#9|a |#10]
[=#10|b |()]

正如您所看到的,z2使用了两个cons而不是z1,因为它不会将同一个对象重复用于其列表的两个元素,而是使用单个类似的列表。

在图纸中,car的{​​{1}}和cdr都指向相同的列表z1x指向两个不同的列表,但这些列表中的元素是相同的。

原因是符号是单身。因此,z2只有一个符号对象,而在两个不同位置评估a将指向相同的'a。其他单身人士是a#f#t

()总是创建一个新对,而cons只是list参数的一个过程。因此,表达式中两个相同的代码cons使两个不同的对象看起来相同。

(list 'a 'b)

可以看到引用的数据在程序启动之前一次创建。因此,这是未定义的。

(eq? (car z1) (cdr z1))    ; ==> #t same object
(eq? (car z2) (cdr z2))    ; ==> #f not same object
(equal? (car z2) (cdr z2)) ; ==> #t they look the same, but they are not the same. (created at different places)

原因是Scheme允许(但没有义务)以与结构(eq? '(a b) '(a b)) ; ==> #t or #f (undefined) (eq? '(b c) (cdr '(a b c))) ; ==> #t or #f (undefined) 相同的方式重用数据。