In letzter Zeit habe ich versucht, Zeiger auf visuelle Weise als Karteikarten zu erklären.
Frage 001: Dies ist die Zeichnung eines Speicherorts im Computerspeicher. Stimmt es, dass seine Adresse ist
0x23452
? Warum?Antwort: Ja, da
0x23452
beschrieben wird, wo der Computer diesen Ort finden kann.
Frage 002: Stimmt es, dass das Zeichen
b
im Speicherort gespeichert ist0x23452
? Warum?Antwort: Nein, da der Charakter
a
tatsächlich darin gespeichert ist.
Frage 003: Stimmt es, dass ein Zeiger im Speicherort gespeichert ist
0x23452
? Warum?Antwort: Ja, da die Adresse des Speicherorts
0x34501
darin gespeichert ist.
Frage 004: Stimmt es, dass ein Zeiger im Speicherort gespeichert ist
0x23452
? Warum?Antwort: Ja, da die Adresse eines anderen Speicherorts darin gespeichert ist.
Nun zu dem Teil, der mich beunruhigt hat. Ein Softwareentwickler erklärte mir die folgenden Hinweise:
Ein Zeiger ist eine Variable, deren Wert die Speicheradresse einer anderen Variablen ist.
Anhand der vier Karteikarten, die ich Ihnen allen gezeigt habe, würde ich Zeiger auf etwas andere Weise definieren:
Ein Zeiger ist ein Speicherort, dessen Wert die Speicheradresse eines anderen Speicherorts ist.
Ist es sicher zu sagen, dass eine Variable dasselbe ist wie ein Speicherort?
Wenn nicht, wer hat dann Recht? Was ist der Unterschied zwischen einer Variablen und einem Speicherort?
quelle
a
,0x23453
.nil
usw. Zeug in ihnen sind die Werte. Das mag Ihnen offensichtlich erscheinen, aber ich würde nicht gerne entscheidende Antworten auf diese Fragen geben, ohne zu sehen, wie diese Felder definiert sind. Es gibt wirklich keine Möglichkeit herauszufinden, ob es sicha
bei dem zweiten Bild um ein Zeichen, eine Zeichenfolge (falls sie sich unterscheiden) oder den Namen einer Variablen handelt. Wenn es eine Zeichenfolge ist, istnil
es dann auch eine Zeichenfolge? Oder ein "Null" -Wert?Antworten:
Eine Variable ist ein logisches Konstrukt, das zur Intention eines Algorithmus gehört, während ein Speicherort ein physikalisches Konstrukt ist, das den Betrieb eines Computers beschreibt. Im Allgemeinen wird zur Ausführung eines Programms eine (vom Compiler generierte) Zuordnung zwischen dem logischen Begriff einer Variablen und dem Speicher des Computers vorgenommen.
(Auch in der Assemblersprache haben wir eine Vorstellung von (logischen) Variablen, die Algorithmen und Absichten sowie (physischen) Speicherorten entsprechen, obwohl sie in der Assemblersprache stärker zusammengeführt sind.)
Eine Variable ist ein übergeordnetes Konzept. Eine Variable steht entweder für eine unbekannte (wie in Mathematik oder Programmieraufgabe) oder einen Platzhalter, der durch einen Wert ersetzt werden kann (wie in Programmierung: Parameter).
Ein Speicherort ist ein Konzept auf niedriger (er) Ebene. Ein Speicherort kann verwendet werden, um einen Wert zu speichern, manchmal um den Wert einer Variablen zu speichern. Ein CPU-Register ist jedoch eine andere Möglichkeit, den Wert einiger Variablen zu speichern. CPU-Register sind ebenfalls Speicherorte auf niedriger (er) Ebene, aber sie sind keine Speicherorte, da sie keine Adressen, sondern nur Namen haben.
In gewissem Sinne ist eine Variable ein Abstraktionsmechanismus, um die Absicht des Programms auszudrücken, wohingegen ein Speicherort eine physikalische Entität der Verarbeitungsumgebung ist, die das Speichern und Abrufen ermöglicht.
Wir können nicht sicher sagen. Nur weil es dort einen Wert gibt, der als Adresse funktionieren würde, heißt das nicht, dass es sich um diese Adresse handelt, sondern stattdessen die ganze Zahl (Dezimalzahl) 144466. Wir können keine Annahmen über die Interpretation von Werten treffen, die nur darauf beruhen, wie sie numerisch erscheinen.
Dies ist in der Tat eine seltsame Frage. Sie erwarten einige Annahmen, die auf den Feldern basieren. Beachten Sie jedoch, dass die Adressen für jedes Feld um 1 erhöht werden. In jedem modernen Computer würde dies bedeuten, dass jede Box eine Byte - Byte - Adressierbarkeit enthalten kann. Dies ist seit Jahrzehnten die Norm. Ein Byte besteht jedoch nur aus 8 Bits und kann zwischen 0 und 255 liegen (für Werte ohne Vorzeichen). Sie weisen jedoch einen viel größeren Wert auf, der in einer dieser Adressen gespeichert ist, und sind daher sehr verdächtig. (Dies könnte funktionieren, wenn dies eine wortadressierte Maschine wäre, aber das sagt es nicht, und heutzutage sind es nur wenige Maschinen, obwohl dies bei einigen Lehrmaschinen der Fall ist.)
Während es Situationen gibt, in denen dieses Denken richtig ist, mischen Sie hier Metaphern. Der Begriff einer Variablen geht auf den Algorithmus und seine Absicht zurück - es muss nicht angenommen werden, dass alle Variablen Speicherplätze haben. Einige Variablen (insbesondere Arrays) haben Speicherplätze, da Speicherplätze die Adressierung unterstützen (während CPU-Register nur benannt und nicht indiziert werden können).
Zur Ausführung gibt es eine logische Zuordnung zwischen Variablen & Anweisungen und Prozessorspeicherplätzen & Prozessorbefehlssequenzen. Eine Variable, deren Wert sich nie ändert (z. B. eine Konstante), benötigt nicht unbedingt einen Speicherplatz, da der Wert nach Belieben reproduziert werden kann (z. B. nach Bedarf für vom Compiler generierte Codesequenzen).
quelle
for
Schleifenindex, wenn der Compiler entscheidet, die Schleife vollständig zu entrollen. Nirgendwo in dem erzeugten Ausgabecode (sei es Baugruppen- oder Maschinencode oder Bytecode) befindet sich ein Speicherort, an dem der Schleifenzähler gespeichert wird. Aber es ist immer noch eine Variable.source
gleicher Länge tut, könntedest
eine Schleife, die so codiert istfor (int i=0; i<8; ++i) dest[i] = source[i];
, bis zu einemdest++ = source++;
Punkt kompiliert werden, der der Wiederholung der entsprechenden Häufigkeit entspricht. Mit dem Schleifenzähler selbst ist nirgends etwas zu sehen (auch nicht im Register), und nur die Anzahl der Wiederholungen gibt Auskunft über den Schleifenzustand.Nein. Variable und Speicherort sind zwei Abstraktionen auf zwei verschiedenen Abstraktionsebenen. Variable und Zeiger sind auf Code- / Sprachebene ein übergeordnetes Konzept, der Speicherort ist auf Maschinenebene ein untergeordnetes Konzept. Sobald ein Code in eine ausführbare Datei kompiliert wurde, gibt es keine Variablen mehr. Der Versuch, auf diese Weise über Speicherort und Variablen zu sprechen, ist ein kategorischer Fehler.
Eine Variable kann unter Verwendung des Speichers implementiert werden, aber nicht immer, da ein Compiler eine Berechnung optimieren und alle Berechnungen, die sich auf eine Variable beziehen, vollständig in Registern ausführen kann, oder eine einzelne Variable mehreren Speicherstellen zuordnen kann oder einen einzelnen Speicher verwenden kann Speicherort für mehrere Variablen.
Diese Reihe von Karteikarten ist so verwirrt, dass sie nicht nur nicht richtig, sondern auch nicht falsch sind.
quelle
Once a code had been compiled into an executable, there's no longer any variables.
Damit bin ich wohl nicht einverstanden. Es ist richtig, dass Ihre Variable, wie Sie sie kennen (dh mit diesem Namen), nicht mehr existiert, aber Ihre Formulierung scheint darauf hinzudeuten, dass die kompilierte ausführbare Datei nur Speicheradressen verwendet. Das stimmt nicht. Ihre kompilierte, aber nicht ausführbare ausführbare Datei hat keine Ahnung, welche Speicheradressen sie bei der Ausführung verwendet. Das Konzept einer Variablen (dh eine wiederverwendbare Referenz auf die Speicheradresse, die zur Laufzeit zugewiesen wird) ist in der kompilierten ausführbaren Datei noch vorhanden.Variablen sind Sprachkonstrukte . Sie haben einen Namen, befinden sich in einem Bereich, können von anderen Teilen des Codes referenziert werden usw. Sie sind eine logische Einheit. Dem Compiler steht es frei, dieses Sprachkonstrukt nach Belieben zu implementieren, sofern das beobachtbare Verhalten dem durch den Sprachstandard vorgegebenen entspricht. Daher muss die Variable nicht einmal irgendwo gespeichert werden, wenn der Compiler nachweisen kann, dass dies nicht erforderlich ist.
Speicherplätze sind ein Hardwarekonzept . Sie kennzeichnen einen Platz im virtuellen / physischen Speicher. Jeder Speicherort hat genau eine physikalische Adresse und eine beliebige Anzahl von virtuellen Adressen, die zur Manipulation verwendet werden können. An jedem Speicherplatz ist aber immer genau ein Byte gespeichert.
Zeiger sind eine besondere Art von Werten . Etwas zu sagen, ist ein Zeiger, ist vergleichbar damit, etwas von Typ zu sagen
double
. Es gibt an, wie viele Bits für den Wert verwendet werden und wie diese Bits interpretiert werden. Es bedeutet jedoch nicht, dass dieser Wert in einer Variablen gespeichert ist, und es bedeutet auch nicht, dass dieser Wert im Speicher gespeichert ist.Um ein Beispiel in C zu geben: Wenn ich ein 2D-Array habe
int foo[6][7];
und damit auf ein Element davon zugreifefoo[1][2]
,foo
ist dies eine Variable, die ein Array enthält. Wennfoo
es in diesem Kontext verwendet wird, wird es in einen Zeiger auf das erste Element des Arrays umgewandelt. Dieser Zeiger wird weder in einer Variablen noch im Speicher gespeichert. Sein Wert wird nur in einem Register der CPU generiert, verwendet und dann vergessen. Ebenso wird der Ausdruckfoo[1]
in diesem Zusammenhang in einen anderen Zeiger umgewandelt, der wiederum nicht in einer Variablen enthalten ist, nicht im Speicher gespeichert, sondern in der CPU berechnet, verwendet und vergessen wird. Die drei Konzepte Variable , Speicherort und Zeiger sind wirklich drei verschiedene Konzepte.Übrigens, ich meinte wirklich "an jedem Speicherort ist immer genau ein Byte gespeichert". Dies war in der Steinzeit vor etwa fünfzig Jahren nicht der Fall, aber es gilt für praktisch alle Hardware, die heute verwendet wird. Immer wenn Sie einen Wert im Speicher ablegen, der größer als ein Byte ist, verwenden Sie mehrere aufeinanderfolgende Speicherorte. Dh (unter der Annahme einer Big-Endian-Bytereihenfolge) die Nummer 0x01234567 wird im Speicher als gespeichert
(Little-Endian-Maschinen wie die X86-Architektur speichern die Bytes in umgekehrter Reihenfolge.) Dies gilt auch für Zeiger: Ein Zeiger auf einer 64-Bit-Maschine wird in acht aufeinanderfolgenden Bytes mit jeweils eigener Speicheradresse gespeichert. Sie können nicht auf eine Speicherzelle schauen und sagen: "Oh, das ist ein Zeiger!" Sie sehen immer nur Bytes, wenn Sie den Speicher betrachten .
quelle
Lassen Sie mich auf Ihre eigentliche Frage konzentrieren - "Wer hat Recht?" beim Vergleich dieser beiden Aussagen:
Die Antwort darauf ist keine . Der erste spricht von einer "Speicheradresse einer anderen Variablen", aber Variablen müssen nicht unbedingt Speicheradressen haben, wie die anderen Antworten bereits erklärt haben. Der zweite besagt "ein Zeiger ist ein Speicherort", aber ein Zeiger ist buchstäblich nur eine Zahl, die in einer Variablen gespeichert werden kann, aber wie zuvor hat eine Variable nicht notwendigerweise eine Speicheradresse.
Einige Beispiele für genauere Aussagen:
"Ein Zeiger ist eine Zahl, die die Speicheradresse eines Speicherorts darstellt", oder
"Eine Zeigervariable ist eine Variable, deren Wert die Speicheradresse eines Speicherorts ist."
"Eine Speicheradresse kann einen Zeiger enthalten, der die Speicheradresse eines Speicherorts darstellt."
Beachten Sie, dass manchmal der Begriff "Zeiger" als Abkürzung für "Zeigervariable" verwendet wird, was in Ordnung ist, solange dies nicht zu Verwirrung führt.
quelle
Ich würde sicherlich nicht sagen, dass ein Zeiger ein Speicherort ist, der eine Adresse enthält. Zum einen kenne ich keine Architektur,
0x23453
die in ein einzelnes Byte passen könnte. :) Auch wenn Sie die Byte / Wort-Unterscheidung von Hand wegwinken, haben Sie immer noch das Problem, dass jeder Speicherort eine Adresse enthält. Adressen sind nur Zahlen und der Inhalt des Speichers sind nur Zahlen.Ich denke, der Trick dabei ist, dass "Zeiger" menschliche Absichten beschreibt , keine besonderen Merkmale der Architektur. Es ist ähnlich wie bei einem "Zeichen" oder einer "Zeichenfolge", dass man nichts Konkretes im Gedächtnis sieht - das sind alles nur Zahlen, aber sie funktionieren wie Zeichenfolgen, weil sie so behandelt werden. "Zeiger" bedeutet lediglich einen Wert, der als Adresse verwendet werden soll.
Um ehrlich zu sein, wenn Sie eine bestimmte Sprache unterrichten möchten (Ziel C?), Bin ich mir nicht sicher, ob das Herausziehen des klassischen Speicherbands überhaupt so nützlich ist. Sie lügen bereits, wenn Sie eingegebene Werte und Werte anzeigen, die für ein Byte zu groß sind. Lehren Sie Semantik, nicht Mechanik - die wichtigste Erkenntnis über Zeiger ist, dass sie Indirektion bieten. Dies ist ein äußerst nützliches Werkzeug, um dies zu verstehen.
Ich denke, ein guter Vergleich könnte eine URL sein, die Ihnen sagt, wo Sie einige Daten finden, aber nicht die Daten selbst. Lass mich ausreden:
Es ist Ihnen selten wichtig, wie die URL tatsächlich lautet . Die überwiegende Mehrheit von ihnen ist in Verbindung mit Namen verirrt. Viele Leute nutzen das Internet, ohne genau zu wissen, wie eine URL zu einer Seite führt. Manche Leute kennen URLs überhaupt nicht.
Nicht jeder String ist eine URL oder soll als URL verwendet werden.
Wenn Sie versuchen, eine gefälschte URL oder eine Seite aufzurufen, die zuvor vorhanden war, aber inzwischen gelöscht wurde, wird eine Fehlermeldung angezeigt.
Eine URL kann auf ein Bild, einen Text, eine Musik oder eine beliebige Anzahl anderer einzelner Elemente verweisen - oder auf eine Seite mit einer Vielzahl von Dingen, die darin enthalten sind. Es kommt sehr häufig vor, dass eine ganze Reihe von Seiten ähnliche Layouts, aber unterschiedliche Daten aufweisen.
Wenn Sie eine Webseite erstellen und auf Daten auf einer anderen Webseite verweisen möchten, müssen Sie nicht alles kopieren und einfügen. Sie können einfach einen Link dazu erstellen.
Beliebig viele andere Seiten können auf dieselbe URL verweisen.
Wenn Sie über eine Sammlung ähnlicher Seiten verfügen, können Sie eine Indexseite erstellen, auf der Links zu allen Seiten aufgeführt sind, oder Sie haben einfach einen "nächsten" Link am Ende von Seite 1, der Sie zu Seite 2 führt, und so weiter. Die Vor- und Nachteile beider Ansätze liegen auf der Hand, insbesondere wenn Sie überlegen, was der Webmaster tun muss, um Seiten an verschiedenen Stellen hinzuzufügen oder zu entfernen.
Diese Analogie macht sehr deutlich, wofür Zeiger sind , was für das Verständnis entscheidend ist - ansonsten wirken sie einfach willkürlich, kompliziert und sinnlos. Zu verstehen, wie etwas funktioniert, ist viel einfacher, wenn Sie bereits verstehen, was es tut und warum es nützlich ist. Wenn Sie bereits verinnerlicht haben, dass ein Zeiger eine Blackbox ist, die Ihnen sagt, wo sich etwas anderes befindet, und Sie dann die Feinheiten des Speichermodells kennenlernen, ist die Darstellung von Zeigern als Adressen ziemlich offensichtlich. Darüber hinaus können Ihre Schüler durch das Unterrichten von Semantik andere Formen der Indirektion besser verstehen und erfinden - was gut ist, wenn die meisten wichtigen Sprachen überhaupt keine Hinweise haben!
quelle
every memory location contains an address
- Jeder Speicherplatz hat eine Adresse. Es ist nirgendwo enthalten , außer vielleicht in einer Zeigervariable.Ich weiß, dass Sie bereits eine Antwort akzeptiert haben und diese Frage hat bereits fünf Antworten, aber es gibt einen Punkt, den sie nicht erwähnen. CS-Lehrbücher versuchen oft, bei der Wahl der Programmiersprache Agnostiker zu sein, was implizit zu der Annahme führt, dass die zur Beschreibung der Dinge verwendete Terminologie universell ist. Ist es nicht.
In C wird der Operator für unäres kaufmännisches Und der Operator "Adresse von" genannt. C-Programmierer würden ohne zu zögern sagen, dass der Ausdruck
&x
die Adresse der Variablen x ergibt. Natürlich meinen sie "die Speicheradresse, in der der Wert der Variablen x gespeichert ist", aber niemand ist in gelegentlichen Gesprächen so umständlich. In C bezieht sich das Wort "Zeiger" normalerweise auf den Datentyp einer Variablen, deren Wert eine Speicheradresse ist. Oder gleichbedeutend mit dem Datentyp des Werts. Aber einige Leute würden "Zeiger" als Wert selbst verwenden.In Java verhalten sich alle Variablen vom Typ Objekt oder Array ähnlich wie C-Zeiger (mit Ausnahme der Zeigerarithmetik), aber Java-Programmierer bezeichnen sie als Referenzen und nicht als Zeiger.
C ++ betrachtet Referenzen und Zeiger als unterschiedliche Konzepte. Sie sind verwandt, aber nicht ganz dasselbe, daher müssen C ++ - Programmierer die Unterscheidung in Gesprächen treffen. Das kaufmännische Und wird in einigen Kontexten als "Adresse von" und in anderen als "Verweis auf" gelesen.
So könnte es ein C-Programmierer beschreiben, der "einen Zeiger" im gleichen Sinne wie "ein Int." (Wie in "Ein Zeiger enthält eine Speicheradresse, während ein Int eine Ganzzahl innerhalb eines bestimmten Bereichs enthält.")
Das ist eine merkwürdige Art, es zu sagen, weil es eine sehr lockere und informelle Definition von "ist" erfordert.
Es wäre klarer zu sagen, dass eine Speicheradresse der Ort im Speicher ist, an dem der Wert einer Variablen gespeichert ist. (Zugegeben, aufgrund von Compiler-Optimierungen werden nicht alle Variablen gespeichert, aber jede Variable, deren Adresse mit übernommen
&x
wird, wird gespeichert .)quelle
Die Anweisung Ein Zeiger ist eine Variable, deren Wert die Speicheradresse einer anderen Variablen ist. Wenn ein Leser jedoch versteht, was genau ein Speicherort ist und wie er sich von einer Variablen unterscheidet, versteht er bereits, was genau ein Zeiger ist, und muss sich daher nicht mehr auf diese ungenaue Erklärung verlassen.
Die Anweisung Ein Zeiger ist ein Speicherort, dessen Wert die Speicheradresse eines anderen Speicherorts ist, ist falsch. Der Wert eines Zeigers muss nicht an einem Speicherort gespeichert werden, und es ist fraglich, ob ein Zeiger auf einen Speicherort zeigen muss, abhängig von der beabsichtigten Definition von "Speicher".
Ein Speicherort ist einer von mehreren möglichen Orten, an denen Daten gespeichert werden können. Diese Daten können eine Variable oder ein Teil einer Variablen sein. Variablen sind eine Möglichkeit, Daten zu kennzeichnen.
quelle
Diese Antwort konzentriert sich auf C und C ++. Das scheint angebracht, da sich Ihre Frage mit Zeigern befasst, die ein wesentlicherer Bestandteil von C / C ++ als von anderen Sprachen sind. Der Großteil dieses Beitrags gilt für die meisten kompilierten Sprachen ohne eine aufwendige Laufzeit (wie Pascal oder Ada, aber nicht wie Java oder C #).
Die bereits gegebenen guten Antworten betonen, dass eine Variable ein Sprachkonstrukt ist, das abstrakter ist als das physische Gedächtnis. Ich möchte jedoch betonen, dass diese Abstraktion eine bestimmte Begründung und ein bestimmtes System hat:
Die Abstraktion besteht hauptsächlich darin, einen Namen anstelle einer wörtlichen Adresse zu verwenden.
Die Grundidee ist, dass eine Variable ein benanntes Handle für ein typisiertes Objekt ist. Objekte in C / C ++ befinden sich normalerweise im Speicher. Die Sprachen fügen dann einige Feinheiten hinsichtlich des Lebensdauermanagements und des Datenmarshalls für Typkonvertierungen hinzu. Das Konzept von Variablen ist abstrakter als physikalische Adressen, da uns der numerische Wert von Adressen oder die genaue Position von Funktionen im Speicher nicht wichtig ist. Wir benennen sie einfach und adressieren sie später mit Namen, und der Compiler, der Linker und das Laufzeitsystem kümmern sich um die wichtigen Details.
Und tun Sie nicht so, als wäre C / C ++ speicherunabhängig: Es gibt schließlich den universell einsetzbaren Adressoperator. Ja, stimmt, Sie können die Adresse einer C-Variablen in der Registerspeicherklasse nicht übernehmen. aber wann hast du zuletzt eins benutzt? Dies ist eine besondere Ausnahme vom allgemeinen Konzept und keine pauschale Ablehnung des Arguments. Die allgemeine Regel ist im Gegenteil, dass das Aufnehmen einer Adresse einer Variablen den Compiler tatsächlich dazu zwingt, ein Objekt im Speicher zu erstellen, auch wenn dies sonst nicht der Fall wäre (z. B. mit Konstanten). Das "named handle" -Konzept ist auch ein gutes Paradigma für C ++ - Verweise: Ein Verweis ist nur ein anderer Name für dasselbe Objekt.
Als ich Inline Assembler für 68k geschrieben habe, war es schön zu sehen, wie Sie Variablennamen als Offsets für Adressregister verwenden können (und Sie können die Namen von deklarierten Variablen
register
anstelle der Bare-Metal-Registernamen verwenden!). Für den Compiler ist eine Variable ein konstanter Adressoffset. So wiederholen Sie: Variablen werden als Handles bezeichnet, normalerweise für Objekte im Speicher.quelle
Es hört sich so an, als ob die Frage auf eine populäre Sprache abzielt, die durch die Erweiterung des C-Standards mit der zusätzlichen Garantie "gebildet wird dominiert der erstere Teil. "sowie eine Definition von" Variable ", die mit der Verwendung des Begriffs durch andere Sprachen übereinstimmt.
In dieser Sprache kann jeder Speicherort als eine nummerierte Mailbox angesehen werden, die immer eine Anzahl (typischerweise acht) von Bits enthält, von denen jedes unabhängig null oder eins sein kann. Speicherorte sind typischerweise in Reihen von zwei, vier oder acht organisiert. und einige Operationen verarbeiten mehrere aufeinanderfolgende Speicherstellen gleichzeitig. Abhängig von der Maschine können einige Operationen, die mit Gruppen von zwei, vier oder acht Speicherplätzen arbeiten, auf Positionen innerhalb einer einzelnen Zeile beschränkt sein. Während einige Computer möglicherweise einen einzelnen Raum mit fortlaufend nummerierten Postfächern haben, können andere mehrere nicht zusammenhängende Gruppen mit nummerierten Postfächern haben.
Eine Variable identifiziert einen Bereich von Speicherorten, die ausschließlich ihr zugeordnet sind, und einen Typ, als den diese Speicherorte interpretiert werden sollten. Das Lesen einer Variablen bewirkt, dass die Bits in ihren zugeordneten Speicherorten in einer dem Variablentyp entsprechenden Weise interpretiert werden, und das Schreiben einer Variablen bewirkt, dass die zugeordneten Bits in einer dem Typ und Wert entsprechenden Weise gesetzt werden.
Eine Adresse kapselt alle Informationen, die zur Identifizierung eines Postfachs erforderlich sind. Dies kann als einfache Nummer oder als eine Art Gruppenbezeichnung zusammen mit der Nummer einer Mailbox in dieser Gruppe gespeichert werden.
Wenn Sie den
&
Operator auf eine Variable anwenden, erhalten Sie einen Zeiger, der die Adresse und den Typ der Variablen enthält. Das Anwenden des unären Operators*
oder[]
Operators auf einen Zeiger bewirkt, dass die Bits von Postfächern, die an einer gekapselten Adresse beginnen, in einer dem gekapselten Typ entsprechenden Weise interpretiert oder festgelegt werden.quelle
Ich komme zu spät zu dieser Party, aber ich kann nicht widerstehen, meine 2 Cent in.
Was ist zu diesen Zeiten der Unterschied zwischen den in diesen Speicherorten gespeicherten Werten?
Zeit 1
Zeit 2
Richtige Antwort: nichts. Sie sind alle identische Werte, die mit unterschiedlichen Interpretationen ihrer Bedeutung dargestellt werden.
Woher weiß ich das? Weil ich derjenige bin, der das erfunden hat. Das weißt du noch nicht so genau.
Sie stoßen auf etwas, das ich als Out-of-Band- Problem bezeichne. Wie die Bedeutung dieser Werte richtig interpretiert wird, wird hier nicht gespeichert. Dieses Wissen wird woanders gespeichert. Wenn Sie diese Werte jedoch auf Papier präsentieren, geben Sie diese Interpretation ein. Das heißt, Sie haben Informationen hinzugefügt, die an diesen Speicherorten einfach nicht vorhanden sind.
Zum Beispiel sind die Werte hier identisch, aber Sie wissen nur, dass es wahr ist, wenn Sie richtig sind, wenn Sie annehmen, dass eine ASCII / UTF-8-Zeichenkodierung so ist, wie ich die erste erhalten habe, anstatt EBCDIC zu sagen . Und Sie müssen auch davon ausgehen, dass es sich bei dem zweiten Wert um hexadezimale Ausdrücke der an diesen Speicherorten gespeicherten numerischen Werte handelt, die alle Zeiger auf andere Adressen sein können, anstatt Verweise auf Zeichenfolgen zu verwenden, die alle mit "0x" beginnen. : P
Nichts, was an diesen Speicherorten gespeichert ist, sagt Ihnen, dass eine dieser Annahmen richtig ist. Diese Informationen können gespeichert werden. Aber es würde woanders gelagert werden.
Dies ist das Präsentationsproblem . Sie können überhaupt keine Zahl ausdrücken, ohne sich vorher darauf geeinigt zu haben, wie sie präsentiert werden soll. Sie können sich auf Annahmen, Konventionen und den Kontext stützen. Wenn Sie jedoch tiefgreifend voranschreiten und die Präsentation nicht explizit definiert ist, ist die einzig richtige Antwort "nicht genügend Informationen".
quelle