Warum brauchen wir einen anderen Datentyp für den Zeiger?

7
  1. Im Grunde ist der Zeiger eine Variable, die zum Speichern der Speicheradresse verwendet wird, die immer ein
    ist hexadezimal (Speicheradresse) Warum brauchen wir dann einen anderen Datentyp zum Speichern der Adresse?
  2. EX: int * a; Können wir das zum Speichern der Float-Adresse verwenden?
user2866139 10.10.2013, 09:38
quelle

5 Antworten

10

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.

    
Luchian Grigore 10.10.2013 09:40
quelle
6

Zwei Gründe:

  1. 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.

  2. 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.

Barmar 10.10.2013 09:44
quelle
3

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:

%Vor%

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.

    
James Kanze 10.10.2013 09:52
quelle
2

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)

    
LeleDumbo 10.10.2013 09:42
quelle
1
  

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.

    
Ivan Voras 10.10.2013 10:11
quelle

Tags und Links