I puntatori sono rappresentazioni simboliche degli indirizzi. Consentono ai programmi di simulare call-by-reference nonché di creare e manipolare strutture di dati dinamiche. L'iterazione sugli elementi negli array o in altre strutture dati è uno degli usi principali dei puntatori.
L'indirizzo della variabile con cui stai lavorando è assegnato alla variabile puntatore che punta allo stesso tipo di dati (come un int o una stringa).
delizia soleggiata
Sintassi:
datatype *var_name; int *ptr; // ptr can point to an address which holds int data>

Come utilizzare un puntatore?
- Definire una variabile puntatore
- Assegnare l'indirizzo di una variabile a un puntatore utilizzando l'operatore unario (&) che restituisce l'indirizzo di quella variabile.
- Accedere al valore memorizzato nell'indirizzo utilizzando l'operatore unario (*) che restituisce il valore della variabile situata all'indirizzo specificato dal suo operando.
Il motivo per cui associamo il tipo di dati a un puntatore è che sa in quanti byte sono archiviati i dati . Quando incrementiamo un puntatore, aumentiamo il puntatore della dimensione del tipo di dati a cui punta.

// C++ program to illustrate Pointers #include using namespace std; void geeks() { int var = 20; // declare pointer variable int* ptr; // note that data type of ptr and var must be same ptr = &var; // assign the address of a variable to a pointer cout << 'Value at ptr = ' << ptr << '
'; cout << 'Value at var = ' << var << '
'; cout << 'Value at *ptr = ' << *ptr << '
'; } // Driver program int main() { geeks(); return 0; }>
Produzione
Value at ptr = 0x7ffe454c08cc Value at var = 20 Value at *ptr = 20>
Riferimenti e puntatori
Esistono 3 modi per passare argomenti C++ a una funzione:
- Chiamata per valore
- Chiamata per riferimento con un argomento puntatore
- Chiamata per riferimento con un argomento di riferimento
// C++ program to illustrate call-by-methods #include using namespace std; // Pass-by-Value int square1(int n) { // Address of n in square1() is not the same as n1 in // main() cout << 'address of n1 in square1(): ' << &n << '
'; // clone modified inside the function n *= n; return n; } // Pass-by-Reference with Pointer Arguments void square2(int* n) { // Address of n in square2() is the same as n2 in main() cout << 'address of n2 in square2(): ' << n << '
'; // Explicit de-referencing to get the value pointed-to *n *= *n; } // Pass-by-Reference with Reference Arguments void square3(int& n) { // Address of n in square3() is the same as n3 in main() cout << 'address of n3 in square3(): ' << &n << '
'; // Implicit de-referencing (without '*') n *= n; } void geeks() { // Call-by-Value int n1 = 8; cout << 'address of n1 in main(): ' << &n1 << '
'; cout << 'Square of n1: ' << square1(n1) << '
'; cout << 'No change in n1: ' << n1 << '
'; // Call-by-Reference with Pointer Arguments int n2 = 8; cout << 'address of n2 in main(): ' << &n2 << '
'; square2(&n2); cout << 'Square of n2: ' << n2 << '
'; cout << 'Change reflected in n2: ' << n2 << '
'; // Call-by-Reference with Reference Arguments int n3 = 8; cout << 'address of n3 in main(): ' << &n3 << '
'; square3(n3); cout << 'Square of n3: ' << n3 << '
'; cout << 'Change reflected in n3: ' << n3 << '
'; } // Driver program int main() { geeks(); }>
Produzione
address of n1 in main(): 0x7fffa7e2de64 address of n1 in square1(): 0x7fffa7e2de4c Square of n1: 64 No change in n1: 8 address of n2 in main(): 0x7fffa7e2de68 address of n2 in square2(): 0x7fffa7e2de68 Square of n2: 64 Change reflected in n2: 64 address of n3 in main(): 0x7fffa7e2de6c address of n3 in square3(): 0x7fffa7e2de6c Square of n3: 64 Change reflected in n3: 64>
In C++, per impostazione predefinita gli argomenti vengono passati per valore e le modifiche apportate alla funzione chiamata non si rifletteranno nella variabile passata. Le modifiche vengono apportate in un clone creato dalla funzione chiamata. Se desideri modificare direttamente la copia originale (specialmente nel passaggio di oggetti o array di grandi dimensioni) e/o evitare il sovraccarico della clonazione, utilizziamo il pass-by-reference. Il passaggio per riferimento con argomenti di riferimento non richiede alcuna sintassi goffa per il riferimento e il dereferenziamento.
- Puntatori a funzioni in C
- Puntatore a una funzione
Nome dell'array come puntatori
UN vettore name contiene l'indirizzo del primo elemento dell'array che agisce come un puntatore costante. Significa che l'indirizzo memorizzato nel nome dell'array non può essere modificato. Ad esempio, se abbiamo un array denominato val allora val E &val[0] possono essere usati in modo intercambiabile.
C++ // C++ program to illustrate Array Name as Pointers #include using namespace std; void geeks() { // Declare an array int val[3] = { 5, 10, 20 }; // declare pointer variable int* ptr; // Assign the address of val[0] to ptr // We can use ptr=&val[0];(both are same) ptr = val; cout << 'Elements of the array are: '; cout << ptr[0] << ' ' << ptr[1] << ' ' << ptr[2]; } // Driver program int main() { geeks(); }>
Produzione
Elements of the array are: 5 10 20>

Se il puntatore ptr viene inviato a una funzione come argomento, è possibile accedere all'array val in modo simile. Puntatore vs array
Espressioni dei puntatori e aritmetica dei puntatori
Un insieme limitato di aritmetica le operazioni possono essere eseguite su puntatori che sono:
esempi di programmazione Python
- incrementato ( ++ )
- decrementato (—)
- è possibile aggiungere un numero intero a un puntatore ( + o += )
- un numero intero può essere sottratto da un puntatore ( – o -= )
- differenza tra due puntatori (p1-p2)
( Nota: L'aritmetica dei puntatori non ha senso se non viene eseguita su un array.)
C++ // C++ program to illustrate Pointer Arithmetic #include using namespace std; void geeks() { // Declare an array int v[3] = { 10, 100, 200 }; // declare pointer variable int* ptr; // Assign the address of v[0] to ptr ptr = v; for (int i = 0; i < 3; i++) { cout << 'Value at ptr = ' << ptr << '
'; cout << 'Value at *ptr = ' << *ptr << '
'; // Increment pointer ptr by 1 ptr++; } } // Driver program int main() { geeks(); }>
Produzione
Value at ptr = 0x7ffe5a2d8060 Value at *ptr = 10 Value at ptr = 0x7ffe5a2d8064 Value at *ptr = 100 Value at ptr = 0x7ffe5a2d8068 Value at *ptr = 200>

Notazione avanzata del puntatore
Considera la notazione dei puntatori per gli array numerici bidimensionali. considerare la seguente dichiarazione
int nums[2][3] = { { 16, 18, 20 }, { 25, 26, 27 } };>
In generale, nums[ i ][ j ] equivale a *(*(nums+i)+j)

Puntatori e stringhe letterali
Le stringhe letterali sono matrici contenenti sequenze di caratteri con terminazione null. I valori letterali stringa sono array di tipo carattere più carattere nullo terminale, con ciascuno degli elementi di tipo const char (poiché i caratteri di stringa non possono essere modificati).
>
Questo dichiara un array con la rappresentazione letterale di geek, quindi un puntatore al suo primo elemento viene assegnato a ptr. Se immaginiamo che geek sia memorizzato nelle locazioni di memoria che iniziano all'indirizzo 1800, possiamo rappresentare la dichiarazione precedente come:

Poiché puntatori e array si comportano allo stesso modo nelle espressioni, ptr può essere utilizzato per accedere ai caratteri di una stringa letterale. Per esempio:
char ptr = 0; char x = *(ptr+3); char y = ptr[3];>
Qui, sia x che y contengono k memorizzato a 1803 (1800+3).
Puntatori a puntatori
In C++ possiamo creare un puntatore a un puntatore che a sua volta può puntare a dati o a un altro puntatore. La sintassi richiede semplicemente l'operatore unario (*) per ogni livello di indiretto durante la dichiarazione del puntatore.
char a; char *b; char ** c; a = ’g’; b = &a; c = &b;>
Qui b punta a un carattere che memorizza 'g' e c punta al puntatore b.
jquery un clic
Puntatori del Vuoto
Questo è un tipo speciale di puntatore disponibile in C++ che rappresenta l'assenza di tipo. Puntatori del vuoto sono puntatori che puntano a un valore che non ha tipo (e quindi anche una lunghezza indeterminata e proprietà di dereferenziazione indeterminate). Ciò significa che i puntatori void hanno una grande flessibilità poiché possono puntare a qualsiasi tipo di dati. C’è un vantaggio per questa flessibilità. Questi puntatori non possono essere dereferenziati direttamente. Devono essere prima trasformati in qualche altro tipo di puntatore che punti a un tipo di dati concreto prima di essere dereferenziati.
un esempio di sistema operativo open source èC++
// C++ program to illustrate Void Pointer #include using namespace std; void increase(void* data, int ptrsize) { if (ptrsize == sizeof(char)) { char* ptrchar; // Typecast data to a char pointer ptrchar = (char*)data; // Increase the char stored at *ptrchar by 1 (*ptrchar)++; cout << '*data points to a char' << '
'; } else if (ptrsize == sizeof(int)) { int* ptrint; // Typecast data to a int pointer ptrint = (int*)data; // Increase the int stored at *ptrchar by 1 (*ptrint)++; cout << '*data points to an int' << '
'; } } void geek() { // Declare a character char c = 'x'; // Declare an integer int i = 10; // Call increase function using a char and int address // respectively increase(&c, sizeof(c)); cout << 'The new value of c is: ' << c << '
'; increase(&i, sizeof(i)); cout << 'The new value of i is: ' << i << '
'; } // Driver program int main() { geek(); }>
Produzione
*data points to a char The new value of c is: y *data points to an int The new value of i is: 11>
Puntatori non validi
Un puntatore dovrebbe puntare a un indirizzo valido ma non necessariamente a elementi validi (come per gli array). Questi sono chiamati puntatori non validi. Anche i puntatori non inizializzati sono puntatori non validi.
int *ptr1; int arr[10]; int *ptr2 = arr+20;>
Qui, ptr1 non è inizializzato, quindi diventa un puntatore non valido e ptr2 è fuori dai limiti di arr, quindi diventa anch'esso un puntatore non valido. (Nota: i puntatori non validi non generano necessariamente errori di compilazione)
Puntatori NULL
UN puntatore nullo è un puntatore che non punta da nessuna parte e non solo un indirizzo non valido. Di seguito sono riportati 2 metodi per assegnare un puntatore come NULL;
int *ptr1 = 0; int *ptr2 = NULL;>
Vantaggi dei puntatori
- I puntatori riducono il codice e migliorano le prestazioni. Vengono utilizzati per recuperare stringhe, alberi, array, strutture e funzioni.
- I puntatori ci consentono di restituire più valori dalle funzioni.
- Oltre a ciò, i puntatori ci consentono di accedere a una posizione di memoria nella memoria del computer.
Articoli Correlati:
- Puntatore opaco
- Puntatori vicini, lontani ed enormi
Quiz:
- Nozioni di base sul puntatore
- Puntatore avanzato