Dereferenzierung in C

9

Ich habe gerade angefangen, C zu lernen, also sei bitte nett. Von dem was ich bisher bezüglich Zeigern gelesen habe:

%Vor%

Nun, was ich nicht ganz verstehe:

%Vor%

Ähnlich:

%Vor%     
Meda 12.12.2012, 22:36
quelle

3 Antworten

3

Große Frage.

Dein erster Block ist korrekt. Ein Zeiger ist eine Variable, die die Adresse einiger Daten enthält. Der Typ dieses Zeigers teilt dem Code mit, wie er den Inhalt der Adresse interpretiert, die von diesem Zeiger gehalten wird.

Das Konstrukt:

%Vor%

Wird als Deferenzierung eines Zeigers bezeichnet. Das heißt, Sie können auf die Adresse zugreifen, auf die der Zeiger zeigt, und darauf lesen und schreiben wie eine normale Variable. Hinweis:

%Vor%

Das obige ist nur ein mnemotechnisches Gerät, das ich benutze.

Es ist selten, dass Sie einem Zeiger jemals einen numerischen Wert zuweisen ... vielleicht, wenn Sie für eine bestimmte Umgebung entwickeln, die einige 'bekannte' Speicheradressen hat, aber auf Ihrer Ebene, würde ich keine Sorge haben zu viel darüber.

Verwenden Sie

%Vor%

würde letztendlich zu einem Fehler führen. Sie würden versuchen, etwas zu stören, das kein Zeiger ist, so dass Sie wahrscheinlich einen Systemfehler bekommen, weil wer weiß, wohin es zeigt.

&test1 und &test2 sind tatsächlich Zeiger auf test1 und test2 .

Zeiger auf Zeiger sind sehr nützlich und eine Suche nach Zeiger auf einen Zeiger führt Sie zu einigen Ressourcen Das ist viel besser als ich.

    
Dancrumb 12.12.2012, 22:44
quelle
1

Es sieht so aus, als hätten Sie den ersten Teil richtig.

Ein zufälliger Gedanke: Es gibt verschiedene Konventionen darüber, wo dieses * -Zeichen stehen soll. Ich bevorzuge meine mit dem Variablennamen, wie in int *test1 , während andere int* test1 bevorzugen. Ich bin nicht sicher, wie üblich es ist, es in der Mitte schweben zu lassen.

Ein weiterer nebensächlicher Gedanke: test2 = 3.0 weist Floating-Point 3 einen Wert von test2 zu. Das gleiche Ende könnte mit test2=3 erreicht werden, in welchem ​​Fall die 3 implizit von einer ganzen Zahl in eine Gleitkommazahl umgewandelt wird. Die Konvention, die Sie gewählt haben, ist wahrscheinlich in Bezug auf Klarheit sicherer, aber nicht unbedingt notwendig.

Keine Nebenkosten

*test1=3 weist der von test angegebenen Adresse 3 zu.

test1=3 ist eine Zeile, die eine Bedeutung hat, die ich aber für sinnlos halte. Wir wissen nicht, was an Speicherplatz 3 ist, ob es sicher ist, es zu berühren, oder ob wir es berühren dürfen.

Deshalb ist es praktisch, etwas wie

zu verwenden %Vor%

Der Befehl &var gibt den Speicherort von var zurück und speichert ihn in pointy , damit wir später mit *pointy darauf zugreifen können.

Aber ich könnte auch so etwas machen:

%Vor%

Und hier sehen Sie vielleicht etwas wie test1=3 : Zeiger können genau wie Zahlen addiert und subtrahiert werden, so dass Sie Offsets wie diese speichern können.

&test1 ist ein Zeiger auf einen Zeiger, aber das klingt irgendwie verwirrend für mich. Es ist wirklich die Adresse im Speicher, in der der Wert von test1 gespeichert ist. Und test1 speichert zufällig nur die Adresse einer anderen Variablen als Wert. Sobald Sie auf diese Weise an Zeiger denken (Adresse im Speicher, Wert dort gespeichert), wird es einfacher mit ... zu arbeiten ... oder zumindest denke ich das.

Ich weiß nicht, ob *test2 "Bedeutung" an sich hat. Im Prinzip könnte es nützlich sein, wenn wir uns vorstellen, dass der * -Befehl den Wert von test2 als einen Speicherplatz im Speicher annehmen und den dort gefundenen Wert zurückgeben wird. Aber da Sie test2 als Float definieren, ist es schwierig vorherzusagen, wo im Speicher wir landen würden, wenn test2=3 nicht auf den dritten Punkt von irgendwas gesetzt wird (schauen Sie in der IEEE754-Spezifikation nach, warum). Aber ich wäre überrascht, wenn ein Compiler so etwas erlauben würde.

Schauen wir uns ein anderes schnelles Beispiel an:

%Vor%

Sie sehen also, dass Sie Zeiger so aneinander ketten können, so viele hintereinander wie Sie möchten. Dies könnte auftreten, wenn Sie ein Array von Zeigern hätten, das mit den Adressen vieler Strukturen gefüllt wäre, die Sie aus dem dynamischen Speicher erstellt haben, und diese Strukturen enthalten Zeiger auf dynamisch zugewiesene Dinge selbst. Wenn es Zeit wird, einen Zeiger auf einen Zeiger zu verwenden, werden Sie es wahrscheinlich wissen. Für jetzt mach dir keine Sorgen um sie.

    
Richard 12.12.2012 23:09
quelle
1

Lassen Sie uns zunächst etwas Verwirrung stiften: Das Wort "Zeiger" kann sich entweder auf eine Variable (oder ein Objekt) mit einem Zeigertyp oder auf einen Ausdruck mit dem Zeigertyp beziehen. In den meisten Fällen, wenn Leute von "Zeigern" sprechen, meinen sie Zeigervariablen.

Ein Zeiger kann ( muss ) auf ein Ding (ein "Objekt" im Standardsprachgebrauch) zeigen. Es kann nur auf die richtige Art der Sache hinweisen; Ein Zeiger auf int soll nicht sein, um auf ein float-Objekt zu zeigen. Ein Zeiger kann auch NULL sein; In diesem Fall gibt es nichts, worauf man hinweisen könnte.

Ein Pointertyp ist auch ein Typ und ein Zeigerobjekt ist auch ein Objekt. So ist es möglich, einen Zeiger auf Zeiger zu konstruieren: Der Zeiger auf Zeiger speichert nur die Adressen des Zeigerobjekts.

Was ein Zeiger kann nicht sein:

  • Es kann nicht auf einen Wert zeigen: p = &4; ist unmöglich. 4 ist ein Literalwert, der nicht in einem Objekt gespeichert ist und daher keine Adresse hat.
  • Gleiches gilt für Ausdrücke: p = &(1+4); ist unmöglich, weil der Ausdruck "1 + 4" keinen Ort hat.
  • das gleiche gilt für den Rückgabewert p = &sin(pi); ist unmöglich; Der Rückgabewert ist kein Objekt und hat daher keine Adresse.
  • Variablen, die als "register" gekennzeichnet sind (jetzt fast eindeutig), können keine Adresse haben.
  • Sie können die Adresse eines Bitfeldes nicht verwenden, weil diese kleiner sein können als das Zeichen (oder eine feinere Granularität haben), daher wäre es möglich, dass verschiedene Bitmasken dieselbe Adresse haben.

Es gibt einige "Ausnahmen" zum obigen Skelett (Leere Zeiger, Casting, Zeige ein Element über ein Array-Objekt hinaus), aber zur Klarheit Diese sollten als Verfeinerungen / Änderungen gesehen werden, IMHO.

    
wildplasser 12.12.2012 23:52
quelle

Tags und Links