Pointeri în C

Pointeri în C

În C, pointerii sunt un subiect care sperie mulți începători, dar ideea de bază este simplă: un pointer este o variabilă care ține o adresă de memorie. Adică nu ține direct o valoare (cum ține un int), ci ține locul unde se află acea valoare în memorie. 


 

1) Ce este o adresă de memorie?

Gândește-te la memorie ca la un bloc cu multe apartamente. Fiecare apartament are un număr (adresa). Valoarea unei variabile stă într-un “apartament”, iar adresa este “numărul apartamentului”.

2) Variabilă normală vs pointer

O variabilă normală (de exemplu un int) conține valoarea:

int x = 10;

Un pointer (de exemplu int*) conține adresa unde se află un int:

int *p = &x;

Aici apar două simboluri importante:

  • & (address-of) – “dă-mi adresa variabilei”
  • * (dereference) – “du-te la adresa din pointer și ia valoarea de acolo”

3) Exemplu complet, pas cu pas

#include <stdio.h>

int main(void) {
    int x = 10;       // x ține valoarea 10
    int *p = &x;      // p ține adresa lui x

    printf("x = %d\n", x);
    printf("&x = %p\n", (void*)&x);

    printf("p = %p\n", (void*)p);
    printf("*p = %d\n", *p);

    return 0;
}

Ce se întâmplă aici:

  • x este 10.
  • &x este adresa lui x.
  • p este aceeași adresă (pentru că p = &x).
  • *p este valoarea de la acea adresă, adică tot 10.

4) De ce sunt pointerii utili?

Pointerii sunt folosiți foarte des în C pentru:

  • Modificarea unei variabile dintr-o funcție (transmiți adresa, nu copia).
  • Lucrul cu tablouri (array-uri) și parcurgerea lor eficientă.
  • Alocare dinamică de memorie (de exemplu malloc / free).
  • Structuri complexe (liste înlănțuite, arbori etc.).

5) Pointeri în funcții: “vreau să modific variabila originală”

În C, când trimiți o variabilă normală într-o funcție, se trimite o copie. Dacă vrei să modifici variabila originală, trimiți adresa ei (un pointer).

#include <stdio.h>

void set_to_99(int *p) {
    *p = 99;  // modifică valoarea de la adresa p
}

int main(void) {
    int x = 10;
    set_to_99(&x);  // trimitem adresa lui x
    printf("x = %d\n", x); // va afișa 99
    return 0;
}

Observă combinația: set_to_99(&x) trimite adresa, iar în funcție *p = 99 modifică valoarea de acolo.

6) Pointeri și tablouri (array)

În C, un tablou și un pointer sunt strâns legate. De multe ori, numele unui tablou “se comportă” ca un pointer către primul element.

#include <stdio.h>

int main(void) {
    int a[3] = {10, 20, 30};
    int *p = a; // echivalent cu &a[0]

    printf("a[0] = %d\n", a[0]);
    printf("*p   = %d\n", *p);

    printf("a[1] = %d\n", a[1]);
    printf("*(p+1) = %d\n", *(p+1));

    return 0;
}

Explicație:

  • p pointează la a[0].
  • p+1 pointează la următorul int din memorie, adică a[1].
  • *(p+1) înseamnă “valoarea de la adresa următorului element”.

7) Greșeli frecvente (și cum le eviți)

7.1) Pointer neinițializat

Dacă declari un pointer și nu îi dai o adresă validă, conținutul lui este “gunoi” (o valoare aleatoare). Dereferențierea (*p) poate duce la crash.

int *p;   // NU e inițializat
//*p = 10; // periculos

Variante corecte:    <p>

      Dacă vrei, îți pot adapta articolul pentru Blogger/WordPress (cu stiluri CSS simple) sau îți pot adăuga o secțiune separată

      despre <strong>pointeri la structuri</strong> și operatorul <code>-&gt;</code>.

    </p>

int *p = NULL;   // sigur, arată clar “nu pointează nicăieri”

7.2) Dereferențierea lui NULL

NULL înseamnă “nici o adresă validă”. Nu ai voie să faci *p dacă p == NULL.

7.3) Folosirea unui pointer după ce “nu mai e valid”

Un exemplu clasic: întorci dintr-o funcție adresa unei variabile locale. Variabila locală dispare când funcția se termină, iar pointerul rămâne “agățat” (dangling pointer).

int* wrong(void) {
    int x = 5;
    return &x; // GREȘIT: x e local și dispare după return
}

8) Mini-rezumat (de ținut minte)

  • Pointer = adresă
  • &x = adresa lui x
  • *p = valoarea de la adresa stocată în p
  • Folosești pointeri când vrei eficiență, acces la memorie și modificări “în loc” (in-place).
  • Nu dereferenția pointeri nevalizi: neinițializați, NULL sau “dangling”.

9) Exercițiu simplu

Scrie un program care:

  1. Declară un int x = 7.
  2. Declară un pointer int *p și îl setează cu adresa lui x.
  3. Folosește *p ca să schimbe valoarea lui x în 42.
  4. Afișează x și *p și verifică că sunt egale.

Documentatie

Cărți despre limbajul C (RO/EN) + PDF-uri gratuite

Lista de mai jos include titluri comerciale (link către editură/librărie) și resurse gratuite în format PDF din surse care le publică legal (autori, organizații, universități, proiecte open).

1) Cărți în limba română

2) Cărți în limba engleză 

3) PDF-uri gratuite (surse legale / open / autor-universitate)

Susține acest blog

Cumpărând de pe https://mag.automatic-house.ro/ro/ susții blogul meu, iar 10% din vânzări vor fi direcționate către Fundația Dăruiește Viață. Îți mulțumesc!

Mulțumesc pentru atenție! 

Pentru întrebări și/sau consultanță tehnică vă stau la dispoziție pe blog mai jos în secțiunea de comentarii sau pe email simedruflorin@automatic-house.ro.
O zi plăcută tuturor !
Back to top of page

Etichete

Afișați mai multe

Arhiva

Afișați mai multe