2015-07-30 18 views
7

Struktur und Interpretation von Computerprogrammen (SICP) Box-and-Pointer-Diagramme in Abbildung 3.16 und 3.17 erscheinen nicht gleichwertig (rein in Bezug auf Wert, nicht Speicher) obwohl es heißt, dass sie es sind. ("Wenn sie als Liste gedacht, z1 und z2 beide für "die gleiche" -Liste, ((a b) a b))", S. 258.)Inkonsistente Box-and-Pointer-Diagramme in SICP

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

SICP ein Diagramm mit den Paar z1 wie folgt aus:

enter image description here

und z2 wie folgt aus:

enter image description here

die Pfeile in der pa ir, z1, scheinen nicht beide auf das gesamte Paar zu zeigen, x. Sie weisen nicht einmal auf dasselbe hin, obwohl beide das gleiche (Gedächtnis und Wert) Paar erhalten haben. würde ich das erste Diagramm als (a b), und die zweiten als ((a b) a b)

bewerten ich, dass jeder Pfeil auf das gesamte Paar zeigt tatsächlich erraten konnte, x, aber in Abbildung 2.3 auf Seite 98:

enter image description here

es zeigt sehr deutlich auf eine ganze Box, indem Sie entweder auf die Seite oder zwischen zwei Elemente zeigen.

Ich verstehe Box-and-Pointer-Diagramme falsch oder etwas ganz anderes?

Antwort

5

Ihre letzte Annahme ist richtig. Der Punkt zeigt an, wo der Zeigerwert ist, die ganze Doppelbox, auf die der Pfeil zeigt, ist das Ziel. Es spielt keine Rolle, ob es auf die Seite, oben Mitte, oben links oder oben rechts zeigt. Das ganze Paar ist die "Adresse" des Objekts.

Sie können nicht auf einen Teil eines Objekts zeigen, ohne auf seinen Teil mit car und cdr zuzugreifen. In der Sekunde, in der du das tust, hast du das, worauf es gezeigt wurde, und nicht einen indirekten Zeiger. (car '(a b)) ; ==> a und a hat keine Essenz der Liste, die immer noch darauf zeigt, bis es Müll gesammelt wird.

wir es mögen diese stattdessen illustrieren könnte:

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

Der erste Wert mit = # ist die Lage der Box selbst, während die nächsten zwei car und cdr sind. Oben, x zeigt auf die Adresse # 3 und z1 auf # 1. Lassen Sie uns z2

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

machen Wie Sie sehen können, z2 verwendet zwei weitere cons als z1, da es nicht das gleiche Objekt wie beide Elemente seiner Liste nicht wiederverwendet werden, sondern nutzt einzelne ähnlich aussehende Listen.

In den Zeichnungen zeigen sowohl car als auch cdr von z1 auf dieselbe Liste x. z2 verweist auf zwei verschiedene Listen, aber die Elemente in diesen Listen sind identisch.

Der Grund dafür ist, dass Symbole Singletons sind. Somit haben Sie nur ein Symbolobjekt für a und die Auswertung 'a an zwei verschiedenen Stellen zeigen beide auf die gleiche a. Andere Singletons sind #f, #t und ()

cons schafft immer ein frisches Paar und list ist nur ein Verfahren, das cons zusammen die Argumente. So macht der gleiche Code zwei Stellen im Ausdruck zwei verschiedene Objekte, die einfach gleich aussehen.

(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) 

Angegebene Daten können vor dem Start des Programms als auf einmal erstellt angesehen werden. Dies ist also undefiniert.

(eq? '(a b) '(a b))   ; ==> #t or #f (undefined) 
(eq? '(b c) (cdr '(a b c))) ; ==> #t or #f (undefined) 

Der Grund dafür ist, dass Schema erlaubt ist, aber nicht verpflichtet, Daten auf die gleiche Weise wie bei der Struktur z1 wiederzuverwenden.

10

Sie lesen zu viel hinein. :-) Wenn es in die Box irgendwo zeigt, nehme an, es ist ein Zeiger auf diese Cons-Zelle. Sie können nicht speziell auf den car oder cdr Teil davon zeigen.

+1

Warum können Sie nicht speziell auf ein Auto oder eine CDR eines Paares zeigen? Nur Konvention? – Aaron

+4

Schema (und Lisp) ist nicht C; es hat keine Adressen an sich. Es hat Objektreferenzen, die sich (konzeptuell) immer auf ein ganzes Objekt beziehen, nicht Teile davon. So bezieht sich ein Objektreferenz auf eine Cons-Zelle auf die gesamte Cons-Zelle (auch wenn sie typischerweise als ein Zeiger auf den Ort des Beginns der Cons-Zelle implementiert ist), bezieht sich ein Objektreferenz auf eine Zeichenkette auf die ganze Zeichenkette (und nicht einzelne Zeichen in der Zeichenkette), bezieht sich eine Objektreferenz auf einen Vektor auf den gesamten Vektor usw. –