logo

C dubultā rādītājs (no rādītāja uz rādītāju)

Kā zināms, rādītājs tiek izmantots, lai saglabātu C mainīgā adreses. Rādītājs samazina mainīgā piekļuves laiku. Tomēr programmā C mēs varam arī definēt rādītāju, lai saglabātu cita rādītāja adresi. Šāds rādītājs ir pazīstams kā dubultā rādītājs (norādītājs uz rādītāju). Pirmais rādītājs tiek izmantots, lai saglabātu mainīgā lieluma adresi, bet otrais rādītājs tiek izmantots, lai saglabātu pirmā rādītāja adresi. Sapratīsim to pēc zemāk redzamās diagrammas.

rādītājs uz rādītāju c

Dubultrādītāja deklarēšanas sintakse ir dota zemāk.

 int **p; // pointer to a pointer which is pointing to an integer. 

Apsveriet šādu piemēru.

 #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 } 

Izvade

 address of a: d26a8734 address of p: d26a8738 value stored at p: 10 value stored at pp: 10 

C dubultā rādītāja piemērs

Apskatīsim piemēru, kur viens rādītājs norāda uz cita rādītāja adresi.

C rādītāja rādītāja piemērs

Kā redzams iepriekšējā attēlā, p2 satur p adresi (fff2), un p satur skaitļa mainīgā (fff4) adresi.

 #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; } 

Izvade

 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 

J. Kāds būs šādas programmas rezultāts?

 #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 } 

Paskaidrojums

Dubultā rādītāja jautājums

Iepriekš minētajā jautājumā rādītāja aritmētika tiek izmantota kopā ar dubulto rādītāju. Ir definēts 6 elementu masīvs, uz kuru norāda rādītāja p masīvs. Rādītāja masīvs p ir norādīts ar dubulto rādītāju pp. Tomēr iepriekš redzamais attēls sniedz īsu priekšstatu par to, kā atmiņa tiek piešķirta masīvam a un rādītāja masīvam p. P elementi ir rādītāji, kas norāda uz katru masīva a elementu. Tā kā mēs zinām, ka masīva nosaukumā ir ietverta masīva bāzes adrese, tas darbosies kā rādītājs un vai vērtību var šķērsot, izmantojot *(a), *(a+1) utt. Kā parādīts attēlā. , a[0] var piekļūt šādos veidos.

  • a[0]: tas ir vienkāršākais veids, kā piekļūt pirmajam masīva elementam
  • *(a): tā kā tiek saglabāta masīva pirmā elementa adrese, mēs varam piekļūt tā vērtībai, izmantojot uz tā netiešo rādītāju.
  • *p[0]: ja a[0] ir jāpiekļūst, izmantojot rādītāju p uz to, tad mēs varam izmantot indirection operatoru (*) rādītāja masīva p pirmajā elementā, t.i., *p[0].
  • **(pp): tā kā pp saglabā rādītāja masīva bāzes adresi, *pp sniegs rādītāja masīva pirmā elementa vērtību, kas ir veselā masīva pirmā elementa adrese. **p uzrādīs veselā masīva pirmā elementa faktisko vērtību.

Nonākot pie programmas, 1. un 2. rinda deklarē veselo skaitļu un rādītāju masīvu relatīvi. 3. rindiņa inicializē dubulto rādītāju uz rādītāju masīvu p. Kā parādīts attēlā, ja masīva adrese sākas ar 200 un veselā skaitļa lielums ir 2, tad rādītāja masīvā būs tādas vērtības kā 200, 202, 204, 206, 208, 210. Ņemsim vērā, ka rādītāja masīva bāzes adrese ir 300; dubultā rādītāja pp ir rādītāja masīva adrese, t.i., 300. Rindas numurs 4 palielina pp vērtību par 1, t.i., pp tagad norādīs uz adresi 302.

Rindas numurs 5 satur izteiksmi, kas izdrukā trīs vērtības, t.i., pp - p, *pp - a, **pp. Aprēķināsim tos katru no tiem.

  • pp = 302, p = 300 => pp-p = (302-300)/2 => pp-p = 1, t.i., tiks izdrukāts 1.
  • pp = 302, *pp = 202, a = 200 => *pp - a = 202 - 200 = 2/2 = 1, t.i., tiks drukāts 1.
  • lpp = 302, *pp = 202, *(*pp) = 206, t.i., tiks drukāts 206.

Tāpēc 5. rindas rezultātā konsolē tiks izdrukāta izvade 1, 1, 206. 6. rindā ir rakstīts *pp++. Šeit mums jāņem vērā, ka diviem unāriem operatoriem * un ++ būs vienāda prioritāte. Tāpēc pēc asociativitātes principa tas tiks vērtēts no labās uz kreiso pusi. Tāpēc izteiksmi *pp++ var pārrakstīt kā (*(pp++)). Tā kā pp = 302, kas tagad kļūs par 304. *pp dos 204.

7. rindā atkal tiek rakstīts izteiksme, kas izdrukā trīs vērtības, t.i., pp-p, *pp-a, *pp. Aprēķināsim katru no tiem.

  • pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, t.i., tiks izdrukāts 2.
  • pp = 304, *pp = 204, a = 200 => *pp-a = (204 - 200)/2 = 2, t.i., tiks drukāts 2.
  • pp = 304, *pp = 204, *(*pp) = 300, t.i., tiks izdrukāti 300.

Tāpēc 7. rindas rezultātā konsolē tiks izdrukāta izvade 2, 2, 300. 8. rindā ir rakstīts ++*pp. Saskaņā ar asociativitātes likumu to var pārrakstīt kā, (++(*(pp))). Tā kā pp = 304, *pp = 204, vērtība *pp = *(p[2]) = 206, kas tagad norāda uz a[3].

9. rindā atkal tiek rakstīts izteiksme, kas izdrukā trīs vērtības, t.i., pp-p, *pp-a, *pp. Aprēķināsim katru no tiem.

  • pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, t.i., tiks izdrukāts 2.
  • pp = 304, *pp = 206, a = 200 => *pp-a = (206 - 200)/2 = 3, t.i., tiks drukāts 3.
  • pp = 304, *pp = 206, *(*pp) = 409, t.i., tiks drukāts 409.

Tāpēc 9. rindas rezultātā konsolē tiks izdrukāta izvade 2, 3, 409. 10. rindā rakstīts ++**pp. saskaņā ar asociativitātes likumu to var pārrakstīt kā, (++(*(*(pp)))). pp = 304, *pp = 206, **pp = 409, ++**pp => *pp = *pp + 1 = 410. Citiem vārdiem sakot, a[3] = 410.

11. rindā atkal tiek rakstīts izteiksme, kas izdrukā trīs vērtības, t.i., pp-p, *pp-a, *pp. Aprēķināsim katru no tiem.

  • pp = 304, p = 300 => pp - p = (304 - 300)/2 => pp-p = 2, t.i., tiks izdrukāts 2.
  • pp = 304, *pp = 206, a = 200 => *pp-a = (206 - 200)/2 = 3, t.i., tiks drukāts 3.
  • 8. rindiņā **pp = 410.

Tāpēc 9. rindas rezultātā konsolē tiks izdrukāta izvade 2, 3, 410.

Visbeidzot, visas programmas izvade tiks sniegta šādi:

Izvade

 1 1 206 2 2 300 2 3 409 2 3 410