Wie wir wissen, wird ein Zeiger verwendet, um die Adresse einer Variablen in C zu speichern. Der Zeiger verkürzt die Zugriffszeit einer Variablen. In C können wir jedoch auch einen Zeiger definieren, um die Adresse eines anderen Zeigers zu speichern. Ein solcher Zeiger wird als Doppelzeiger (Zeiger auf Zeiger) bezeichnet. Der erste Zeiger wird zum Speichern der Adresse einer Variablen verwendet, während der zweite Zeiger zum Speichern der Adresse des ersten Zeigers verwendet wird. Lassen Sie es uns anhand des unten angegebenen Diagramms verstehen.
Die Syntax zum Deklarieren eines Doppelzeigers ist unten angegeben.
int **p; // pointer to a pointer which is pointing to an integer.
Betrachten Sie das folgende Beispiel.
math.pow Java
#include void main () { int a = 10; int *p; int **pp; p = &a; // pointer p is pointing to the address of a pp = &p; // pointer pp is a double pointer pointing to the address of pointer p printf('address of a: %x ',p); // Address of a will be printed printf('address of p: %x ',pp); // Address of p will be printed printf('value stored at p: %d ',*p); // value stoted at the address contained by p i.e. 10 will be printed printf('value stored at pp: %d ',**pp); // value stored at the address contained by the pointer stoyred at pp }
Ausgabe
address of a: d26a8734 address of p: d26a8738 value stored at p: 10 value stored at pp: 10
Beispiel für einen C-Doppelzeiger
Sehen wir uns ein Beispiel an, bei dem ein Zeiger auf die Adresse eines anderen Zeigers zeigt.
Wie Sie in der obigen Abbildung sehen können, enthält p2 die Adresse von p (fff2) und p enthält die Adresse der Zahlenvariablen (fff4).
#include int main(){ int number=50; int *p;//pointer to int int **p2;//pointer to pointer p=&number;//stores the address of number variable p2=&p; printf('Address of number variable is %x ',&number); printf('Address of p variable is %x ',p); printf('Value of *p variable is %d ',*p); printf('Address of p2 variable is %x ',p2); printf('Value of **p2 variable is %d ',*p); return 0; }
Ausgabe
Address of number variable is fff4 Address of p variable is fff4 Value of *p variable is 50 Address of p2 variable is fff2 Value of **p variable is 50
F. Was wird das Ergebnis des folgenden Programms sein?
#include void main () { int a[10] = {100, 206, 300, 409, 509, 601}; //Line 1 int *p[] = {a, a+1, a+2, a+3, a+4, a+5}; //Line 2 int **pp = p; //Line 3 pp++; // Line 4 printf('%d %d %d ',pp-p,*pp - a,**pp); // Line 5 *pp++; // Line 6 printf('%d %d %d ',pp-p,*pp - a,**pp); // Line 7 ++*pp; // Line 8 printf('%d %d %d ',pp-p,*pp - a,**pp); // Line 9 ++**pp; // Line 10 printf('%d %d %d ',pp-p,*pp - a,**pp); // Line 11 }
Erläuterung
In der obigen Frage wird die Zeigerarithmetik mit dem Doppelzeiger verwendet. Es wird ein Array aus 6 Elementen definiert, auf das ein Array mit dem Zeiger p zeigt. Auf das Zeiger-Array p wird durch einen Doppelzeiger pp gezeigt. Das obige Bild gibt Ihnen jedoch eine kurze Vorstellung davon, wie der Speicher dem Array a und dem Zeiger-Array p zugewiesen wird. Die Elemente von p sind die Zeiger, die auf jedes Element des Arrays a zeigen. Da wir wissen, dass der Array-Name die Basisadresse des Arrays enthält, fungiert er als Zeiger und kann den Wert mithilfe von *(a), *(a+1) usw. durchlaufen. Wie im Bild gezeigt Auf a[0] kann auf folgende Weise zugegriffen werden.
- a[0]: Dies ist die einfachste Möglichkeit, auf das erste Element des Arrays zuzugreifen
- *(a): Da a die Adresse des ersten Elements des Arrays speichert, können wir auf seinen Wert zugreifen, indem wir einen Indirektionszeiger darauf verwenden.
- *p[0]: Wenn auf a[0] mithilfe eines Zeigers p zugegriffen werden soll, können wir den Indirektionsoperator (*) für das erste Element des Zeigerarrays p verwenden, d. h. *p[0].
- **(pp): Da pp die Basisadresse des Zeiger-Arrays speichert, gibt *pp den Wert des ersten Elements des Zeiger-Arrays an, das die Adresse des ersten Elements des Integer-Arrays ist. **p gibt den tatsächlichen Wert des ersten Elements des Integer-Arrays an.
Kommen wir zum Programm: Zeile 1 und 2 deklarieren das Ganzzahl- und Zeiger-Array relativ. Zeile 3 initialisiert den Doppelzeiger auf das Zeiger-Array p. Wie im Bild gezeigt, enthält das Zeiger-Array die Werte 200, 202, 204, 206, 208, 210, wenn die Adresse des Arrays bei 200 beginnt und die Größe der Ganzzahl 2 beträgt Die Basisadresse des Zeiger-Arrays ist 300; Der Doppelzeiger pp enthält die Adresse des Zeigerarrays, also 300. Zeile Nummer 4 erhöht den Wert von pp um 1, d. h. pp zeigt jetzt auf Adresse 302.
Zeile Nummer 5 enthält einen Ausdruck, der drei Werte ausgibt, nämlich pp - p, *pp - a, **pp. Berechnen wir sie einzeln.
- pp = 302, p = 300 => pp-p = (302-300)/2 => pp-p = 1, d. h. 1 wird gedruckt.
- pp = 302, *pp = 202, a = 200 => *pp - a = 202 - 200 = 2/2 = 1, d. h. 1 wird gedruckt.
- pp = 302, *pp = 202, *(*pp) = 206, d. h. 206 werden gedruckt.
Daher wird als Ergebnis von Zeile 5 die Ausgabe 1, 1, 206 auf der Konsole ausgegeben. In Zeile 6 wird *pp++ geschrieben. Hier müssen wir beachten, dass zwei unäre Operatoren * und ++ die gleiche Priorität haben. Daher wird nach der Assoziativitätsregel von rechts nach links ausgewertet. Daher kann der Ausdruck *pp++ als (*(pp++)) umgeschrieben werden. Denn pp = 302, was nun 304 wird. *pp ergibt 204.
In Zeile 7 wird erneut der Ausdruck geschrieben, der drei Werte ausgibt, nämlich pp-p, *pp-a, *pp. Berechnen wir jeden einzelnen davon.
- pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, d. h. 2 wird gedruckt.
- pp = 304, *pp = 204, a = 200 => *pp-a = (204 - 200)/2 = 2, d. h. 2 wird gedruckt.
- pp = 304, *pp = 204, *(*pp) = 300, d. h. 300 werden gedruckt.
Daher wird als Ergebnis von Zeile 7 die Ausgabe 2, 2, 300 auf der Konsole ausgegeben. In Zeile 8 wird ++*pp geschrieben. Gemäß der Assoziativitätsregel kann dies umgeschrieben werden als (++(*(pp))). Da pp = 304, *pp = 204, ist der Wert von *pp = *(p[2]) = 206, der nun auf a[3] zeigt.
In Zeile 9 wird erneut der Ausdruck geschrieben, der drei Werte ausgibt, nämlich pp-p, *pp-a, *pp. Berechnen wir jeden einzelnen davon.
- pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, d. h. 2 wird gedruckt.
- pp = 304, *pp = 206, a = 200 => *pp-a = (206 - 200)/2 = 3, d. h. 3 wird gedruckt.
- pp = 304, *pp = 206, *(*pp) = 409, d. h. 409 wird gedruckt.
Daher wird als Ergebnis von Zeile 9 die Ausgabe 2, 3, 409 auf der Konsole ausgegeben. In Zeile 10 wird ****pp geschrieben. Gemäß der Assoziativitätsregel kann dies umgeschrieben werden als (++(*(*(pp)))). pp = 304, *pp = 206, **pp = 409, ++**pp => *pp = *pp + 1 = 410. Mit anderen Worten, a[3] = 410.
In Zeile 11 wird erneut der Ausdruck geschrieben, der drei Werte ausgibt, nämlich pp-p, *pp-a, *pp. Berechnen wir jeden einzelnen davon.
- pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, d. h. 2 wird gedruckt.
- pp = 304, *pp = 206, a = 200 => *pp-a = (206 - 200)/2 = 3, d. h. 3 wird gedruckt.
- In Zeile 8 ist **pp = 410.
Daher wird als Ergebnis von Zeile 9 die Ausgabe 2, 3, 410 auf der Konsole ausgegeben.
Abschließend wird die Ausgabe des vollständigen Programms wie folgt ausgegeben:
Ausgabe
1 1 206 2 2 300 2 3 409 2 3 410