După cum știm că, un pointer este folosit pentru a stoca adresa unei variabile în C. Pointerul reduce timpul de acces al unei variabile. Totuși, în C, putem defini și un pointer pentru a stoca adresa altui pointer. Un astfel de indicator este cunoscut ca un indicator dublu (pointer la pointer). Primul pointer este folosit pentru a stoca adresa unei variabile, în timp ce al doilea pointer este folosit pentru a stoca adresa primului indicator. Să-l înțelegem prin diagrama prezentată mai jos.
Sintaxa declarării unui indicator dublu este dată mai jos.
int **p; // pointer to a pointer which is pointing to an integer.
Luați în considerare următorul exemplu.
#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 }
Ieșire
address of a: d26a8734 address of p: d26a8738 value stored at p: 10 value stored at pp: 10
Exemplu de indicator C dublu
Să vedem un exemplu în care un pointer indică adresa altui pointer.
După cum puteți vedea în figura de mai sus, p2 conține adresa lui p (fff2), iar p conține adresa variabilei numerice (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; }
Ieșire
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
Î. Care va fi rezultatul următorului program?
#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 }
Explicaţie
În întrebarea de mai sus, aritmetica indicatorului este folosită cu indicatorul dublu. Este definită o matrice de 6 elemente care este indicată de o matrice de pointer p. Tabloul pointer p este indicat de un pointer dublu pp. Cu toate acestea, imaginea de mai sus vă oferă o scurtă idee despre modul în care memoria este alocată matricei a și matricei pointerului p. Elementele lui p sunt pointerii care indică fiecare element al matricei a. Deoarece știm că numele matricei conține adresa de bază a matricei, prin urmare, va funcționa ca un pointer și valoarea poate fi parcursă folosind *(a), *(a+1), etc. După cum se arată în imagine , a[0] poate fi accesat în următoarele moduri.
- a[0]: este cel mai simplu mod de a accesa primul element al matricei
- *(a): deoarece un stochează adresa primului element al matricei, putem accesa valoarea acestuia utilizând indicatorul de indirectă pe acesta.
- *p[0]: dacă a[0] trebuie accesat utilizând un pointer p către acesta, atunci putem folosi operatorul de indirectă (*) pe primul element al tabloului de pointeri p, adică *p[0].
- **(pp): deoarece pp stochează adresa de bază a matricei de pointeri, *pp va da valoarea primului element al matricei de pointeri care este adresa primului element al matricei întregi. **p va da valoarea reală a primului element al matricei întregi.
Venind la program, Linia 1 și 2 declară matricea întregului și a indicatorului relativ. Linia 3 inițializează indicatorul dublu către tabloul de indicatori p. După cum se arată în imagine, dacă adresa matricei începe de la 200 și dimensiunea întregului este 2, atunci tabloul pointerului va conține valori ca 200, 202, 204, 206, 208, 210. Să considerăm că adresa de bază a tabloului pointer este 300; indicatorul dublu pp conține adresa matricei de pointeri, adică 300. Linia numărul 4 crește valoarea lui pp cu 1, adică pp va indica acum adresa 302.
Linia numărul 5 conține o expresie care afișează trei valori, adică pp - p, *pp - a, **pp. Să le calculăm fiecare dintre ele.
elementele de bază ale seleniului
- pp = 302, p = 300 => pp-p = (302-300)/2 => pp-p = 1, adică se va imprima 1.
- pp = 302, *pp = 202, a = 200 => *pp - a = 202 - 200 = 2/2 = 1, adică se va tipări 1.
- pp = 302, *pp = 202, *(*pp) = 206, adică 206 va fi tipărit.
Prin urmare, ca rezultat al liniei 5, ieșirea 1, 1, 206 va fi tipărită pe consolă. Pe linia 6 se scrie *pp++. Aici, trebuie să observăm că doi operatori unari * și ++ vor avea aceeași prioritate. Prin urmare, după regula asociativității, se va evalua de la dreapta la stânga. Prin urmare, expresia *pp++ poate fi rescrisă ca (*(pp++)). Deoarece, pp = 302 care va deveni acum, 304. *pp va da 204.
Pe linia 7, din nou este scrisă expresia care afișează trei valori, adică pp-p, *pp-a, *pp. Să calculăm fiecare dintre ele.
- pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, adică se va imprima 2.
- pp = 304, *pp = 204, a = 200 => *pp-a = (204 - 200)/2 = 2, adică se va tipări 2.
- pp = 304, *pp = 204, *(*pp) = 300, adică se vor tipări 300.
Prin urmare, ca rezultat al liniei 7, ieșirea 2, 2, 300 va fi tipărită pe consolă. Pe linia 8 se scrie ++*pp. Conform regulii asociativității, aceasta poate fi rescrisă ca, (++(*(pp))). Deoarece, pp = 304, *pp = 204, valoarea lui *pp = *(p[2]) = 206 care va indica acum a[3].
Pe linia 9, din nou este scrisă expresia care afișează trei valori, adică pp-p, *pp-a, *pp. Să calculăm fiecare dintre ele.
- pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, adică se va imprima 2.
- pp = 304, *pp = 206, a = 200 => *pp-a = (206 - 200)/2 = 3, adică se va tipări 3.
- pp = 304, *pp = 206, *(*pp) = 409, adică 409 vor fi tipărite.
Prin urmare, ca rezultat al liniei 9, ieșirea 2, 3, 409 va fi tipărită pe consolă. Pe linia 10 se scrie ++**pp. după regula asociativității, aceasta poate fi rescrisă ca, (++(*(*(pp)))). pp = 304, *pp = 206, **pp = 409, ++**pp => *pp = *pp + 1 = 410. Cu alte cuvinte, a[3] = 410.
Pe linia 11, din nou este scrisă expresia care afișează trei valori, adică pp-p, *pp-a, *pp. Să calculăm fiecare dintre ele.
fmovies India
- pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, adică se va imprima 2.
- pp = 304, *pp = 206, a = 200 => *pp-a = (206 - 200)/2 = 3, adică se va tipări 3.
- Pe linia 8, **pp = 410.
Prin urmare, ca rezultat al liniei 9, ieșirea 2, 3, 410 va fi tipărită pe consolă.
În cele din urmă, rezultatul programului complet va fi dat ca:
Ieșire
1 1 206 2 2 300 2 3 409 2 3 410