I puntatori in C sono fondamentali per generare del codice efficiente.

I puntatori sono fondamentalmente delle variabili che rappresentano la locazione di altri elementi nel programma, come variabili, strutture, funzioni, array, file, ecc…

Abbiamo già parlato delle variabili in questo articolo: variabili.

Adesso precisiamo che ad ogni variabile corrisponde un nome, una locazione di memoria e l’indirizzo della locazione di memoria.

Infatti le variabili sono memorizzate nella memoria RAM del computer in un indirizzo specifico e per un numero di byte corrispondente alla loro dimensione.

Quindi in C l’operatore &, che abbiamo utilizzato nella funzione scanf, ci restituisce l’indirizzo di memoria di una variabile.

Banner Pubblicitario

Dobbiamo precisare che l’indirizzo restituito non è quello fisico ma quello logico precedente la traslazione da parte della MMU del processore che appunto gestisce le richieste di accesso alla memoria.

Un indirizzo può essere assegnato solo a una speciale categoria di variabili denominate puntatori.

Quindi i puntatori sono variabili abilitate a contenere un indirizzo.

Innanzitutto diciamo che, una variabile di tipo puntatore viene dichiarata premettendo il simbolo * (operatore unario) al nome della variabile. L’operatore * viene anche denominato operatore di in-direzione.

Dunque questa è la sintassi della dichiarazione dei puntatori in C:

tipo *nome_var;


Quindi facciamo alcuni esempi di dichiarazione delle variabili puntatore:

Banner pubblicitario

int *pa; // puntatore ad una variabile intera

char *pc; //puntatore ad una variabile char

float *pf; //puntatore ad una variabile float

void *p; //puntatore a void

Appena dichiarati i puntatori sono inizializzati al valore speciale NULL.


Esempio di utilizzo dei puntatori in C

Iniziamo facendo dei semplicissimi esempi sulla dichiarazione di un puntatore in C.

int *pa, a; //pa è una variabile di tipo puntatore ad int

pa=&a //il puntatore pa assume l’indirizzo di a

Quindi provate ad eseguire questo semplice codice, vedrete che stamperà l’indirizzo della variabile a.

int main(void) {
	int *pa, a=10;
	
        pa=&a;
	printf("Indirizzo della variabile: %x ", pa);
	printf("Valore variabile: %d ", *pa);
//oppure avrei potuto scrivere: printf("Valore variabile: %d ", a);
	return 0;
}

N.B. Al posto di %x si può utilizzare %p, anche perchè talvolta (raramente) %x può generare un comportamento errato quando si porta un programma nelle architetture a 64 bit.

Dopo aver assegnato a pa l’indirizzo di a, è possibile accedere alla stessa area di memoria in due modi diversi:

attraverso la variabile a;

attraverso la dereferenziazione di pa, cioè *pa.

Facciamo ancora un semplice esempio:

int *pa, a;

pa=&a;

*pa=10; // è equivalente a scrivere a=10

Infatti, se compilate questo codice, verrà stampato il valore 10 perché il puntatore pa assume l’indirizzo di a (pa=&a).

int main(void) {
	int *pa, a;
	
	pa=&a;
	*pa=10; // è equivalente ad a=10
	printf("Il valore di a e': %d ", a);
        
        return 0;
}


Secondo esempio

Per capire meglio il concetto di variabile puntatore, modifichiamo l’esempio di prima:

int *pa, *pb, a;

pa=&a;

pb=pa;

*pb=10;

Abbiamo assegnato alla seconda variabile puntatore pb il contenuto di pa e quindi l’indirizzo di memoria della variabile a.

In questo caso *pb=10 è equivalente a scrivere *pa=10 e a=10;

Infatti provate a compilare il codice sotto, stamperà che la variabile a vale 10.

int main(void) {
	int *pa, *pb, a;
	
	pa=&a;
	pb=pa;
	*pb=10; 
	
	printf("Il valore di a e': %d ", a);

	return 0;
}

Nell’esempio sopra abbiamo assegnato ad un puntatore un altro puntatore (pb=pa) ma attenzione devono essere compatibili, cioè devono riferirsi allo stesso tipo di dati per avere il risultato desiderato. Se vogliamo trasformare un puntatore in modo che si riferisca ad un tipo di dati differente allora dovremmo utilizzare il cast.

Assegnazioni tra puntatori in C

Facciamo quindi un esempio:

char *pc;

int *pa;

pa=(int *) pc; //in questo caso dunque il cast rende possibile l’assegnazione tra puntatori


Alcuni link utili

Realizzare un menù di scelta in C

Strutture complesse in C

Esercizio sulle struct in C

Typedef struct C

Media per riga e per colonna

Somma elementi diagonale principale di una matrice

Come sommare gli elementi della cornice esterna

Come sommare due matrici

Sommare dei numeri di una matrice

Matrice trasposta

Prodotto tra matrici

Ricerca elementi in una matrice

Inserire dati in una matrice

Tavola pitagorica in C

Array multidimensionali

Programma sui triangoli in C

Media dei numeri in un array

Array con numeri random

Quick sort in C

Selection sort in C

Merge sort in C

Insertion Sort in C