计算机程序的结构和解释(SICP)的图3.16和3.17中的方框图和指针图看起来并不相同(纯粹是关于价值,而不是记忆),尽管它们是这样的.("当被认为是一个列表,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)))
Run Code Online (Sandbox Code Playgroud)
SICP像这样绘制对z1:
和z2像这样:
这对中的箭头z1似乎都没有指向整个对,x.他们甚至没有指出相同的事情,尽管两者都收到了相同的(记忆和价值)对.我会将第一个图表评估为(a b),而第二个图表评估为((a b) a b)
我猜可能每个箭头实际上指向整个对x,但是在第98页的图2.3中:
通过指向侧面或两个项目之间非常清楚地指向整个盒子.
我是否错误地理解了盒子和指针图或其他完全不同的东西?
Chr*_*ung 10
你读得太多了.:-)如果它指向任何地方的框,假设它是指向该cons单元格的指针.你不能明确指向car或cdr它的一部分.
你最后的假设是正确的.点表示指针值的位置,箭头指向的整个双框是目标.如果它指向侧面,顶部中间,左上角或右上角并不重要.它是整个对,它是对象的"地址".
如果没有使用car和访问它的部分,则无法指向对象的一部分cdr.第二个你这样做,你有任何指向,而不是间接指针.(car '(a b)) ; ==> a并且a没有任何列表的精华仍然指向它,直到它被垃圾收集.
我们可以这样说明:
[=#1|#3|#2]
[=#2|#3|()]
[=#3|a |#4]
[=#4|b |()]
Run Code Online (Sandbox Code Playgroud)
带=#的第一个值是盒子本身的位置,而接下来的两个是car和cdr.在上面,x指向地址#3和z1#1.让我们做z2
[=#5|#6|#8]
[=#6|a |#7]
[=#7|b |()]
[=#8|#9|()]
[=#9|a |#10]
[=#10|b |()]
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,z2使用两个以上cons,z1因为它不会将同一个对象重用为其列表的两个元素,而是使用单个类似的相似列表.
在附图中,都car和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)
Run Code Online (Sandbox Code Playgroud)
引用的数据可以看作是在程序启动之前一次创建的.因此,这是未定义的.
(eq? '(a b) '(a b)) ; ==> #t or #f (undefined)
(eq? '(b c) (cdr '(a b c))) ; ==> #t or #f (undefined)
Run Code Online (Sandbox Code Playgroud)
原因是Scheme允许(但没有义务)以与结构相同的方式重用数据z1.