Puntatori

di il
11 risposte

Puntatori

Salve, vorrei sapere la differenza tra questi due codici, entrambi stampano 3. Essendoci un puntatore nel main, per modificare il valore di a da una funzione esterna al main ci vorrebbe il doppio puntatore.. Però non capisco perché anche il primo codice sembra funzionare.

Main() {
Int a = 2;
Int *p = &a;
Funzione1(p);
Printf("%d", a) ;
Return 0;
}
Funzione1(int *p) {
*p = 3;
}
 
   
Main() {
Int a = 2;
Int *p = &a;
Funzione1(&p);
Printf("%d", a) ;
Return 0;
}
Funzione1(int **p) {
**p = 3;
}

11 Risposte

  • Re: Puntatori

    Monkey ha scritto:


    Essendoci un puntatore nel main, per modificare il valore di a da una funzione esterna al main ci vorrebbe il doppio puntatore.
    E' qui che ti sbagli, il puntatore doppio serve se vuoi modificare il valore di p!

    Magari questo mio vecchio post ti può essere utile:
    In C il passaggio degli argomenti ad una funzione avviene sempre per copia, ossia qualsiasi modifica ai parametri formali non avrà alcun effetto sui parametri attuali. L'unico modo quindi in cui una funzione f possa modificare una generica variabile n appartenente ad un ambito di visibilità (non globale) diverso da quello di f, è quello di accedere ad n attraverso il suo indirizzo di memoria (ossia &n). A questo punto risulta ovvio che, dovendo contenere &n, il tipo dell'argomento (chiamiamolo m) sarà un puntatore di un ordine superiore rispetto ad n.
    Per esempio:
    n = int ==> m = int*
    n = char ==> m = char*
    n = float* ==> m = float**
    n = double**** ==> m = double*****
  • Re: Puntatori

    Ma poi perché tutte quelle maiuscole ? main int return
  • Re: Puntatori

    Oregon, il codice l'ho scritto dal telefono quindi il correttore automatico mi ha inserito le maiuscole.
    Se il puntatore *p punta ad a, nella funzione Funzione1 per cambiare il valore di *p é necessario usare il doppio puntatore.. E quindi il secondo codice l ho capito.
    Il problema é il primo, dove non sto usando un puntatore di grado superiore nella funzione, eppure mi stampa comunque 3.

    //Ho aggiunto una printf nel codice
  • Re: Puntatori

    Monkey ha scritto:


    Il problema é il primo, dove non sto usando un puntatore di grado superiore nella funzione, eppure mi stampa comunque 3.
    p è un puntatore di un grado superiore rispetto ad a (che seguendo questa narrazione possiamo considerare di grado 0).
    In ogni caso per capire meglio quello che intendo dire, prova a lanciare il seguente codice.
    #include <stdio.h>
    
    void fun_1(int *p)
    {
        *p = 1;
        p = NULL;
    }
    
    void fun_2(int **p)
    {
        **p = 2;
        *p = NULL;
    }
    
    int main()
    {
    	int a = 5;
    	int *p = &a;
    	printf("a = %d\np = %x\n\n", a, p);
    	fun_1(p);
    	printf("a = %d\np = %x\n\n", a, p);
    	fun_2(&p);
    	printf("a = %d\np = %x\n\n", a, p);
    	return 0;
    }
    Se hai dubbi chiedi pure.
  • Re: Puntatori

    Ok, il tuo esempio l'ho capito.
    Quindi ora il dubbio che mi viene è questo: in quale caso pratico si usa il doppio puntatore (oltre ai vettori dinamici)?
    ad esempio mi ritrovo questo codice dove è stato utilizzato il doppio puntatore:
    
    main(){
    FILE *fp
    AprireFile(&fp)
    return 0;
    }
    void AprireFile(FILE **fp){
    *fp = fopen("file.txt","w");
    ...
    fclose(*fp);
    }
    
    perchè è stato necessario l'utilizzo del doppio puntatore?
  • Re: Puntatori

    In questo caso dovevi modificare il puntatore, non il valore puntato dal puntatore.

    Se devi modificare il valore del puntatore, ti serve un doppio puntatore.

    Se devi modificare il valore puntato dal puntatore, ti basta il puntatore.
  • Re: Puntatori

    Ok, penso di aver capito.
    quindi il codice seguente è giusto?
    
    main(){
    int *Vett;
    AllocazioneVettore(&Vett);
    ...
    free(Vett);
    return 0;
    }
    void AllocazioneVettore(int **Vett){
    *Vett = (int*) malloc (10 * sizeof(int));
    }
  • Re: Puntatori

    Sì, corretto. In questo caso il puntatore deve essere modificato quinti ti serve il puntatore doppio.
  • Re: Puntatori

    Ti faccio cmq notare che puntatori di ordine superiore al primo ti permettono di modificare altrettante variabili:
    #include <stdio.h>
    
    void fun(int *****p)
    {
        *****p = 5;
        ****p = NULL;
        ***p = NULL;
        **p = NULL;
        *p = NULL;
    }
    
    int main()
    {
    	int a = 3;
    	int *b = &a;
    	int **c = &b;
    	int ***d = &c;
    	int ****e = &d;
    	printf("a = %d\nb = %x\nc = %x\nd = %x\ne = %x\n\n", a, b, c, d, e);
    	fun(&e);
    	printf("a = %d\nb = %x\nc = %x\nd = %x\ne = %x\n\n", a, b, c, d, e);
    	return 0;
    }
  • Re: Puntatori

    Perché metti NULL ai vari indirizzi?
  • Re: Puntatori



    Magari sono io che non ci ho mai fatto caso, ma è la prima che noto questa cosa!
    Perché metti NULL ai vari indirizzi?
    Un modo come un altro per dimostrare di aver modificato i vari puntatori attraverso fun().
Devi accedere o registrarti per scrivere nel forum
11 risposte