Nein, keine Hausaufgaben ... wollte nur wissen ... weil ich es oft sehe, wenn ich C-Code lese.
1
Ein Zeiger auf Zeiger ist kein Sonderfall von etwas, daher verstehe ich nicht, was Sie über void ** nicht verstehen.
Akappa
Für 2D-Arrays ist das beste Beispiel, dass die Befehlszeilenargumente "prog arg1 arg2" char ** argv gespeichert sind. Und wenn der Anrufer den Speicher nicht zuordnen möchte (die aufgerufene Funktion ordnet den Speicher zu)
Ergebnisweg
1
Sie haben ein schönes Beispiel für die Verwendung von "Zeiger auf Zeiger" in Git 2.0: siehe meine Antwort unten
VonC
Antworten:
359
Nehmen wir einen 8-Bit-Computer mit 8-Bit-Adressen (und damit nur 256 Byte Speicher) an. Dies ist Teil dieses Speichers (die Zahlen oben sind die Adressen):
54555657585960616263646566676869+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+||58|||63||55||| h | e | l | l | o | \0 ||+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
Was Sie hier sehen können, ist, dass bei Adresse 63 die Zeichenfolge "Hallo" beginnt. Wenn dies in diesem Fall das einzige Vorkommen von "Hallo" im Speicher ist, dann
constchar*c ="hello";
... definiert cals Zeiger auf die (schreibgeschützte) Zeichenfolge "Hallo" und enthält somit den Wert 63. cmuss selbst irgendwo gespeichert werden: im obigen Beispiel an Position 58. Natürlich können wir nicht nur auf Zeichen zeigen , sondern auch auf andere Hinweise. Z.B:
constchar**cp =&c;
Zeigt nun cpauf c, das heißt, es enthält die Adresse von c(die 58 ist). Wir können noch weiter gehen. Erwägen:
constchar***cpp =&cp;
cppSpeichert jetzt die Adresse von cp. Es hat also den Wert 55 (basierend auf dem obigen Beispiel), und Sie haben es erraten: Es ist selbst unter der Adresse 60 gespeichert.
In Bezug auf , warum ein Zeiger auf Zeiger verwendet:
Der Name eines Arrays ergibt normalerweise die Adresse seines ersten Elements. Wenn das Array also Elemente vom Typ enthält t, hat ein Verweis auf das Array den Typ t *. Betrachten Sie nun ein Array von Arrays vom Typ t: Natürlich hat ein Verweis auf dieses 2D-Array den Typ (t *)*= t **und ist daher ein Zeiger auf einen Zeiger.
Obwohl ein Array von Strings eindimensional klingt, ist es tatsächlich zweidimensional, da Strings Zeichenarrays sind. Daher : char **.
Eine Funktion fmuss ein Argument vom Typ akzeptieren, t **wenn eine Variable vom Typ geändert werden soll t *.
Viele andere Gründe, die zu zahlreich sind, um sie hier aufzulisten.
Ja, gutes Beispiel. Ich verstehe, was sie sind. Aber wie und wann man sie verwendet, ist wichtiger. Jetzt.
2
Stephan hat im Grunde genommen das Diagramm in Kernighan & Richies Programmiersprache The C gut reproduziert. Wenn Sie C programmieren und dieses Buch nicht haben und mit Papierdokumentation cool sind, empfehle ich Ihnen dringend, es zu bekommen. Die (ziemlich) bescheidenen Kosten machen sich sehr schnell in der Produktivität bezahlt. Es neigt dazu, in seinen Beispielen sehr klar zu sein.
J. Polfer
4
char * c = "Hallo" sollte const char * c = "Hallo" sein. Es ist auch höchstens irreführend zu sagen, dass "ein Array als Adresse des ersten Elements gespeichert ist". Ein Array wird als ... Array gespeichert. Oft gibt sein Name einen Zeiger auf sein erstes Element, aber nicht immer. Über Zeiger auf Zeiger würde ich einfach sagen, dass sie nützlich sind, wenn eine Funktion einen als Parameter übergebenen Zeiger ändern muss (dann übergeben Sie stattdessen einen Zeiger auf den Zeiger).
Bastien Léonard
4
Wenn ich diese Antwort nicht falsch interpretiere, sieht sie falsch aus. c wird bei 58 gespeichert und zeigt auf 63, cp wird bei 55 gespeichert und zeigt auf 58, und cpp ist im Diagramm nicht dargestellt.
Thanatos
1
Sieht gut aus. Als kleines Problem war alles, was mich davon abhielt zu sagen: Großartiger Beitrag. Die Erklärung selbst war ausgezeichnet. Wechsel zu einer Abstimmung. (Vielleicht muss Stackoverflow Zeiger überprüfen?)
Thanatos
46
Wie funktionieren Zeiger auf Zeiger in C?
Zunächst ist ein Zeiger wie jede andere Variable eine Variable, die jedoch die Adresse einer Variablen enthält.
Ein Zeiger auf einen Zeiger ist wie jede andere Variable eine Variable, die jedoch die Adresse einer Variablen enthält. Diese Variable ist zufällig ein Zeiger.
Wann würden Sie sie verwenden?
Sie können sie verwenden, wenn Sie einen Zeiger auf einen Speicher auf dem Heap zurückgeben müssen, aber nicht den Rückgabewert verwenden.
Beispiel:
int getValueOf5(int*p){*p =5;return1;//success}int get1024HeapMemory(int**p){*p = malloc(1024);if(*p ==0)return-1;//errorelsereturn0;//success}
Und du nennst es so:
int x;
getValueOf5(&x);//I want to fill the int varaible, so I pass it's address in//At this point x holds 5int*p;
get1024HeapMemory(&p);//I want to fill the int* variable, so I pass it's address in//At this point p holds a memory address where 1024 bytes of memory is allocated on the heap
Es gibt auch andere Verwendungszwecke, z. B. hat das Argument main () jedes C-Programms einen Zeiger auf einen Zeiger für argv, wobei jedes Element ein Array von Zeichen enthält, die die Befehlszeilenoptionen darstellen. Sie müssen jedoch vorsichtig sein, wenn Sie Zeiger von Zeigern verwenden, um auf zweidimensionale Arrays zu zeigen. Es ist besser, stattdessen einen Zeiger auf ein zweidimensionales Array zu verwenden.
Hier ist ein Beispiel für einen Zeiger auf ein zweidimensionales Array, das ordnungsgemäß ausgeführt wurde:
int(*myPointerTo2DimArray)[ROWS][COLUMNS]
Sie können jedoch keinen Zeiger auf ein zweidimensionales Array verwenden, wenn Sie eine variable Anzahl von Elementen für ROWS und COLUMNS unterstützen möchten. Aber wenn Sie vorher wissen, würden Sie ein zweidimensionales Array verwenden.
Ich mag dieses "reale" Codebeispiel für die Verwendung von Zeigern auf Zeiger in Git 2.0, Commit 7b1004b :
Linus hat einmal gesagt:
Ich wünschte tatsächlich, mehr Menschen würden die wirklich grundlegende Art der Codierung auf niedriger Ebene verstehen. Keine großen, komplexen Dinge wie die Suche nach sperrenlosen Namen, sondern einfach eine gute Verwendung von Zeigern zu Zeigern usw.
Ich habe zum Beispiel zu viele Leute gesehen, die einen einfach verknüpften Listeneintrag löschen, indem sie den Eintrag "prev" verfolgen , und dann, um den Eintrag zu löschen, tun Sie so etwas
und wenn ich solchen Code sehe, gehe ich einfach zu "Diese Person versteht keine Zeiger". Und es ist leider ziemlich häufig.
Personen, die Zeiger verstehen, verwenden einfach einen " Zeiger auf den Eintragszeiger " und initialisieren diesen mit der Adresse des Listenkopfs. Und dann, wenn sie die Liste durchlaufen, können sie den Eintrag ohne Verwendung von Bedingungen entfernen, indem sie einfach a ausführen
*pp = entry->next
Wenn wir diese Vereinfachung anwenden, verlieren wir 7 Zeilen aus dieser Funktion, selbst wenn wir 2 Kommentarzeilen hinzufügen.
Sie müssen von Anfang bis Ende darüber iterieren und ein bestimmtes Element entfernen, dessen Wert dem Wert von to_remove entspricht.
Der naheliegendste Weg, dies zu tun, wäre:
list_entry *entry = head;/* assuming head exists and is the first entry of the list */
list_entry *prev = NULL;while(entry){/* line 4 */if(entry->val == to_remove)/* this is the one to remove ; line 5 */if(prev)
prev->next = entry->next;/* remove the entry ; line 7 */else
head = entry->next;/* special case - first entry ; line 9 *//* move on to the next entry */
prev = entry;
entry = entry->next;}
Was wir oben tun, ist:
Durchlaufen der Liste bis zum Eintrag NULL, was bedeutet, dass wir das Ende der Liste erreicht haben (Zeile 4).
Wenn wir auf einen Eintrag stoßen, den wir entfernen möchten (Zeile 5),
Wir weisen den Wert des aktuellen nächsten Zeigers dem vorherigen zu.
Dadurch wird das aktuelle Element eliminiert (Zeile 7).
Es gibt oben einen Sonderfall: Zu Beginn der Iteration gibt es keinen vorherigen Eintrag ( previs NULL). Um den ersten Eintrag in der Liste zu entfernen, müssen Sie den Kopf selbst ändern (Zeile 9).
Was Linus sagte, ist, dass der obige Code vereinfacht werden könnte, indem das vorherige Element zu einem Zeiger auf einen Zeiger und nicht nur zu einem Zeiger gemacht wird .
Der Code sieht dann so aus:
Der obige Code ist der vorherigen Variante sehr ähnlich, aber beachten Sie, dass wir nicht mehr auf den Sonderfall des ersten Elements der Liste achten müssen, da er ppnicht NULLam Anfang steht. Einfach und clever.
Außerdem hat jemand in diesem Thread kommentiert, dass der Grund dafür besser ist, weil *pp = entry->nextes atomar ist. Es ist mit Sicherheit NICHT atomar .
Der obige Ausdruck enthält zwei Dereferenzierungsoperatoren ( *und ->) und eine Zuweisung, und keines dieser drei Dinge ist atomar. Dies ist ein weit verbreitetes Missverständnis, aber leider sollte so gut wie nichts in C als atomar angenommen werden (einschließlich der ++und --Operatoren)!
@ Kumar gute Referenz. Ich habe es in die Antwort für mehr Sichtbarkeit aufgenommen.
VonC
Dieses Video war für mich wichtig, um Ihr Beispiel zu verstehen. Insbesondere war ich verwirrt (und kriegerisch), bis ich ein Speicherdiagramm zeichnete und den Fortschritt des Programms verfolgte. Trotzdem scheint es mir immer noch etwas mysteriös.
Chris
@ Chris Tolles Video, danke, dass du es erwähnt hast! Ich habe Ihren Kommentar zur besseren Sichtbarkeit in die Antwort aufgenommen.
VonC
14
Als wir Hinweise auf einen Programmierkurs an der Universität gaben, erhielten wir zwei Hinweise, wie wir anfangen sollten, etwas über sie zu lernen. Das erste war, Pointer Fun With Binky anzusehen . Das zweite war, über die Passage der Haddocks 'Eyes aus Lewis Carrolls Through the Looking-Glass nachzudenken
"Du bist traurig", sagte der Ritter in einem besorgten Ton: "Lass mich dir ein Lied singen, um dich zu trösten."
"Ist es sehr lang?" Fragte Alice, denn sie hatte an diesem Tag viel Poesie gehört.
„Es ist lang“, sagte der Ritter, „aber es ist sehr, sehr schön. Jeder, der mich singen hört - entweder bringt es die Tränen in die Augen oder sonst - “
"Oder was?" sagte Alice, denn der Ritter hatte plötzlich eine Pause gemacht.
„Oder auch nicht, weißt du? Der Name des Songs heißt 'Haddocks' Eyes '. "
"Oh, das ist der Name des Liedes, oder?", Sagte Alice und versuchte sich interessiert zu fühlen.
„Nein, du verstehst nicht“, sagte der Ritter und sah ein wenig verärgert aus. „So heißt der Name. Der Name ist wirklich "The Aged Aged Man". "
"Dann hätte ich sagen sollen 'So heißt das Lied'?" Alice korrigierte sich.
„Nein, das solltest du nicht: das ist eine ganz andere Sache! Das Lied heißt 'Ways And Means': aber so heißt es nur, weißt du! “
"Nun, was ist das Lied dann?" sagte Alice, die zu diesem Zeitpunkt völlig verwirrt war.
"Ich kam dazu", sagte der Ritter. "Das Lied ist wirklich 'A -itting On A Gate': und die Melodie ist meine eigene Erfindung."
Wenn ein Verweis auf einen Zeiger erforderlich ist. Zum Beispiel, wenn Sie den Wert (Adresse, auf die gezeigt wird) einer Zeigervariablen ändern möchten, die im Bereich einer aufrufenden Funktion innerhalb einer aufgerufenen Funktion deklariert ist.
Wenn Sie einen einzelnen Zeiger als Argument übergeben, ändern Sie lokale Kopien des Zeigers, nicht den ursprünglichen Zeiger im aufrufenden Bereich. Mit einem Zeiger auf einen Zeiger ändern Sie letzteren.
Ein Zeiger auf einen Zeiger wird auch als Handle bezeichnet . Eine Verwendung dafür ist häufig, wenn ein Objekt im Speicher verschoben oder entfernt werden kann. Oft ist man dafür verantwortlich, die Nutzung des Objekts zu sperren und zu entsperren damit es beim Zugriff nicht verschoben wird.
Es wird häufig in Umgebungen mit eingeschränktem Speicher verwendet, z. B. unter Palm OS.
Betrachten Sie die folgende Abbildung und das folgende Programm, um dieses Konzept besser zu verstehen .
Gemäß der Abbildung ist ptr1 ein einzelner Zeiger mit der Adresse der Variablen num .
ptr1 =#
In ähnlicher Weise ist ptr2 ein Zeiger auf einen Zeiger (Doppelzeiger), der die Adresse des Zeigers ptr1 hat .
ptr2 =&ptr1;
Ein Zeiger, der auf einen anderen Zeiger zeigt, wird als Doppelzeiger bezeichnet. In diesem Beispiel ist ptr2 ein Doppelzeiger.
Werte aus obigem Diagramm:
Address of variable num has :1000Address of Pointer ptr1 is:2000Address of Pointer ptr2 is:3000
Beispiel:
#include<stdio.h>int main (){int num =10;int*ptr1;int**ptr2;// Take the address of var
ptr1 =#// Take the address of ptr1 using address of operator &
ptr2 =&ptr1;// Print the value
printf("Value of num = %d\n", num );
printf("Value available at *ptr1 = %d\n",*ptr1 );
printf("Value available at **ptr2 = %d\n",**ptr2);}
Ausgabe:
Value of num =10Value available at *ptr1 =10Value available at **ptr2 =10
Es ist ein Zeiger auf den Adresswert des Zeigers. (das ist schrecklich, ich weiß)
Grundsätzlich können Sie einen Zeiger auf den Wert der Adresse eines anderen Zeigers übergeben, sodass Sie ändern können, wohin ein anderer Zeiger von einer Unterfunktion zeigt, z.
Ein aussagekräftiges Beispiel für someType ** ist ein zweidimensionales Array: Sie haben ein Array, das mit Zeigern auf andere Arrays gefüllt ist, also beim Schreiben
dpointer [5] [6]
Sie greifen auf das Array zu, das Zeiger auf andere Arrays an seiner 5. Position enthält, erhalten den Zeiger (lassen Sie fpointer seinen Namen) und greifen dann auf das 6. Element des Arrays zu, auf das auf dieses Array verwiesen wird (also fpointer [6]).
Zeiger auf Zeiger sollten nicht mit Arrays von Rang 2 verwechselt werden, z. B. int x [10] [10], wo Sie x [5] [6] schreiben, greifen Sie auf den Wert im Array zu.
Pete Kirkham
Dies ist nur ein Beispiel, bei dem eine Leere ** angemessen ist. Ein Zeiger auf Zeiger ist nur ein Zeiger, der auf einen Zeiger zeigt.
Akappa
1
So funktioniert es: Es ist eine Variable, die einen anderen Zeiger speichern kann.
Wann würden Sie sie verwenden: Viele verwenden eine davon, wenn Ihre Funktion ein Array erstellen und an den Aufrufer zurückgeben möchte.
//returns the array of roll nos {11, 12} through paramater// return value is total number of studentsint fun(int**i ){int*j;*i =(int*)malloc (2*sizeof(int));**i =11;// e.g., newly allocated memory 0x2000 store 11
j =*i;
j++;*j =12;;// e.g., newly allocated memory 0x2004 store 12return2;}int main(){int*i;int n = fun(&i );// hey I don't know how many students are in your class please send all of their roll numbers.for(int j=0; j<n; j++)
printf("roll no = %d \n", i[j]);return0;}
Es gibt so viele nützliche Erklärungen, aber ich habe nicht nur eine kurze Beschreibung gefunden, also ..
Grundsätzlich ist der Zeiger die Adresse der Variablen. Kurzer Zusammenfassungscode:
int a,*p_a;//declaration of normal variable and int pointer variable
a =56;//simply assign value
p_a =&a;//save address of "a" to pointer variable*p_a =15;//override the value of the variable//print 0xfoo and 15 //- first is address, 2nd is value stored at this address (that is called dereference)
printf("pointer p_a is having value %d and targeting at variable value %d", p_a,*p_a);
Antworten:
Nehmen wir einen 8-Bit-Computer mit 8-Bit-Adressen (und damit nur 256 Byte Speicher) an. Dies ist Teil dieses Speichers (die Zahlen oben sind die Adressen):
Was Sie hier sehen können, ist, dass bei Adresse 63 die Zeichenfolge "Hallo" beginnt. Wenn dies in diesem Fall das einzige Vorkommen von "Hallo" im Speicher ist, dann
... definiert
c
als Zeiger auf die (schreibgeschützte) Zeichenfolge "Hallo" und enthält somit den Wert 63.c
muss selbst irgendwo gespeichert werden: im obigen Beispiel an Position 58. Natürlich können wir nicht nur auf Zeichen zeigen , sondern auch auf andere Hinweise. Z.B:Zeigt nun
cp
aufc
, das heißt, es enthält die Adresse vonc
(die 58 ist). Wir können noch weiter gehen. Erwägen:cpp
Speichert jetzt die Adresse voncp
. Es hat also den Wert 55 (basierend auf dem obigen Beispiel), und Sie haben es erraten: Es ist selbst unter der Adresse 60 gespeichert.In Bezug auf , warum ein Zeiger auf Zeiger verwendet:
t
, hat ein Verweis auf das Array den Typt *
. Betrachten Sie nun ein Array von Arrays vom Typt
: Natürlich hat ein Verweis auf dieses 2D-Array den Typ(t *)*
=t **
und ist daher ein Zeiger auf einen Zeiger.char **
.f
muss ein Argument vom Typ akzeptieren,t **
wenn eine Variable vom Typ geändert werden sollt *
.quelle
Wie funktionieren Zeiger auf Zeiger in C?
Zunächst ist ein Zeiger wie jede andere Variable eine Variable, die jedoch die Adresse einer Variablen enthält.
Ein Zeiger auf einen Zeiger ist wie jede andere Variable eine Variable, die jedoch die Adresse einer Variablen enthält. Diese Variable ist zufällig ein Zeiger.
Wann würden Sie sie verwenden?
Sie können sie verwenden, wenn Sie einen Zeiger auf einen Speicher auf dem Heap zurückgeben müssen, aber nicht den Rückgabewert verwenden.
Beispiel:
Und du nennst es so:
Es gibt auch andere Verwendungszwecke, z. B. hat das Argument main () jedes C-Programms einen Zeiger auf einen Zeiger für argv, wobei jedes Element ein Array von Zeichen enthält, die die Befehlszeilenoptionen darstellen. Sie müssen jedoch vorsichtig sein, wenn Sie Zeiger von Zeigern verwenden, um auf zweidimensionale Arrays zu zeigen. Es ist besser, stattdessen einen Zeiger auf ein zweidimensionales Array zu verwenden.
Warum ist es gefährlich?
Hier ist ein Beispiel für einen Zeiger auf ein zweidimensionales Array, das ordnungsgemäß ausgeführt wurde:
Sie können jedoch keinen Zeiger auf ein zweidimensionales Array verwenden, wenn Sie eine variable Anzahl von Elementen für ROWS und COLUMNS unterstützen möchten. Aber wenn Sie vorher wissen, würden Sie ein zweidimensionales Array verwenden.
quelle
Ich mag dieses "reale" Codebeispiel für die Verwendung von Zeigern auf Zeiger in Git 2.0, Commit 7b1004b :
Chris weist in den Kommentaren zum 2016er Video " Linus Torvalds 'Double Pointer Problem " von Philip Buuck darauf hin .
Kumar weist in den Kommentaren auf den Blog-Beitrag " Linus über das Verstehen von Zeigern " hin, in dem Grisha Trubetskoy erklärt:
quelle
Als wir Hinweise auf einen Programmierkurs an der Universität gaben, erhielten wir zwei Hinweise, wie wir anfangen sollten, etwas über sie zu lernen. Das erste war, Pointer Fun With Binky anzusehen . Das zweite war, über die Passage der Haddocks 'Eyes aus Lewis Carrolls Through the Looking-Glass nachzudenken
quelle
Vielleicht möchten Sie dies lesen: Zeiger auf Zeiger
Ich hoffe, dies hilft, einige grundlegende Zweifel zu klären.
quelle
Wenn ein Verweis auf einen Zeiger erforderlich ist. Zum Beispiel, wenn Sie den Wert (Adresse, auf die gezeigt wird) einer Zeigervariablen ändern möchten, die im Bereich einer aufrufenden Funktion innerhalb einer aufgerufenen Funktion deklariert ist.
Wenn Sie einen einzelnen Zeiger als Argument übergeben, ändern Sie lokale Kopien des Zeigers, nicht den ursprünglichen Zeiger im aufrufenden Bereich. Mit einem Zeiger auf einen Zeiger ändern Sie letzteren.
quelle
Ein Zeiger auf einen Zeiger wird auch als Handle bezeichnet . Eine Verwendung dafür ist häufig, wenn ein Objekt im Speicher verschoben oder entfernt werden kann. Oft ist man dafür verantwortlich, die Nutzung des Objekts zu sperren und zu entsperren damit es beim Zugriff nicht verschoben wird.
Es wird häufig in Umgebungen mit eingeschränktem Speicher verwendet, z. B. unter Palm OS.
quelle
Betrachten Sie die folgende Abbildung und das folgende Programm, um dieses Konzept besser zu verstehen .
Gemäß der Abbildung ist ptr1 ein einzelner Zeiger mit der Adresse der Variablen num .
In ähnlicher Weise ist ptr2 ein Zeiger auf einen Zeiger (Doppelzeiger), der die Adresse des Zeigers ptr1 hat .
Ein Zeiger, der auf einen anderen Zeiger zeigt, wird als Doppelzeiger bezeichnet. In diesem Beispiel ist ptr2 ein Doppelzeiger.
Werte aus obigem Diagramm:
Beispiel:
Ausgabe:
quelle
Es ist ein Zeiger auf den Adresswert des Zeigers. (das ist schrecklich, ich weiß)
Grundsätzlich können Sie einen Zeiger auf den Wert der Adresse eines anderen Zeigers übergeben, sodass Sie ändern können, wohin ein anderer Zeiger von einer Unterfunktion zeigt, z.
quelle
Sie haben eine Variable, die eine Adresse von etwas enthält. Das ist ein Hinweis.
Dann haben Sie eine andere Variable, die die Adresse der ersten Variablen enthält. Das ist ein Zeiger auf Zeiger.
quelle
Ein Zeiger auf Zeiger ist ein Zeiger auf Zeiger.
Ein aussagekräftiges Beispiel für someType ** ist ein zweidimensionales Array: Sie haben ein Array, das mit Zeigern auf andere Arrays gefüllt ist, also beim Schreiben
dpointer [5] [6]
Sie greifen auf das Array zu, das Zeiger auf andere Arrays an seiner 5. Position enthält, erhalten den Zeiger (lassen Sie fpointer seinen Namen) und greifen dann auf das 6. Element des Arrays zu, auf das auf dieses Array verwiesen wird (also fpointer [6]).
quelle
So funktioniert es: Es ist eine Variable, die einen anderen Zeiger speichern kann.
Wann würden Sie sie verwenden: Viele verwenden eine davon, wenn Ihre Funktion ein Array erstellen und an den Aufrufer zurückgeben möchte.
quelle
Ich habe ein 5-minütiges Video erstellt, in dem erklärt wird, wie Zeiger funktionieren:
https://www.youtube.com/watch?v=3X-ray3tDjQ
quelle
Es gibt so viele nützliche Erklärungen, aber ich habe nicht nur eine kurze Beschreibung gefunden, also ..
Grundsätzlich ist der Zeiger die Adresse der Variablen. Kurzer Zusammenfassungscode:
Nützliche Informationen finden Sie auch im Thema Was bedeutet Referenz und Dereferenzierung?
Und ich bin mir nicht so sicher, wann Zeiger nützlich sein können, aber gemeinsam ist es notwendig, sie zu verwenden, wenn Sie eine manuelle / dynamische Speicherzuweisung durchführen - Malloc, Calloc usw.
Ich hoffe also, dass es auch hilft, das Problem zu klären :)
quelle