Nicht alle Zeiger sind (müssen von derselben Größe sein). Wenn Sie eine große Struktur haben, die auf 10 MB ausgerichtet werden muss, könnte der Compiler entscheiden, dass er nur 8 Bits (statt der üblichen 32 oder 64) benötigt, um alle möglichen Adressen zu speichern, auf denen Ihre Variable liegen könnte.
Sie brauchen auch keinen anderen Datentyp, Sie können void*
einfach verwenden, aber warum sollten Sie? In C ++ ist dies ein Code-Geruch.
Es gibt auch Typ-Sicherheit. Sie wissen, dass int*
auf ein int
zeigt, und das ist zu Ihrem Vorteil.
Zwei Gründe:
Auf einigen Architekturen können Zeiger verschiedene Formate haben, abhängig von der Größe der Daten, auf die sie zeigen. Zum Beispiel muss ein Zeiger auf char
in der Lage sein, einzelne Bytes zu adressieren, aber ein Zeiger auf int
muss nur Gruppen von 4 Bytes adressieren können. Letztere könnte also ein Format verwenden, das die Byteadresse geteilt durch 4 enthält.
Es erlaubt dem Compiler, korrekte Programme zu erzeugen. Wenn Sie versuchen, einen char
-Zeiger zu dereferenzieren und ihn einem int
zuzuordnen, muss er wissen, dass er nur ein Byte von der Quelle lesen und auf die Größe von int
erweitern soll. Ohne die Deklaration des Zeigertyps würde es mehr Bytes als angemessen lesen.
Für den Anfang, ich kenne keine Maschine, wo Zeiger sind als Hexadezimal gespeichert; Jede Maschine, die ich kenne, wird benutzt eine binäre Darstellung intern. (Für die letzten 30 oder 40 mindestens Jahre. IIRC, die IBM 1401 verwendete Dezimalzahl überall.)
Wie andere darauf hingewiesen haben, sind nicht alle Zeiger gleich
Größe und Darstellung. Ich habe an Maschinen gearbeitet, auf denen char*
war größer als andere Daten Pointer-Typen und natürlich mit
verschiedene Größen für Funktionszeiger und Datenzeiger, die verwendet werden
sehr verbreitet sein.
Die eigentliche Antwort basiert jedoch auf dem Typsystem in C und
C ++. Wenn p
ein Zeiger ist, was ist der Typ von *p
? Wenn ich schreibe
etwas wie *p + *q
, muss der Compiler wissen, ob zu verwenden
Ganzzahlarithmetik oder Fließkommaarithmetik zum Beispiel.
Wie für Ihre zweite Frage: normalerweise, ja, obwohl Sie
Wahrscheinlich muss irgendwo ein reinterpret_cast
drin sein. Jedoch,
Das einzige, was du legal mit deinem int*
machen kannst, ist es
zurück zu einem float*
; Dereferenzierung ist ein undefiniertes Verhalten.
Es gibt einige Ausnahmen für char*
und unsigned char*
. Und
in der Praxis, wenn Sie wissen, was Sie tun, können Sie wegkommen
mit Dingen wie:
Ich mache tatsächlich ähnliche Dinge für einige Arten von niedrigem Niveau
Debugging oder Programmierung; Dinge wie Extrahieren des Exponenten
Feld von einem float
. Ein solcher Code ist jedoch äußerst selten und
beinhaltet formal undefined Verhalten, also müssen Sie was verifizieren
der Compiler tatsächlich, und möglicherweise deaktivieren bestimmte
Optimierungen.
Weil es Informationen darüber gibt, wie Daten interpretiert werden, auf die der Zeiger zeigt.
EX: int * a; Können wir das für die Speicherung der Float-Adresse verwenden?
Durch die C-Typ-Sicherheitsfunktion: Ja, aber nicht direkt, besonders in den letzten Compilern und im Standard (die tendenziell sicherer und sicherer sind)
Warum brauchen wir einen anderen Datentyp zum Speichern der Adresse
?
Das ist eigentlich die richtige Frage, und die Antwort ist darin versteckt - warum wir brauchen einen anderen Datentyp zum Speichern von Adressen. Wir (die Programmierer) brauchen es. Der Maschine ist es egal - eine Nummer ist genau wie die andere.
Wenn Sie eine "Variable" als "Platzhalter" für einige Daten betrachten, gibt es in Programmiersprachen eine Zweiteilung zwischen der Verwendung der Daten selbst und der Verwendung der Variablen. Manchmal benötigen Sie nur die Daten (z. B. müssen Sie es ausdrucken) und manchmal benötigen Sie die Adresse, wo diese Daten gespeichert sind (z. B. können Sie sie ändern). Die meisten Sprachen haben syntaktischen Zucker, der diese beiden Fälle verwirrt und den Variablenbezeichner in verschiedenen Kontexten unterschiedlich behandelt.
Ein solcher Fall geht so: Betrachten Sie die Aussage
%Vor%In diesem Fall sucht der Compiler die Adresse einer mit "a" gekennzeichneten Variablen und schreibt "1" an diese Adresse. Die Kennung "a" könnte auch ein Zeiger sein. Nun schau dir eine andere Sache an:
%Vor%Sie sind nicht beim Vergleichen der Adresse einer mit "a" identifizierten Variablen mit etwas, Sie vergleichen, was an dieser Adresse mit "1" gespeichert ist.
Die verschiedenen "Zeigertypen" gibt es wieder für die Bequemlichkeit der Programmierer: Es ist im Grunde so, dass wir weniger Fehler machen, indem wir falsch auf Daten zugreifen. Schau dir dieses Beispiel an:
%Vor%Standardmäßig ist C sehr entspannt und Sie können normalerweise ein:
%Vor%oder
%Vor%... aber! sizeof (i) == 4 und sizeof (d) == 8, wenn du also den dp-Zeiger dereferenzierst, würdest du versuchen, 8 Bytes von einer Variablen (i) zu lesen, die nur 4 enthält. Das bedeutet, du würdest 4 unvorhersehbar lesen (zufällige) Bytes nach den ersten vier Bytes von i, was definitiv nicht gewünscht ist.
Auch dies alles dient unserer Bequemlichkeit. Der Maschine ist es egal. Beide Zeiger sehen und verhalten sich für die CPU genau gleich.
Tags und Links c c++ operating-system