图3.16和3.17中的计算机程序结构和解释(SICP)的方框图指针看起来并不等同(纯粹是关于价值,而不是内存),即使它们是这样的。 (“当被视为列表时,z1
和z2
都代表”相同“列表,((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:
和z2是这样的:
对中的箭头z1
,似乎都没有指向整个对x
。他们甚至没有指出相同的事情,尽管两者都收到了相同的(记忆和价值)对。
我会将第一个图表评估为(a b)
,将第二个图表评估为((a b) a b)
我猜可能每个箭头实际上都指向整个对x
,但在第98页的图2.3中:
通过指向侧面或两个项目之间非常清楚地指向整个框。
我是否正确地理解了盒子和指针图表或完全不了解其他内容?
答案 0 :(得分:10)
你读得太多了。 :-)如果它指向任何地方的框,假设它是指向该cons单元格的指针。您不能专门指向它的car
或cdr
部分。
答案 1 :(得分:6)
你最后的假设是正确的。点表示指针值的位置,箭头指向的整个双框是目标。如果它指向侧面,顶部中间,左上角或右上角并不重要。它是整个对,它是对象的“地址”。
如果没有使用car
和cdr
访问其部分,则无法指向对象的一部分。第二个你这样做,你有任何指向,而不是间接指针。 (car '(a b)) ; ==> a
和a
在收集垃圾之前没有任何指向它的列表的本质。
我们可以这样说明:
[=#1|#3|#2]
[=#2|#3|()]
[=#3|a |#4]
[=#4|b |()]
=#的第一个值是框本身的位置,而接下来的两个是car
和cdr
。在上方,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
都指向相同的列表z1
。 x
指向两个不同的列表,但这些列表中的元素是相同的。
原因是符号是单身。因此,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)
相同的方式重用数据。