un puntatore é una variabile che contiene l'indirizzo di memoria di un'altra variabile
una specie di link ad un'altra variabile.

utilizzo:
in pratica serve per poter agire su una variabile anche quando ci si trova al di fuori dalle funzione che l'ha dichiarata
ad esempio se si dichiara una variabile in main, per modificare il suo valore in una funzione esterna richiamata occorre passare il puntatore a questa funzione.

sintassi:
l'uso del * è differente tra dichiarazione e uso poi del puntatore

  • dichiarazione *

  • tipo *nome_puntatore;

    array di puntatori:
    tipo *nome_puntatore[...];

  • uso del puntatore

  • assegnazione dell'indirizzo di memoria &
    nome_puntatore = &variabile

    esempio:
    int main (void)

    {int *a, b; dichiarazione puntatore e variabile
    b = 10;
    a = &b;} assegnazione puntatore l'indirizzo di memoria della variabile b

    esempio:
    int main (void)

    {int *a, *c, b;
    b = 10;
    a = &b; assegnazione puntatore
    c = a;} il puntatore c = puntatore a
    puntatore a e puntatore c puntano entrambi alla stessa variabile b dato che puntano sullo stesso indrizzo di memoria


    assegnazione di una stringa
    si tratta di una forzatura, dopo la dichiarazione inizializzo la variabile (di cui ho creato il puntatore) immettendo il testo
    char *pmessage
    pmessage = "ciao mondo"

    è come per gli array/vettori quando si inizializza la stringa direttamente:
    char messaggio[]="ciao mondo"

    c'è una notevole differenza tra i due sistemi:
    il primo sarà una variabile, cioè sarà possibile modificare il valore di *pmessage
    il secondo è una costante, messaggio[] non potrà essere modificato


    accesso al valore variabile
    per accedere tramite puntatore al valore della variabile di usa *
    *nome_puntatore
    * praticamente converte il puntatore nel valore della variabile puntata, permettendo quindi la visualizzazione e la modifica del valore

    esempio:
    int main (void)
    {int *a, b = 10;
    a = &b;
    printf("La variabile b, puntata da a, vale %d", *a);}


    infatti usando il * si accede al valore della variabile, senza si accede all'indirizzo di memoria

    si potrebbe anche modificare il valore della variabile:
    *a = *a + 10
    modifico il valore della variabile b aggiungendo 10, *a é in pratica la variabile b senza il puntatore


    accesso all'indirizzo memoria
    per accedere all'indirizzo di memoria del puntatore di usa il nome del puntatore senza *
    nome_puntatore

    esempio: controllo se 2 puntatori puntano alle stessa variabile
    if (p1 == p2) printf("p1 e p2 puntano allo stesso indirizzo di memoria.");
    else printf("p1 e p2 puntano a due differenti indirizzi di memoria.");

    esempio: visualizzazioni e uso del puntatore
    int main()
    {int alfa = 4;
    int beta = 7;
    int *pointer;

    pointer = &alfa;
    printf("alfa -> %d, beta -> %d, pointer -> %p\n", alfa, beta, pointer);
    alfa -> 4, beta -> 7, pointer -> 100

    beta = *pointer;
    printf("alfa -> %d, beta -> %d, pointer -> %p\n", alfa, beta, pointer);
    alfa -> 4, beta -> 4, pointer -> 100

    alfa = pointer;
    printf("alfa -> %d, beta -> %d, pointer -> %p\n", alfa, beta, pointer);
    alfa -> 100, beta -> 4, pointer -> 100

    *pointer = 5;
    printf("alfa -> %d, beta -> %d, pointer -> %p\n", alfa, beta, pointer);
    alfa -> 5, beta -> 4, pointer -> 100
    }

    esempio: funzione swap, gioco delle tre carte passando i puntatori.
    è necessario passare i puntatori altrimenti si passerebbero solo i valori delle variabili

    void main ()
    {....;
    swap (&a, &b); la main passa alla funzione swap gli indrizzi di memoria delle variabili
    ....;
    }

    void swap (int *px, int *py) dichiara i 2 puntatori
    {int temp;
    temp = *px;
    *px = *py;
    *py = temp;
    }