Puntatori in C: cos'è il puntatore nella programmazione C? Tipi
Cos'è il puntatore in C?
Migliori Pointer in C, è una variabile che memorizza l'indirizzo di un'altra variabile. Un puntatore può essere utilizzato anche per fare riferimento a un'altra funzione del puntatore. Un puntatore può essere incrementato/decrementato, ovvero puntare alla posizione di memoria successiva/precedente. Lo scopo del puntatore è risparmiare spazio di memoria e ottenere tempi di esecuzione più rapidi.
Come utilizzare i puntatori in C
Se dichiariamo una variabile v di tipo int, v memorizzerà effettivamente un valore.
v è uguale a zero ora.
Tuttavia, ogni variabile, oltre al valore, ha anche il suo indirizzo (o, in parole povere, dove si trova nella memoria). L'indirizzo può essere recuperato inserendo una e commerciale (&) prima del nome della variabile.
Se stampi l'indirizzo di una variabile sullo schermo, apparirà come un numero totalmente casuale (inoltre può essere diverso da corsa a corsa).
Proviamolo in pratica con il puntatore nell'esempio in C
L'output di questo programma è -480613588.
Ora, cos'è un puntatore? Invece di memorizzare un valore, un puntatore memorizzerà l'indirizzo di una variabile.
Variabile puntatore
Int *y = &v;
| VARIABILE | PUNTATORE |
|---|---|
| A APPREZZIAMO memorizzato in a detto indirizzo di archiviazione/memoria | A variabile che punta a l'indirizzo di archiviazione/memoria di un altro variabile |
Dichiarazione di un puntatore
Come le variabili, i puntatori in Programmazione C. devono essere dichiarati prima di poter essere utilizzati nel tuo programma. I puntatori possono essere chiamati come vuoi, purché rispettino le regole di denominazione del C. Una dichiarazione di puntatore ha la seguente forma.
data_type * pointer_variable_name;
Qui,
- tipo di dati è il tipo base del puntatore dei tipi di variabile del C e indica il tipo della variabile a cui punta il puntatore.
- L'asterisco (*: lo stesso asterisco utilizzato per la moltiplicazione), che è un operatore di indirezione, dichiara un puntatore.
Vediamo alcune dichiarazioni di puntatori valide in questo tutorial sui puntatori C:
int *ptr_thing; /* pointer to an integer */ int *ptr1,thing;/* ptr1 is a pointer to type integer and thing is an integer variable */ double *ptr2; /* pointer to a double */ float *ptr3; /* pointer to a float */ char *ch1 ; /* pointer to a character */ float *ptr, variable;/*ptr is a pointer to type float and variable is an ordinary float variable */
Inizializza un puntatore
Dopo aver dichiarato un puntatore, lo inizializziamo come variabili standard con un indirizzo di variabile. Se i puntatori nella programmazione C non vengono inizializzati e utilizzati in un programma, i risultati possono essere imprevedibili e potenzialmente disastrosi.
Per ottenere l'indirizzo di una variabile, utilizziamo l'operatore e commerciale (&), posizionato prima del nome di una variabile di cui abbiamo bisogno dell'indirizzo. L'inizializzazione del puntatore viene eseguita con la seguente sintassi.
Sintassi del puntatore
pointer = &variable;
Di seguito è riportato un semplice programma per l'illustrazione del puntatore:
#include <stdio.h>
int main()
{
int a=10; //variable declaration
int *p; //pointer variable declaration
p=&a; //store address of variable a in pointer p
printf("Address stored in a variable p is:%x\n",p); //accessing the address
printf("Value stored in a variable p is:%d\n",*p); //accessing the value
return 0;
}
Produzione:
Address stored in a variable p is:60ff08 Value stored in a variable p is:10
| Operator | Significato |
|---|---|
| * | Ha 2 scopi
|
| & | Serve solo 1 scopo
|
Tipi di puntatori in C
Di seguito sono riportate le diverse Tipi di puntatori in C:
Puntatore nullo
Possiamo creare un puntatore nullo assegnando un valore nullo durante la dichiarazione del puntatore. Questo metodo è utile quando non è assegnato alcun indirizzo al puntatore. Un puntatore nullo contiene sempre il valore 0.
Il programma seguente illustra l'uso di un puntatore nullo:
#include <stdio.h>
int main()
{
int *p = NULL; //null pointer
printf(“The value inside variable p is:\n%x”,p);
return 0;
}
Produzione:
The value inside variable p is: 0
Puntatore del Vuoto
In Programmazione C., un puntatore void è anche chiamato puntatore generico. Non ha alcun tipo di dati standard. Un puntatore void viene creato utilizzando la parola chiave void. Può essere utilizzato per memorizzare l'indirizzo di qualsiasi variabile.
Il programma seguente illustra l'uso di un puntatore vuoto:
#include <stdio.h>
int main()
{
void *p = NULL; //void pointer
printf("The size of pointer is:%d\n",sizeof(p));
return 0;
}
Produzione:
The size of pointer is:4
Puntatore selvaggio
Si dice che un puntatore sia un puntatore jolly se non viene inizializzato su nulla. Questi tipi di puntatori C non sono efficienti perché potrebbero puntare a posizioni di memoria sconosciute che potrebbero causare problemi nel nostro programma e potrebbero portare al crash del programma. Bisogna sempre stare attenti mentre si lavora con i puntatori selvaggi.
Il programma seguente illustra l'uso del puntatore jolly:
#include <stdio.h>
int main()
{
int *p; //wild pointer
printf("\n%d",*p);
return 0;
}
Produzione:
timeout: the monitored command dumped core sh: line 1: 95298 Segmentation fault timeout 10s main
Altri tipi di puntatori in 'c' sono i seguenti:
- Puntatore penzolante
- Puntatore complesso
- Puntatore vicino
- Puntatore lontano
- Puntatore enorme
Puntatori di accesso diretto e indiretto
In C esistono due modi equivalenti per accedere e manipolare un contenuto variabile
- Accesso diretto: utilizziamo direttamente il nome della variabile
- Accesso indiretto: utilizziamo un puntatore alla variabile
Capiamolo con l'aiuto del programma seguente
#include <stdio.h>
/* Declare and initialize an int variable */
int var = 1;
/* Declare a pointer to int */
int *ptr;
int main( void )
{
/* Initialize ptr to point to var */
ptr = &var;
/* Access var directly and indirectly */
printf("\nDirect access, var = %d", var);
printf("\nIndirect access, var = %d", *ptr);
/* Display the address of var two ways */
printf("\n\nThe address of var = %d", &var);
printf("\nThe address of var = %d\n", ptr);
/*change the content of var through the pointer*/
*ptr=48;
printf("\nIndirect access, var = %d", *ptr);
return 0;}
Dopo aver compilato il programma senza errori, il risultato è:
Direct access, var = 1 Indirect access, var = 1 The address of var = 4202496 The address of var = 4202496 Indirect access, var = 48
Aritmetica dei puntatori in C
Le operazioni del puntatore sono riassunte nella figura seguente

Operazione prioritaria (precedenza)
Quando si lavora con i puntatori C, dobbiamo osservare le seguenti regole di priorità:
- Gli operatori * e & hanno la stessa priorità degli operatori unari (la negazione!, l'incremento++, il decremento–).
- Nella stessa espressione, gli operatori unari *, &,!, ++, – vengono valutati da destra a sinistra.
Se un puntatore P punta a una variabile X, allora * P può essere utilizzato ovunque X possa essere scritto.
Le seguenti espressioni sono equivalenti:
int X =10 int *P = &Y; For the above code, below expressions are true
| Espressione | Espressione equivalente |
|---|---|
| Y=*P+1
*P=*P+10 *P+=2 ++*P (*P)++ |
Y=X+1
X=X+10 X+=2 ++X X++ |
In quest'ultimo caso sono necessarie le parentesi: poiché gli operatori unari * e ++ vengono valutati da destra a sinistra, senza le parentesi verrebbe incrementato il puntatore P, non l'oggetto su cui punta P.
La tabella seguente mostra le operazioni aritmetiche e di base che possono essere utilizzate quando si ha a che fare con i puntatori C
| Funzionamento | Spiegazione |
|---|---|
| Assegnazione | int *P1,*P2 P1=P2; P1 e P2 puntano alla stessa variabile intera |
| Incremento e decremento | Intero *P1; P1++;P1– ; |
| Aggiunta di un offset (costante) | Ciò consente al puntatore di spostare N elementi in una tabella. Il puntatore verrà aumentato o diminuito di N volte il numero di byte (i) del tipo della variabile. P1+5; |
Puntatori e array C con esempi
Tradizionalmente accediamo agli elementi dell'array utilizzando il relativo indice, ma questo metodo può essere eliminato utilizzando i puntatori. I puntatori facilitano l'accesso a ciascun elemento dell'array.
#include <stdio.h>
int main()
{
int a[5]={1,2,3,4,5}; //array initialization
int *p; //pointer declaration
/*the ptr points to the first element of the array*/
p=a; /*We can also type simply ptr==&a[0] */
printf("Printing the array elements using pointer\n");
for(int i=0;i<5;i++) //loop for traversing array elements
{
printf("\n%x",*p); //printing array elements
p++; //incrementing to the next element, you can also write p=p+1
}
return 0;
}
Produzione:
1 2 3 4 5
L'aggiunta di un numero particolare a un puntatore sposterà la posizione del puntatore al valore ottenuto da un'operazione di addizione. Supponiamo che p sia un puntatore che attualmente punta alla posizione di memoria 0 se eseguiamo la seguente operazione di addizione, p+1, allora verrà eseguita in questo modo:
Poiché p attualmente punta alla posizione 0 dopo aver aggiunto 1, il valore diventerà 1 e quindi il puntatore punterà alla posizione di memoria 1.
Puntatori e stringhe C con esempi
Una stringa è un array di oggetti char, che termina con un carattere null '\ 0'. Possiamo manipolare le stringhe usando i puntatori. Questo puntatore nell'esempio in C spiega questa sezione
#include <stdio.h>
#include <string.h>
int main()
{
char str[]="Hello Guru99!";
char *p;
p=str;
printf("First character is:%c\n",*p);
p =p+1;
printf("Next character is:%c\n",*p);
printf("Printing all the characters in a string\n");
p=str; //reset the pointer
for(int i=0;i<strlen(str);i++)
{
printf("%c\n",*p);
p++;
}
return 0;
}
Produzione:
First character is:H Next character is:e Printing all the characters in a string H e l l o G u r u 9 9 !
Un altro modo per gestire le stringhe è tramite un array di puntatori come nel seguente programma:
#include <stdio.h>
int main(){
char *materials[ ] = { "iron", "copper", "gold"};
printf("Please remember these materials :\n");
int i ;
for (i = 0; i < 3; i++) {
printf("%s\n", materials[ i ]);}
return 0;}
Produzione:
Please remember these materials: iron copper gold
Vantaggi dei puntatori in C
- I puntatori sono utili per accedere alle posizioni di memoria.
- I puntatori forniscono un modo efficiente per accedere agli elementi di una struttura di array.
- I puntatori vengono utilizzati per l'allocazione dinamica della memoria e per la deallocazione.
- I puntatori vengono utilizzati per formare strutture dati complesse, come liste concatenate, grafici, alberi, ecc.
Svantaggi dei puntatori in C
- I puntatori sono un po' complessi da capire.
- I puntatori possono causare diversi errori, ad es. errori di segmentazione, oppure possono accedere ad una posizione di memoria non necessaria.
- Se a un puntatore viene fornito un valore errato, ciò potrebbe causare il danneggiamento della memoria.
- I puntatori sono anche responsabili della perdita di memoria.
- I puntatori sono relativamente più lenti di quelli delle variabili.
- I programmatori trovano molto difficile lavorare con i puntatori; pertanto è responsabilità del programmatore manipolare attentamente un puntatore.
Sintesi
- Un puntatore non è altro che una posizione di memoria in cui vengono archiviati i dati.
- Un puntatore viene utilizzato per accedere alla posizione di memoria.
- Esistono vari tipi di puntatori come puntatore nullo, puntatore jolly, puntatore void e altri tipi di puntatori.
- I puntatori possono essere utilizzati con array e stringhe per accedere agli elementi in modo più efficiente.
- Possiamo creare puntatori a funzione per invocare una funzione in modo dinamico.
- Le operazioni aritmetiche possono essere eseguite su un puntatore noto come aritmetica dei puntatori.
- I puntatori possono anche puntare a funzioni che facilitano la chiamata di diverse funzioni nel caso di definizione di un array di puntatori.
- Quando vuoi gestire tipi di dati variabili diversi, puoi utilizzare un puntatore void typecast.


