So verwenden Sie C ++ - Zeiger

So verwenden Sie C ++ - Zeiger
Der Speicher eines Computers ist eine lange Reihe von Zellen. Die Größe jeder Zelle wird als Byte bezeichnet. Ein Byte ist ein Raum, der von einem englischen Charakter des Alphabets besetzt ist. Ein Objekt im gewöhnlichen Sinne ist eine aufeinanderfolgende Reihe von Bytes im Gedächtnis. Jede Zelle hat eine Adresse, die eine Ganzzahl ist, die normalerweise in hexadezimaler Form geschrieben ist. Es gibt drei Möglichkeiten, auf ein Objekt im Speicher zugreifen zu können. Auf ein Objekt kann mit einem sogenannten Zeiger zugegriffen werden. Es kann mithilfe einer sogenannten Referenz zugegriffen werden. Es kann weiterhin mit einer Kennung zugegriffen werden. Der Fokus dieses Artikels liegt auf der Verwendung von Zeigern und Referenzen. In C ++ gibt es das spitzen Objekt und das Zeigerobjekt. Das spitze Objekt hat das Interesse des Interesses. Das Zeigerobjekt hat die Adresse zum spitzen Objekt. Das Zeigerobjekt und das spitzen Objekt haben jeweils seine Bezeichnung. Sie müssen grundlegende Kenntnisse in C ++ haben, einschließlich der Kennungen, Funktionen und Arrays. Um diesen Artikel zu verstehen.

Die Adresse des Bedieners, &

Dies ist ein unärer Operator. Wenn es von einer Kennung gefolgt ist, wird die Adresse des Objekts der Kennung zurückgegeben. Betrachten Sie die folgende Erklärung:

int ptdint;

Im Folgenden finden Sie den Code, der folgende Ausdruck, die von PTDINT identifizierte Adresse zurück:

& ptdint

Sie müssen die genaue Adresse (Nummer) nicht wissen, wie Sie codieren.

Der Indirektionoperator *

Dies ist ein unärer Operator im Kontext von Zeigern. Es wird normalerweise vor einer Kennung getippt. Bei Verwendung in einer Erklärung der Kennung ist die Kennung das Zeigerobjekt, das nur die Adresse des spitzen Objekts enthält. Wenn Sie vor dem Zeigerobjektkennung verwendet werden, um etwas zurückzugeben, ist das zurückgegebene Ding der Wert des spitzen Objekts.

Erstellen eines Zeigers

Schauen Sie sich das folgende Codesegment an:

schweben Sie Ptdfloat;
float *ptrfloat;
ptrfoat = &ptdFloat;

Das Segment beginnt mit der Erklärung des spitzen Objekts, Ptdfloat. Ptdfloat ist eine Kennung, die nur ein Float -Objekt identifiziert. Ein tatsächliches Objekt (Wert) hätte ihm zugewiesen werden können, aber in diesem Fall wurde ihm nichts zugewiesen. Als nächstes gibt es im Segment die Erklärung des Zeigerobjekts. Der Indirektionoperator vor dieser Kennung bedeutet, dass er die Adresse eines spitzen Objekts halten muss. Der Objekttyp, float am Anfang der Anweisung, bedeutet, dass das spitzen Objekt ein Float ist. Das Zeigerobjekt ist immer vom gleichen Typ wie das spitzen Objekt. Ptrfoat ist eine Kennung, die nur ein Zeigerobjekt identifiziert.

In der letzten Anweisung des Code wird dem Zeigerobjekt die Adresse des spitzen Objekts zugewiesen. Beachten Sie die Verwendung des Bedienungsadresses, &.

Die letzte Aussage (Zeile) zeigt, dass Sie nach der Deklaration des Zeigerobjekts ohne Initialisierung den Indirektionoperator nicht benötigen, wenn Sie es initialisieren müssen. Tatsächlich ist es ein Syntaxfehler, den Indirektionoperator in der dritten (letzten) Linie zu verwenden.

Das Zeigerobjekt kann durch das spitzen Objekt in einer Anweisung wie folgt deklariert und initialisiert werden:

schweben Sie Ptdfloat;
float *ptrfoat = &ptdFloat;

Die erste Zeile des vorherigen Codesegments und dieser sind gleich. Die zweite und dritte Zeilen des vorherigen Codesegments wurden hier zu einer Anweisung kombiniert.

Beachten Sie im obigen Code, dass bei der Deklaration und Initialisierung des Zeigerobjekts der indirekte Operator verwendet werden muss. Es wird jedoch nicht verwendet, wenn die Initialisierung anschließend durchgeführt werden soll. Das Zeigerobjekt wird mit der Adresse des spitzen Objekts initialisiert.

Im folgenden Codesegment wird der indirekte Operator verwendet, um den Inhalt des spitzen Objekts zurückzugeben.

int ptdint = 5;
int *ptrint = &ptdInt;
Cout << *ptrInt << '\n';

Der Ausgang ist 5.

In der letzten Aussage hier wurde der Indirektionoperator verwendet, um den Wert durch die Zeigerkennung zurückzugeben. Bei Verwendung in einer Erklärung würde der Kennung für den indirekten Operator die Adresse des spitzen Objekts halten. Wenn der Indirektionoperator in Kombination mit dem Zeigerkennung in Kombination mit dem Zeigerkennung verwendet wird.

Einem Zeiger Null zuweisen

Das Zeigerobjekt sollte immer den Typ des spitzen Objekts haben. Bei der Erklärung des Zeigerobjekts muss der Datentyp des spitzen Objekts verwendet werden. Der Wert von Decimal Null kann dem Zeiger jedoch wie im folgenden Codesegment zugeordnet werden:

int ptdint = 5;
int *ptrint;
ptrint = 0;
oder im Segment,
int ptdint = 5;
int *ptrint = 0;

In beiden Fällen wird der Zeiger (Kennung) als Nullzeiger bezeichnet. Das heißt, es weist auf nirgendwo hin. Das heißt, es hat keine Adresse eines spitzen Objekts. Hier ist 0 Dezimal Null und nicht hexadezimaler Null. Hexadezimaler Null würde auf die erste Adresse des Computerspeichers verweisen.

Versuchen Sie nicht, den von einem Nullzeiger gerichteten Wert zu erhalten. Wenn Sie dies versuchen, kann das Programm kompilieren, aber nicht ausführen.

Array -Name als konstantes Zeiger

Betrachten Sie das folgende Array:

int arr [] = 000, 100, 200, 300, 400;

Der Name des Arrays, ARR, ist tatsächlich die Kennung, die die Adresse des ersten Elements des Arrays hat. Der folgende Ausdruck gibt den ersten Wert im Array zurück:

*arr

Mit dem Array verhält sich der Inkrementoperator ++ anders. Anstatt 1 hinzuzufügen, ersetzt es die Adresse des Zeigers durch die Adresse des nächsten Elements im Array. Der Name des Arrays ist jedoch ein konstanter Zeiger; Das heißt, der Inhalt (Adresse) kann nicht geändert oder inkrementiert werden. Um zu erhöhen, muss die Startadresse des Arrays einem nicht konstanten Zeiger wie folgt zugeordnet werden:

int *ptr = arr;

Jetzt kann PTR inkrementiert werden, um auf das nächste Element des Arrays zu verweisen. PTR wurde hier als Zeigerobjekt deklariert. Ohne * hier wäre es kein Zeiger; Es wäre eine Kennung, ein INT -Objekt zu halten und keine Speicheradresse zu halten.

Das folgende Codesegment zeigt schließlich auf das vierte Element:

++ptr;
++ptr;
++ptr;

Der folgende Code gibt den vierten Wert des Arrays aus:

int arr [] = 000, 100, 200, 300, 400;
int *ptr = arr;
++ptr;
++ptr;
++ptr;
Cout << *ptr << '\n';

Die Ausgabe ist 300.

Funktionsname als Kennung

Der Name einer Funktion ist die Kennung der Funktion. Betrachten Sie die folgende Funktionsdefinition:

int fn ()

Cout << "seen" << '\n';
Rückkehr 4;

FN ist die Kennung der Funktion. Der Ausdruck,

& fn

Gibt die Adresse der Funktion im Speicher zurück. FN ist wie das spitzen Objekt. Die folgende Erklärung erklärt einen Zeiger auf eine Funktion:

int (*func) ();

Die Kennung für das spitzen Objekt und die Kennung für das Zeigerobjekt sind unterschiedlich. Func ist ein Zeiger auf eine Funktion. FN ist die Kennung einer Funktion. Und so kann Func wie folgt auf FN verweisen:

func = &fn;

Der Wert (Inhalt) des Func ist die Adresse von FN. Die beiden Kennungen könnten wie folgt mit einer Initialisierungsanweisung in Verbindung gebracht werden:

int (*func) () = &fn;

Beachten Sie die Unterschiede und Ähnlichkeiten in den Hinweisen zur Handhabungsfunktion und der Skalarzeiger. Func ist ein Zeiger auf eine Funktion; Es ist das spitzen Objekt; Es wird anders als ein Skalarzeiger deklariert.

Die Funktion kann aufgerufen werden mit,

fn ()
oder
func ()

Es kann nicht mit *func () aufgerufen werden.

Wenn die Funktion Parameter hat, haben die zweiten Klammern die Arten der Parameter und müssen nicht die Kennungen für die Parameter haben. Das folgende Programm zeigt dies:

#enthalten
Verwenden von Namespace STD;
float fn (float fl, int in)

return fl;

int main ()

float (*func) (float, int) = &fn;
float val = func (2.5, 6);
Cout << val << '\n';
Rückkehr 0;

Der Ausgang ist 2.5.

C ++ Referenz

Die Referenzierung in C ++ ist nur eine Möglichkeit, ein Synonym (ein anderer Name) für eine Kennung zu erstellen. Es verwendet den & Operator, aber nicht auf die gleiche Weise wie und wird für Zeiger verwendet. Betrachten Sie das folgende Codesegment:

int myint = 8;
int & yourInt = myint;
Cout << myInt << '\n';
Cout << yourInt << '\n';

Die Ausgabe ist:

8
8

Die erste Aussage initialisiert die Kennung Myint; ich.e. myint wird deklariert und gemacht, um den Wert zu halten, 8. Die zweite Aussage macht eine neue Kennung, Sie sind ein Synonym für MyInt. Um dies zu erreichen, wird der & Operator zwischen dem Datentyp und dem neuen Kennung in der Deklaration platziert. Die Cout -Aussagen zeigen, dass die beiden Kennungen Synonyme sind. Um den Wert in diesem Fall zurückzugeben, müssen Sie ihm nicht mit * vorausgehen . Verwenden Sie einfach die Kennung.

myint und dein hier sind keine zwei verschiedenen Objekte. Es handelt sich um zwei verschiedene Identifikatoren (identifizieren) denselben Ort im Speicher mit dem Wert 8, 8. Wenn sich der Wert von MyInt geändert hat, ändert sich der Wert von YourInt auch automatisch. Wenn sich der Wert Ihres Int geändert hat, ändert sich der Wert von MyInt auch automatisch.

Referenzen sind vom gleichen Typ.

Verweis auf eine Funktion

So wie Sie einen Verweis auf einen Skalar haben können, können Sie auch einen Verweis auf eine Funktion haben. Das Codieren einer Referenz auf eine Funktion unterscheidet sich jedoch von der Codierung einer Referenz auf einen Skalar. Das folgende Programm zeigt dies:

#enthalten
Verwenden von Namespace STD;
float fn (float fl, int in)

return fl;

int main ()

float (& func) (float, int) = fn;
float val = func (2.5, 6);
Cout << val << '\n';
Rückkehr 0;

Der Ausgang ist 2.5.

Beachten Sie die erste Anweisung in der Hauptfunktion, die Func zu einem Synonym für FN macht. Beide verweisen auf dieselbe Funktion. Beachten Sie die Einzelnutzung und Position von & &. So & ist hier und nicht der Referenzbetreiber hier und nicht der Bedieneradresse. Um die Funktion aufzurufen, verwenden Sie einfach einen der einen Namen.

Eine Referenzkennung ist nicht dasselbe wie eine Zeigerkennung.

Funktion, die einen Zeiger zurückgibt

Im folgenden Programm gibt die Funktion einen Zeiger zurück, der die Adresse des spitzen Objekts ist:

#enthalten
Verwenden von Namespace STD;
float *fn (float fl, int in)

float *fll = &fl;
return fll;

int main ()

float *val = fn (2.5, 6);
Cout << *val << '\n';
Rückkehr 0;

Der Ausgang ist 2.5

Die erste Anweisung in der Funktion, FN (), besteht nur dazu, ein Zeigerobjekt zu erstellen. Beachten Sie die Einzelnutzung und Position von * in der Funktionssignatur. Beachten Sie auch, wie der Zeiger (Adresse) in der Funktion main () von einem anderen Zeigerobjekt empfangen wurde.

Funktion, die eine Referenz zurückgibt

Im folgenden Programm gibt die Funktion eine Referenz zurück:

#enthalten
Verwenden von Namespace STD;
float & fn (float fl, int in)

float & frr = fl;
return frr;

int main ()

float & val = fn (2.5, 6);
Cout << val << '\n';
Rückkehr 0;

Der Ausgang ist 2.5.

Die erste Anweisung in der Funktion, FN (), ist nur, um eine Referenz zu erstellen. Beachten Sie die Einzelnutzung und Position von & in der Funktionssignatur. Beachten Sie auch, wie die Referenz in der Funktion main () durch eine andere Referenz empfangen wurde.

Übergeben eines Zeigers an eine Funktion

Im folgenden Programm wird ein Zeiger, der tatsächlich die Adresse eines schwebenden spitzen Objekts ist, als Argument an die Funktion gesendet:

#enthalten
Verwenden von Namespace STD;
float fn (float *fl, int in)

return *fl;

int main ()

float v = 2.5;
float val = fn (& v, 6);
Cout << val << '\n';
Rückkehr 0;

Der Ausgang ist 2.5

Beachten Sie die Verwendung und Position von * für den Float -Parameter in der Funktionssignatur. Sobald die Bewertung der FN () -Funktion beginnt, wird die folgende Erklärung abgegeben:

float *fl = & v;

Sowohl FL als auch & V zeigen auf das gleiche spitzen Objekt, das 2 enthält.5. *FL bei der Rückgabeerklärung ist keine Erklärung; Es bedeutet, dass der Wert des spitzen Objekts vom Zeigerobjekt angezeigt wird.

Übergeben eines Verweiss auf eine Funktion

Im folgenden Programm wird eine Referenz als Argument an die Funktion gesendet:

#enthalten
Verwenden von Namespace STD;
float fn (float & fl, int in)

return fl;

int main ()

float v = 2.5;
float val = fn (v, 6);
Cout << val << '\n';
Rückkehr 0;

Der Ausgang ist 2.5

Beachten Sie die Verwendung und Position des und für den Float -Parameter in der Funktionssignatur. Sobald die Bewertung der FN () -Funktion beginnt, wird die folgende Erklärung abgegeben:

float & fl = v;

Ein Array an eine Funktion übergeben

Das folgende Programm zeigt, wie ein Array an eine Funktion übergeht:

#enthalten
Verwenden von Namespace STD;
int fn (int arra [])

arra zurückgeben [2];

int main ()

int arr [] = 000, 100, 200, 300, 400;
int val = fn (arr);
Cout << val << '\n';
Rückkehr 0;

Die Ausgabe ist 200.

In diesem Programm ist es das Array, das übergeben wird. Beachten Sie, dass der Parameter der Funktionssignatur eine leere Array -Deklaration hat. Das Argument im Funktionsaufruf ist nur der Name eines erstellten Arrays.

Kann eine C ++ - Funktion ein Array zurückgeben??

Eine Funktion in C ++ kann den Wert eines Arrays zurückgeben, kann das Array jedoch nicht zurückgeben. Das Kompilieren des folgenden Programms führt zu einer Fehlermeldung:

#enthalten
Verwenden von Namespace STD;
int fn (int arra [])

arra zurückgeben;

int main ()

int arr [] = 000, 100, 200, 300, 400;
int val = fn (arr);
Rückkehr 0;

Zeiger eines Zeigers

Ein Zeiger kann auf einen anderen Zeiger verweisen. Das heißt, ein Zeigerobjekt kann die Adresse eines anderen Zeigerobjekts haben. Sie müssen immer noch alle vom gleichen Typ sein. Das folgende Codesegment zeigt dies:

int ptdint = 5;
int *ptrint = &ptdInt;
int ** ptrptrint = &ptrInt;
Cout << **ptrptrInt << '\n';

Der Ausgang ist 5.

In der Deklaration von Zeiger-auf-Zeiger wird doppelt * verwendet. Um den Wert des endgültigen spitzen Objekts zurückzugeben, wird doppelt * noch verwendet.

Spitze von Zeigern

Das folgende Programm zeigt, wie Sie eine Reihe von Zeigern codieren:

#enthalten
Verwenden von Namespace STD;
int main ()

int num0 = 000, num1 = 100, num2 = 200, num3 = 300, num4 = 400;
int *no0 = & num0, *no1 = & num1, *no2 = & num2, *no3 = & num3, *no4 =&num4;
int *arr [] = NO0, NO1, NO2, NO3, NO4;
Cout << *arr[4] << '\n';
Rückkehr 0;

Die Ausgabe ist:

400

Beachten Sie die Verwendung und Position von * in der Erklärung des Arrays. Beachten Sie die Verwendung von * bei der Rückgabe eines Wertes im Array. Mit Zeigern von Zeigern sind zwei * beteiligt. Im Falle von Hinweisen wurde bereits eine * gepflegt, da der Array -Kennung ein Zeiger ist.

Array von Saiten variabler Länge

Ein String -Literal ist eine Konstante, die einen Zeiger zurückgibt. Eine Reihe von Strings aus variabler Länge ist eine Reihe von Zeigern. Jeder Wert im Array ist ein Zeiger. Zeiger sind Adressen an Speicherstandorte und sind von gleicher Größe. Die Saiten der verschiedenen Längen befinden sich an anderer Stelle im Speicher, nicht im Array. Das folgende Programm zeigt die Verwendung:

#enthalten
Verwenden von Namespace STD;
int main ()

const char *arr [] = "Frau", "Junge", "Mädchen", "Erwachsener";
Cout << arr[2] << '\n';
Rückkehr 0;

Die Ausgabe ist "Mädchen".

Die Erklärung des Arrays beginnt mit dem reservierten Wort „const“ für Konstante; gefolgt von „char“ für den Charakter, dann das Sternchen *, um anzuzeigen, dass jedes Element ein Zeiger ist. Um eine Zeichenfolge aus dem Array zurückzugeben, wird * aufgrund der impliziten Natur des Zeigers jeder Zeichenfolge nicht verwendet. Wenn * verwendet wird, wird das erste Element der Zeichenfolge zurückgegeben.

Zeiger auf eine Funktion, die einen Zeiger zurückgibt

Das folgende Programm zeigt, wie ein Zeiger auf eine Funktion, die einen Zeiger zurückgibt, codiert wird:

#enthalten
Verwenden von Namespace STD;
int *fn ()

int num = 4;
int *inter = #
return inter;

int main ()

int *( *func) () = &fn;
int val = *func ();
Cout << val << '\n';
Rückkehr 0;

Die Ausgabe ist 4.

Die Erklärung eines Zeigers auf eine Funktion, die einen Zeiger zurückgibt. Die erste Aussage in der Funktion main () zeigt dies. Um die Funktion mit dem Zeiger aufzurufen, gehen Sie mit * vor, um sie mit * vorzunehmen.

Abschluss

Um einen Zeiger auf einen Skalar zu erstellen, tun Sie so etwas wie,

float spitz;
Float *Zeiger = &pointed;

* hat zwei Bedeutungen: In einer Erklärung zeigt es einen Zeiger an; Um etwas zurückzugeben, ist es für den Wert des spitzen Objekts.

Der Array -Name ist ein konstanter Zeiger auf das erste Element des Arrays.

Um einen Zeiger auf eine Funktion zu erstellen, können Sie dies tun,

int (*func) () = &fn;

Wo fn () eine Funktion ist, die an anderer Stelle definiert ist und der Func ist der Zeiger.

& hat zwei Bedeutungen: In einer Deklaration zeigt es eine Referenz (Synonym) auf dasselbe Objekt wie eine andere Kennung an. Wenn Sie etwas zurückgeben, bedeutet dies die Adresse der Adresse.

Um einen Verweis auf eine Funktion zu erstellen, können Sie dies tun,

float (& reffunc) (float, int) = fn;

wo fn () eine Funktion ist, die an anderer Stelle definiert ist, und Reffunc ist die Referenz.

Wenn eine Funktion einen Zeiger zurückgibt, muss der zurückgegebene Wert von einem Zeiger empfangen werden. Wenn eine Funktion eine Referenz zurückgibt, muss der zurückgegebene Wert durch eine Referenz empfangen werden.

Wenn Sie einen Zeiger an eine Funktion übergeben, ist der Parameter eine Erklärung, während das Argument die Adresse eines spitzen Objekts ist. Wenn Sie eine Referenz auf eine Funktion übergeben, ist der Parameter eine Erklärung, während das Argument die Referenz ist.

Beim Übergeben eines Arrays an eine Funktion ist der Parameter eine Erklärung, während das Argument der Array -Name ohne [] ist, ohne []. Die C ++ - Funktion gibt kein Array zurück.

Ein Zeiger-auf-Zeiger benötigt gegebenenfalls zwei * anstelle eines anstelle eines, gegebenenfalls.