I puntatori in C e C++ spiegati in modo semplice

I puntatori hanno una fama un po' intimidatoria. Tante persone che imparano il C o il C++ ci si bloccano, mollano, e poi ci tornano qualche mese dopo accorgendosi che, in fondo, non era cosรฌ terribile. La veritร  sta in una frase: un puntatore si basa su una sola idea, semplicissima. Invece di lavorare con un valore, si lavora con il posto in cui quel valore รจ conservato. Tutto il resto discende in modo logico da questo principio.

Una variabile, una casella, un indirizzo

Quando si dichiara una variabile, il computer riserva una piccola zona nella memoria per conservarne il valore. Possiamo immaginare la memoria come una lunga via di palazzi, dove ogni casella ha un numero unico: il suo indirizzo. La variabile, invece, รจ soltanto un'etichetta posata su una di quelle caselle, cosรฌ non dobbiamo ricordare il numero a memoria.

Un puntatore รจ semplicemente una variabile che contiene quel numero anzichรฉ un valore normale. Dove un intero conserva il numero 42, un puntatore conserva l'indirizzo del posto in cui si trova, per esempio, proprio quel 42. Se hai giร  letto la nostra guida per scrivere il tuo primo programma in C++, sei giร  a metร  strada: un puntatore resta una variabile, solo con un compito un po' particolare.

Dichiarare un puntatore e leggere ciรฒ che indica

In C, due simboli fanno quasi tutto il lavoro. L'asterisco * dichiara un puntatore e accede al valore che indica; la e commerciale & recupera l'indirizzo di una variabile esistente.

int eta = 42;
int *p = η        // p contiene l'indirizzo di eta

printf("%d\n", *p);   // stampa 42, il valore puntato
*p = 43;              // modifichiamo eta tramite il puntatore
printf("%d\n", eta);  // stampa 43

Qui *p si legge ยซ il valore conservato all'indirizzo contenuto in p ยป. Questa operazione si chiama dereferenziazione. Il punto da ricordare: modificare *p modifica eta direttamente, perchรฉ entrambi indicano la stessa casella di memoria. รˆ proprio questo che rende i puntatori cosรฌ utili.

A cosa servono davvero i puntatori

Potrebbe sembrare una complicazione gratuita. In pratica, i puntatori risolvono problemi molto concreti. Permettono a una funzione di modificare una variabile che le viene passata, invece di riceverne una semplice copia. Evitano di ricopiare grossi blocchi di dati: si passa un indirizzo, pochi byte, anzichรฉ un intero array. E rendono possibili le strutture che crescono e si riducono mentre il programma gira, come le liste concatenate e gli alberi. Se stai appena iniziando, la nostra guida alle variabili mette in chiaro le basi prima di affrontare questo argomento.

L'allocazione dinamica della memoria

Finora le nostre variabili avevano una dimensione nota in anticipo. Ma come si fa quando, nel momento in cui si scrive il codice, non si sa quanti elementi servirร  conservare? La risposta sta nell'allocazione dinamica: si chiede memoria mentre il programma gira, e poi la si restituisce una volta che non serve piรน. In C si usa malloc per riservare e free per liberare.

int *array = malloc(10 * sizeof(int));  // 10 interi
if (array != NULL) {
    array[0] = 1;
    // ... utilizzo ...
    free(array);   // restituiamo la memoria
}

In C++ abbiamo new e delete, che fanno la stessa cosa rispettando meglio i tipi.

int *valore = new int(42);
delete valore;

La regola d'oro sta in una riga: a ogni allocazione deve corrispondere una liberazione. Dimenticare il free o il delete significa lasciare memoria occupata per niente.

Le trappole che spaventano, e come evitarle

La cattiva fama dei puntatori nasce soprattutto da tre errori classici. Il primo รจ la perdita di memoria: si alloca senza mai liberare, e il programma rosicchia la memoria fino a esaurirla. Il secondo รจ il puntatore pendente, che indica una zona giร  liberata; accedervi produce un risultato imprevedibile. Il terzo รจ il puntatore nullo che si dereferenzia senza controllarlo, e che provoca il famoso errore di segmentazione.

La buona notizia รจ che queste trappole si neutralizzano con abitudini semplici. Si inizializza sempre un puntatore, anche solo a NULL. Si verifica che non sia nullo prima di usarlo. E dopo un free, si rimette il puntatore a NULL per non riutilizzarlo per sbaglio. Questi riflessi diventano in fretta una seconda natura.

Cosa cambia con il C++ moderno

Il C++ recente ha addolcito molto tutto questo con i puntatori intelligenti. Uno std::unique_ptr o uno std::shared_ptr si occupa di liberare la memoria automaticamente non appena non serve piรน, eliminando in un colpo solo gran parte delle perdite.

#include <memory>

std::unique_ptr<int> valore = std::make_unique<int>(42);
// liberazione automatica: nessun delete da scrivere

Ciรฒ detto, capire i puntatori ยซ grezzi ยป resta indispensabile: i puntatori intelligenti sono costruiti sopra di essi, e il codice esistente ne รจ pieno. Conviene sempre conoscere entrambi. Lo stesso spirito anima alcune librerie C piรน datate, come quella che descriviamo nel nostro articolo su conio.h, _kbhit e getch.

Per approfondire

I puntatori non si domano in una sola lettura, ma con la pratica. Scrivi piccoli programmi, disegna la memoria su un foglio, segui ogni indirizzo a mano. Nel giro di qualche giorno, ciรฒ che sembrava oscuro diventa un riflesso.

Se preferisci un supporto cartaceo per procedere al tuo ritmo, un buon libro sul linguaggio C resta un ottimo compagno di studio, in aggiunta ai tutorial online.

In qualitร  di Affiliato Amazon, riceviamo un guadagno dagli acquisti idonei.

Articoli recenti

Commenti recenti

  1. Massimiliano Ferretti su I Commenti

    Mi permetto di aggiungere una mia considerazione personale che ho riportato dall'utilizzo di C#. Personalmente mi piace commentare funzioni e…

  2. Personalmente ritengo che utilizzare git porti sempre dei vantaggi anche per lo sviluppo solo. Giร  solo la possibilitร  di fare…

  3. ciao, il link a discord non รจ piu valido, vorrei utilizzare il materiale che hai pubblicato tempo fa, come faccio?

"

Itamde รจ anche una scuola di programmazione online.

Itamde

Impara ciรฒ che desideri, al tuo ritmo

0 Commenti

Invia Un Commento

Il tuo indirizzo email non sarร  pubblicato. I campi obbligatori sono contrassegnati *

Potrebbe interessarti anche...

Ottimizzare WordPress per il posizionamento nei motori di ricerca

I plugin SEO essenziali per WordPress

Le estensioni SEO davvero utili per WordPress โ€” suite SEO, cache, immagini, redirect โ€” e come combinarle senza appesantire il sito.

Rimani aggiornato sulle ultime notizie e novitร 

Accedi ai contenuti riservati

Scopri il dietro le quinte dei nostri progetti, risorse esclusive e lo stato di avanzamento delle nostre creazioni in tempo reale.

Iscriviti alla newsletter

Ricevi le nostre notizie, le nostre riflessioni creative e le novitร  dell'atelier direttamente nella tua casella di posta elettronica.

Seguici

Unisciti alla nostra community sui social network per seguire i nostri progetti quotidiani e interagire con noi.