# C/Vettori e puntatori/Puntatori

C
Copertina Tutti i moduli · Sviluppo
* LinguaggioC/Linguaggio
** PanoramicaC/Linguaggio/Panoramica
** Struttura del linguaggioC/Linguaggio/Struttura del linguaggio
* Variabili, operatori e costantiC/Variabili, operatori e costanti
** VariabiliC/Variabili, operatori e costanti/Variabili
** Operatori aritmeticiC/Variabili, operatori e costanti/Operatori aritmetici
** Operatori sui bitC/Variabili, operatori e costanti/Operatori sui bit
** CostantiC/Variabili, operatori e costanti/Costanti
* Blocchi e funzioniC/Blocchi e funzioni
** Blocchi if e switchC/Blocchi e funzioni/Blocchi if e switch
** Operatori logiciC/Blocchi e funzioni/Operatori logici
** CicliC/Blocchi e funzioni/Cicli
** FunzioniC/Blocchi e funzioni/Funzioni
** mainC/Blocchi e funzioni/main
** LibrerieC/Blocchi e funzioni/Librerie
** RicorsivitàC/Blocchi e funzioni/Ricorsività
* Vettori e puntatoriC/Vettori e puntatori
** VettoriC/Vettori e puntatori/Vettori
** PuntatoriC/Vettori e puntatori/Puntatori
** Interscambiabilità tra puntatori e vettoriC/Vettori e puntatori/Interscambiabilità tra puntatori e vettori
* StringheC/Variabili, operatori e costanti/Stringhe
* Enumerazioni, strutture e unioniC/Enumerazioni, strutture e unioni
** EnumerazioniC/Enumerazioni, strutture e unioni/Enumerazioni
** StruttureC/Enumerazioni, strutture e unioni/Strutture
** UnioniC/Enumerazioni, strutture e unioni/Unioni
* Conversioni di tipoC/Conversioni di tipo
* Lettura e scrittura su fileC/Lettura e scrittura su file
** File di TestoC/Lettura e scrittura su file/File di Testo
** File BinariC/Lettura e scrittura su file/File Binari
* Compilatore e precompilatoreC/Compilatore e precompilatore
** CompilatoreC/Compilatore e precompilatore/Compilatore
** DirettiveC/Compilatore e precompilatore/Direttive
** HeaderC/Compilatore e precompilatore/Header
* VisibilitàC/Visibilità
* Gestione della memoriaC/Gestione della memoria
* Le applicazioni CGIC/Le applicazioni CGI
* Appendice
** Librerie standardC/Appendice/Librerie standard
*** assert.hC/Appendice/Librerie standard/assert.h
*** ctype.hC/Appendice/Librerie standard/ctype.h
*** errno.hC/Appendice/Librerie standard/errno.h
*** float.hC/Appendice/Librerie standard/float.h
*** limits.hC/Appendice/Librerie standard/limits.h
*** locale.hC/Appendice/Librerie standard/locale.h
*** math.hC/Appendice/Librerie standard/math.h
*** setjmp.hC/Appendice/Librerie standard/setjmp.h
*** signal.hC/Appendice/Librerie standard/signal.h
*** stdarg.hC/Appendice/Librerie standard/stdarg.h
*** stddef.hC/Appendice/Librerie standard/stddef.h
*** stdio.hC/Appendice/Librerie standard/stdio.h
*** stdlib.hC/Appendice/Librerie standard/stdlib.h
*** string.hC/Appendice/Librerie standard/string.h
*** time.hC/Appendice/Librerie standard/time.h
** StrumentiC/Appendice/Strumenti
*** InstallerC/Appendice/Strumenti/Installer
** Librerie esterneC/Appendice/Librerie esterne
* Bibliografia
    IndiceC/Indice
Modifica il sommario
I puntatori, in C, sono uno strumento molto potente e utile, ma sono anche frequente causa di errori insidiosi.
Un puntatore è una variabile che contiene l'indirizzo di memoria di un'altra variabile (il puntatore x punta alla variabile y).

## Sintassi
### Dichiarazione

Un puntatore si dichiara nel seguente modo:
Si noti l'asterisco prima del nome del puntatore.
Il precedente codice non genera due puntatori, ma uno solo, a. La variabile b è un intero, perché l'operatore * vale soltanto per la prima variabile. Qualora si desideri dichiarare più variabili di tipo puntatore, l'asterisco va ripetuto per ciascuna di esse:
È possibile creare array di puntatori:
crea un array di cinque puntatori ad intero. Per maggiori informazioni vedere la sezione sugli array.

### Assegnazione

Prima di utilizzare un puntatore, bisogna assegnarlo ad un indirizzo di memoria, ovvero fare in modo che esso punti ad una variabile.
Questo codice fa puntare il puntatore a alla variabile b. È importante notare che a non contiene il valore 10, ma l'indirizzo di memoria della variabile b, ottenuto tramite l'operatore &.
È anche possibile fare in modo che un puntatore punti alla stessa variabile puntata da un altro puntatore:

### Accesso

Dopo aver dichiarato e assegnato un puntatore ad una variabile, è possibile usarlo.
Questo codice stamperà due volte il numero 10.

## Aritmetica dei puntatori

È possibile addizionare o sottrarre ad un puntatore un valore intero. Questo farà in modo che il puntatore punti alla cella di memoria immediatamente successiva.
Se un intero occupa 2 byte, allora se si somma 1 al puntatore che contiene l'indirizzo 100, questo non conterrà 101, ma 102. Questo appunto perché si assume che un intero occupi 2 byte.
Allo stesso modo, se si sottrae 1, il puntatore conterrà il valore 98.
Inoltre, è possibile calcolare la differenza tra due puntatori per capire quante celle di memoria ci sono fra i due. È possibile anche confrontarli per capire se puntano allo stesso indirizzo o meno.
L'aritmetica dei puntatori permette anche l'interscambiabilità tra puntatori e vettori.

## Funzioni e puntatori

Se ad una funzione viene passato un puntatore (che può essere l'indirizzo di una variabile tramite l'operatore di indirizzo "&", oppure un puntatore a quella variabile), essa sarà in grado di modificare il valore puntato dal puntatore. tale azione e' detta "passaggio di variabile per riferimento". Per esempio:
Questa piccola applicazione stamperà 4. Ecco come:
* int a=2; Questa istruzione dichiara una variabile intera a e la inizializza con il valore 2.
* doubleof(&a); Chiama la funzione doubleof, passandole l'indirizzo della variabile a.
* Dentro doubleof viene eseguita l'istruzione * x = (* x) * 2;, che assegna alla variabile puntata da x (a) il valore della stessa variabile puntata da x moltiplicato per 2.
* printf("%d", a); Stampa il valore ottenuto.
se si fosse passata alla funzione la semplice variabile, essa avrebbe restituito 2. questo e' un caso di "passaggio per valore". la funzione creerà una copia della variabile e al termine la cancellerà. NB la variabile passata dal main resterà INALTERATA.
RIASSUNTO:
1) passaggio PER VALORE:
2) passaggio PER RIFERIMENTO:

## Passare un array ad una funzione
### Primo metodo

Il nome di un array, generalmente, decade in un puntatore al suo primo elemento. Questo avviene sempre, tranne quando si usa il nome dell'array come argomento di sizeof, quando si usa l'operatore & ("indirizzo di"), o durante un'inizializzazione con una stringa letterale. Tale puntatore può essere passato ad una funzione. In questo modo si può passare un intero array alla funzione.
Per esempio:
restituisce:

### Secondo metodo

In questo metodo cambia solo la sintassi della funzione, ma il meccanismo è identico. Il vantaggio di questo meccanismo è che rende palese il fatto che ad una funzione verrà passato un array, ma se alla funzione fosse passato un puntatore non produrrebbe errori in fase di compilazione, ma si potrebbe comportare in modo insolito.

### Passaggio di matrici a funzione

Ricapitolando una matrice in C altro non è che un vettore di vettore quindi viene naturale la dichiarazione:
con questa sintassi si dichiara un vettore che contiene un numero pari a colonne di vettori che contengono un numero pari a righe di elementi di tipo tipo. Colonne e righe possono essere delle costanti intere o delle variabili intere (in tal caso si hanno array dinamici caratteristica del C99).
Per poter passare una matrice a una funzione è necessario un puntatore alla matrice che definisca il numero di colonne della matrice quindi il prototipo di una funzione che fa questo è :
se il numero di colonne è variabile si usa questa sintassi
Una volta definita la funzione per passarle la matrice basta passarle il nome della variabile matrice che decade in un puntatore alla matrice stessa.
Stesse considerazioni valgono per vettori n-dimensionali ossia del tipo:
dove gli indici da i1 a iN possono essere costanti o variabili (standard C99), per passare a una funzione il vettore è necessario definire un puntatore a v dove vengano definite le ultime n-1 dimensioni del vettore ossia il prototipo della funzione è:
se le ultime n-1 dimensioni sono variabili:
l'asterisco va solo dove la dimensione è variabile.
Tornando al caso delle matrici segue un esempio commentato sull'uso delle matrici dinamiche e passaggio a funzione.

#### Esempio passaggio matrici
## Puntatori a funzioni

È possibile far puntare un puntatore ad una funzione, in modo che essa possa essere chiamata attraverso il puntatore. Anche le funzioni, come le variabili, hanno un indirizzo di memoria.
Il seguente esempio definisce, assegna e utilizza un puntatore a funzione:
Si noti che il tipo del puntatore "funz" è uguale al tipo dalla funzione "doubleof". Il tipo di una funzione è costituito dalla sequenza dei tipi dei parametri e dal tipo di ritorno. Quindi per assegnare un indirizzo di una funzione a un puntatore a funzione è necessario che la funzione e il puntatore abbiano lo stesso numero di parametri, che i parametri corrispondenti abbiano lo stesso tipo, e il tipo di ritorno sia lo stesso.
Da notare inoltre che in questo caso non è stato usato l'operatore di referenziazione & come negli esempi precedenti, infatti, i nomi delle funzioni sono già dei puntatori.

## Puntatori a puntatori

È possibile definire anche puntatori ad altri puntatori che potrebbero a loro volta puntare a puntatori ecc.
il risultato è: