Puntatori

di Anonimizzato28727 il
11 risposte
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

  • 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*****
  • Ma poi perché tutte quelle maiuscole ? main int return
  • 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
  • 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.
  • 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?
  • 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.
  • 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));
    }
  • Sì, corretto. In questo caso il puntatore deve essere modificato quinti ti serve il puntatore doppio.
  • 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;
    }
  • Perché metti NULL ai vari indirizzi?


  • 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