MySQL Java JavaScript PHP Python HTML-CSS C-sharp C++ Go

Operații cu pointeri

Pointerii suportă o serie de operații: atribuire, obținerea adresei, dereferențiere (obținerea valorii), unele operații aritmetice și operații de comparație.

Atribuirea unei adrese

Unui pointer i se poate atribui adresa unui obiect de același tip sau valoarea altui pointer. Pentru a obține adresa unui obiect se folosește operatorul &:

int a {10};
int *pa {&a};   // pointerul pa stochează adresa variabilei a

Pointerul și variabila trebuie să aibă același tip – în acest caz, int.

Dereferențierea unui pointer

Operația de dereferențiere a unui pointer este scrisă sub forma *nume_pointer. Această operație returnează obiectul aflat la adresa stocată în pointer.

#include <iostream>
 
int main()
{
    int a {10};
    int *pa {&a};   // stochează adresa variabilei a

    std::cout << "*pa = " << *pa << std::endl;  // *pa = 10
    std::cout << "a = " << a << std::endl;      // a = 10

    *pa = 25;   // modificăm valoarea de la adresa din pointer

    std::cout << "*pa = " << *pa << std::endl;  // *pa = 25
    std::cout << "a = " << a << std::endl;      // a = 25
}

Prin expresia *pa obținem valoarea stocată la adresa indicată de pa, iar prin *pa = valoare putem modifica acea valoare. Deoarece pa pointează către a, modificarea afectează și variabila a.

Atribuirea unui alt pointer

#include <iostream>
 
int main()
{
    int a {10};
    int b {2};

    int *pa {&a};   // pointer către a
    int *pb {&b};   // pointer către b

    std::cout << "pa: address=" << pa << "\t value=" << *pa << std::endl;
    std::cout << "pb: address=" << pb << "\t value=" << *pb << std::endl;

    pa = pb;    // acum pa stochează adresa lui b
    std::cout << "pa: address=" << pa << "\t value=" << *pa << std::endl;

    *pa = 125;  // modificăm valoarea de la adresa lui b
    std::cout << "b value=" << b << std::endl;
}

Când unui pointer i se atribuie alt pointer, acesta începe să indice aceeași adresă:

pa: address=0x56347ffc5c         value=10  
pb: address=0x56347ffc58         value=2  
pa: address=0x56347ffc58         value=2  
b value=125

Pointeri nul (null pointers)

Un pointer nul nu indică niciun obiect. Dacă nu dorim ca pointerul să indice către o locație validă, îi putem atribui valoarea nulă:

int *p1{nullptr};
int *p2{};

Referințe la pointeri

Deoarece o referință nu este un obiect, nu putem crea un pointer la o referință, dar putem crea o referință la un pointer. Printr-o astfel de referință putem modifica adresa pe care o stochează pointerul sau valoarea stocată la acea adresă:

#include <iostream>
 
int main()
{
    int a {10};
    int b {6};
 
    int *p{};           // pointer
    int *&pRef {p};     // referință la pointer
    pRef = &a;          // prin referință atribuim adresa lui a pointerului p
    std::cout << "p value=" << *p << std::endl;   // 10
    *pRef = 70;         // modificăm valoarea la care pointează p
    std::cout << "a value=" << a << std::endl;    // 70

    pRef = &b;          // schimbăm adresa către care pointează p
    std::cout << "p value=" << *p << std::endl;   // 6
}

Adresa unui pointer

Un pointer stochează adresa unei variabile, dar el însuși are o adresă proprie în memorie. Această adresă se obține cu &:

int a {10};
int *pa {&a};
std::cout << "address of pointer=" << &pa << std::endl;        // adresa pointerului
std::cout << "address stored in pointer=" << pa << std::endl;  // adresa stocată (adresa lui a)
std::cout << "value on pointer=" << *pa << std::endl;          // valoarea de la acea adresă (valoarea lui a)

Operații de comparație

Pointerii pot fi comparați folosind operatorii >, >=, <, <=, ==, !=, dar doar între pointeri de același tip. Compararea se face după valorile adreselor:

#include <iostream>
 
int main()
{
    int a {10};
    int b {20};
    int *pa {&a};
    int *pb {&b};

    if(pa > pb)
        std::cout << "pa (" << pa << ") is greater than pb ("<< pb << ")" << std::endl;
    else
        std::cout << "pa (" << pa << ") is less or equal pb ("<< pb << ")" << std::endl;
}

Ieșire posibilă:

pa (0xa9da5ffdac) is greater than pb (0xa9da5ffda8)

Conversia tipurilor

Uneori este necesar să atribuim unui pointer valoarea altui pointer de alt tip. În acest caz, se folosește conversia explicită:

#include <iostream>
 
int main()
{
    char c {'N'};
    char *pc {&c};            // pointer la char
    int *pd {(int *)pc};      // conversie la pointer la int
    void *pv {(void*)pc};     // pointer la void
    std::cout << "pv=" << pv << std::endl;
    std::cout << "pd=" << pd << std::endl;
}

Pentru conversie, se pune tipul dorit între paranteze înaintea pointerului. Deși nu putem crea o variabilă de tip void, putem crea un pointer void*.

De asemenea, pointerul de tip char* este interpretat ca un șir la afișare:

std::cout << "pc=" << pc << std::endl;

Dacă dorim să afișăm adresa stocată în pointerul char*, trebuie să o convertim la alt tip, de exemplu void* sau int*.