Informatiile acestui spatiu sunt gratuite. Observatii si sugestii pot fi trimise pe adresa de contact sau pe forum.

     Pointeri in C++

Asa cum am vazut in exemplele anterioare, uneori este nevoie sa lucram cu adresele de memorie ale variabilelor in care se stocheaza anumite valori. In acest fel putem sti locatia valorii in memoria calculatorului. O variabila care memoreaza o adresa se numeste pointer.

Declararea unui pointer se face la fel ca si declararea unei variabile obisnuite, dar in fata numelui variabilei intervine semnul *:

     int *p;

Exemple de variabile si pointeri:

  • int a;
  • - a reprezinta o variabila de timp intreg
  • int *pa;
  • - pa reprezinta un pointer catre o variabila de timp intreg
  • char c;
  • - c reprezinta o variabila de tip caracter
  • char *pc;
  • - pc reprezinta un pointer catre o variabila de tip caracter
  • float f;
  • - f reprezinta o variabila de tip real
  • float *pf;
  • - pf reprezinta un pointer catre o variabila de tip real
  • etc...








  • Observatie: Atat variabilele normale cat si cele de tip pointer pot fi declarate in acelasi timp:

  • int a, *pa;
  • - a reprezinta o variabila de timp intreg
    - pa reprezinta un pointer catre o variabila de timp intreg
  • char c, *pc;
  • - c reprezinta o variabila de tip caracter
    - pc reprezinta un pointer catre o variabila de tip caracter
  • float f, *pf;
  • - f reprezinta o variabila de tip real
    - pf reprezinta un pointer catre o variabila de tip real
  • etc...








  • Este indicata initializarea pointerilor la livelul declaraiei acestora. Initializarea pointerilor se poate face fie cu valorile 0 sau NULL, fie cu o adresa de memorie. Valoarea (constanta) NULL este delclarata in cadrul fiserului standard iostream (directiva preprocesor utilizata la inceputul programului).

    Un pointer constant este un pointer a carui valoare nu poate fi modificata pe parcursul programului, initializarea acestuia realizandu-se la livelul declaratiei lui:

          Exemplu: int a;
                          const int *adr_a=&a;


         Referinte in C++

    Pentru a obtine adresa unei variabile, se foloseste operatorul de referentiere: &. Va loarea returnata prin utilizarea operatorului de referentiere poate fi atribuita unui pointer.

  • int a, *pa;
  • - a reprezinta o variabila de timp intreg
    - &a reprezinta adresa unei variabile de timp intreg
    - pa=&a; pointerului pa i se atribuie adresa de memorie a variabilei de tip intreg a
  • char c, *pc;
  • - c reprezinta o variabila de tip caracter
    - &c reprezinta adresa unei variabile de timp caracter
    - pc=&c pointerului pc i se atribuie adresa de memorie a variabilei de tip caracter c
  • float f, *pf;
  • - f reprezinta o variabila de tip real
    - &f reprezinta adresa unei variabile de timp real
    - pf=&f pointerului pf i se atribuie adresa de memorie a variabilei de tip real f
  • etc...












  •      Operatii cu pointeri

    • Initializarea pointerilor se poate realiza inca din faza de declarare:

         int a=10, *pa=&a;

      Daca int a=10 este o variabila de tip intreg avand valoarea 10, iar int *pa este un pointer catre o variabila de tip intreg atunci:

      - &a reprezinta adresa variabilei a
      - pa=&a realizeaza atribuirea adresei variabilei a catre pointerul pa
      - *pa=&a realizeaza atribuirea valorii aflate la adresa variabilei a, deci *pa=10

      Observatii:
      - *&a=a
      - *pa: operatorul * se mai numeste si operator de indirectare sau de dereferentiere.
      Exemplu:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      #include <iostream>
      using namespace std;
      double a, *b;
      int main()
      {
         cout<<"a=";cin>>a;
         cout<<endl<<"a="<<a<<endl;
         cout<<"Adresa lui a: &a="<<&a<<endl;
         b=&a;
         cout<<"Pointerul b stocheaza adresa variabilei a: b=";
         cout<<b<<endl;
         cout<<"*b reprezinta continutul adresei de memorie: *b=";
         cout<<*b<<endl;
      }
      a=10

      a=10
      Adresa lui a: &a=0x477008
      Pointerul b stocheaza adresa variabilei a: b=0x477008
      *b reprezinta continutul adresei de memorie: *b=10









      Tablourile (unidimensionale, bidimensionale, etc.) sunt sunt strans legate de pointeri, componentele tablourilor fiind stocate la adrese de memorie succesive.

      Un vector v[5] avand elemente de tip intreg, un pointer poate fi initializat astfel:
            int v[5];
            int *pv=v; sau int *pv=&v[0];
      deoarece adresa primei componente a vectorului coincide cu adresa vectorului in sine.

      Exemplu: Se da un vector v de 5 elemente numere intregi, componentele fiind initializate cu pozitia corespunzatoare a acestora in cadrul sirului. Sa se afiseze adresa vectorului precum si adresele componentelor acestuia.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      #include <iostream>
      using namespace std;
      int v[5], *pv=v;
      int main()
      {
         for (int i=0;i<5;i++)
            v[i]=i;
         cout<<"Adresa vectorului: "<<endl;
         cout<<"pv="<<pv<<endl;
         cout<<"Adresa componentelor vectorului: "<<endl;
         for (int i=0;i<5;i++)
         {
             pv=&v[i];
             cout<<"v["<<i<<"] are valoarea: "<<v[i]<<" si adresa: "<<pv<<endl;
         }
      }
      Adresa vectorului:
      pv=0x477008
      Adresa componentelor vectorului:
      v[0] are valoarea: 0 si adresa: 0x477008
      v[1] are valoarea: 1 si adresa: 0x47700c
      v[2] are valoarea: 2 si adresa: 0x477010
      v[3] are valoarea: 3 si adresa: 0x477014
      v[4] are valoarea: 4 si adresa: 0x477018








      Explicatii:

      • Adresa vectorului coincide cu adresa primei componente a acestuia: 0x477008;
      • diferenta intre adresele a doua componente succesive este de 4 octeti - spatiul necesar pentru memorarea unei valori de tip intreg (tipul vectorului);
      • valorile adreselor sunt exprimate in formatul hexazecimal.


    • Incrementarea/decrementarea poinerilor permite, ca si in cazul vatribilelor normale, adaugarea/scaderea cu 1 a valorii curente a pointerului.
         int a=10, *pa=&a;
         pa++;
         pa--;
         ++pa;
         --pa;

      Daca int a=10 este o variabila de tip intreg avand valoarea 10, iar int *pa este un pointer catre o variabila de tip intreg atunci:

      • adresa variabilei a va fi stocata in variabila (pointerul) pa
      • pa++ realizeaza postincrementarea pointerului pa
      • pa-- realizeaza postdecrementarea pointerului pa
      • ++pa realizeaza preincrementarea pointerului pa
      • --pa realizeaza predecrementarea pointerului pa

      Observatie: Dupa operatia de incrementare/decrementare a unui pointer, adresa variabilei creste/descreste cu numarul de octeti corespunzator tipui variabilei.

      Exemplu: Se da o variabila a de tip short respectiv o variabila b de tip int. Sa se declare pointerii aferenti acestor varibile si sa se realizeze operatii de incrementare/decrementare asupra pointerilor, urmarinduse valorile acestora in functie de tipul variabilelor.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      #include <iostream>
      using namespace std;
      short a, *pa=&a;
      int b, *pb=&b;
      int main()
      {
         cout<<"a=";cin>>a;
         cout<<"b=";cin>>b;
         cout<<"Adresa lui a este: "<<pa<<endl;
         cout<<"Adresa lui b este: "<<pb<<endl;
         pa++;
         cout<<"Adresa lui a, dupa postincrementare, este: "<<pa<<endl;
         pb++;
         cout<<"Adresa lui b, dupa postincrementare, este: "<<pb<<endl;
      }
      a=2
      b=3
      Adresa lui a este: 0x477008
      Adresa lui b este: 0x47700c
      Adresa lui a, dupa postincrementare, este: 0x47700a
      Adresa lui b, dupa postincrementare, este: 0x477010









      Explicatii:

      • Adresa variabilei a creste cu 2 deoarece tipul acesteia este short (care se afiseaza pe 2 octeti): 0x477008 => 0x47700a;
      • Adresa variabilei b creste cu 4 deoarece tipul acesteia este int (care se afiseaza pe 4 octeti): 0x47700c => 0x477010;
      • valorile adreselor sunt exprimate in formatul hexazecimal.


    • Adunarea/scaderea poinerilor permite, ca si in cazul vatribilelor normale, adaugarea/scaderea unei anumite valori la valoarea curenta a pointerului. Ca si in cazul incrementarii/decrementarii pointerilor, adresa finala care va fi retinuta de pointer va depinde de tipul variabilei.

         int a=10, *pa=&a;
         pa=pa+2; sau pa+=2;
         pa=pa-2; sau pa-=2;

      Observatie: Pentru o variabila short adresa finala va vi egala cu cea initiala plus/minus n*2octeti (variabilele de tip short se stocheaza pe 2 octeti), in timp ce pentru o variabila int, adresa finala va fi egala cu cea initiala plus/minus n*4octeti (cariabilele de tip int se stocheaza pe 4 octeti).
         int a=10, *pa=&a;
         pa=pa+2; sau pa+=2;
         pa=pa-2; sau pa-=2;

      Exemplu: Se da o variabila a de tip short respectiv o variabila b de tip int. Sa se declare pointerii aferenti acestor varibile si sa se realizeze operatii de incrementare/decrementare asupra pointerilor, urmarinduse valorile acestora in functie de tipul variabilelor.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      #include <iostream>
      using namespace std;
      short a, *pa=&a;
      int b, *pb=&b;
      int main()
      {
         cout<<"a=";cin>>a;
         cout<<"b=";cin>>b;
         cout<<"Adresa lui a este: "<<pa<<endl;
         cout<<"Adresa lui b este: "<<pb<<endl;
         pa+=2;
         cout<<"Adresa lui a, dupa adunare, este: "<<pa<<endl;
         pb-=3;
         cout<<"Adresa lui b, dupa scadere, este: "<<pb<<endl;
      }
      a=2
      b=3
      Adresa lui a este: 0x477008
      Adresa lui b este: 0x47700c
      Adresa lui a, dupa adunare, este: 0x47700c
      Adresa lui b, dupa scadere, este: 0x477000









      Explicatii:

      • Adresa variabilei a creste cu 4 (2*2octeti, cat are nevoie variabila de tip short pentru reprezentare): 0x477008 => 0x47700c;
      • Adresa variabilei b scade cu 12 (3*4octeti, cat are nevoie variabila de tip int pentru reprezentare): 0x47700c => 0x477000;
      • valorile adreselor sunt exprimate in formatul hexazecimal.