Wenn Sie über Zeiger nachdenken, ist es hilfreich, Diagramme zu zeichnen . Ein Zeiger ist ein Pfeil, der auf eine Adresse im Speicher zeigt, wobei eine Beschriftung den Typ des Werts angibt. Die Adresse gibt an, wo gesucht werden soll, und der Typ gibt an, was zu nehmen ist. Durch Umsetzen des Zeigers wird die Beschriftung des Pfeils geändert, jedoch nicht die Stelle, an der der Pfeil zeigt.
din mainist ein Zeiger cvom Typ char. A charist ein Byte Speicher. Wenn dalso dereferenziert wird, erhalten Sie den Wert in diesem einen Byte Speicher. In der folgenden Abbildung repräsentiert jede Zelle ein Byte.
-+----+----+----+----+----+----+-
| | c | | | | |
-+----+----+----+----+----+----+-
^~~~
| char
d
Wenn Sie dzu int*besetzen, sagen Sie, dass dies dwirklich auf einen intWert hinweist . Auf den meisten heutigen Systemen intbelegt ein 4 Bytes.
-+----+----+----+----+----+----+-
| | c | ?₁ | ?₂ | ?₃ | |
-+----+----+----+----+----+----+-
^~~~~~~~~~~~~~~~~~~
| int
(int*)d
Wenn Sie dereferenzieren (int*)d, erhalten Sie einen Wert, der aus diesen vier Speicherbytes bestimmt wird. Der Wert, den Sie erhalten, hängt davon ab, was in diesen Zellen markiert ?ist und wie ein intim Speicher dargestellt wird.
Ein PC ist Little-Endian , was bedeutet, dass der Wert von a auf intdiese Weise berechnet wird (vorausgesetzt, er umfasst 4 Bytes) :
* ((int*)d) == c + ?₁ * 2⁸ + ?₂ * 2¹⁶ + ?₃ * 2²⁴. Wenn Sie also hexadezimal ( printf("%x\n", *n)) drucken , werden die letzten beiden Ziffern immer angezeigt 35(das ist der Wert des Zeichens '5') , während der Wert Müll ist .
Einige andere Systeme sind Big-Endian-Systeme und ordnen die Bytes in die andere Richtung : * ((int*)d) == c * 2²⁴ + ?₁ * 2¹⁶ + ?₂ * 2⁸ + ?₃. Auf diesen Systemen beginnt der Wert immer mit 35hexadezimalem Druck. Einige Systeme haben eine Größe int, die sich von 4 Bytes unterscheidet. Einige wenige Systeme sind intunterschiedlich angeordnet, aber es ist äußerst unwahrscheinlich, dass Sie ihnen begegnen.
Abhängig von Ihrem Compiler und Betriebssystem stellen Sie möglicherweise fest, dass der Wert bei jedem Ausführen des Programms unterschiedlich ist oder dass er immer gleich ist, sich jedoch ändert, wenn Sie den Quellcode auch nur geringfügig ändern.
Auf einigen Systemen muss ein intWert in einer Adresse gespeichert werden, die ein Vielfaches von 4 (oder 2 oder 8) ist. Dies wird als Ausrichtungsanforderung bezeichnet . Je nachdem, ob die Adresse von crichtig ausgerichtet ist oder nicht, kann das Programm abstürzen.
Im Gegensatz zu Ihrem Programm geschieht Folgendes, wenn Sie einen intWert haben und einen Zeiger darauf nehmen.
int x = 42;
int *p = &x;
-+----+----+----+----+----+----+-
| | x | |
-+----+----+----+----+----+----+-
^~~~~~~~~~~~~~~~~~~
| int
p
Der Zeiger pzeigt auf einen intWert. Das Etikett auf dem Pfeil beschreibt korrekt, was sich in der Speicherzelle befindet, sodass beim Dereferenzieren keine Überraschungen auftreten.