Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 15
  1. #1
    Utente di HTML.it
    Registrato dal
    Oct 2003
    Messaggi
    1,258

    [c] restituire una struttura

    sui libri per quanto ho visto non se ne parla...ma provando ho visto che è possibile fare una funzione che restituisca una struttura.
    solo non riesco ad assegnarla...riporto il codice

    codice:
    #include <stdio.h>
    
    struct a{
     int val1;
     int val2;
    };
    
    int main()
    {
      struct a struttura2;
      struttura2 = funx01();
    
      getch();
      return 0;
    }
    
    struct a funx01(){
      struct a struttura;
      struttura.val1 = 12;
      return struttura;
    }

  2. #2
    ma quando lo compili non ti da nessun errore di incompatibilità di assegnamento?
    PyGTK GUI programming
    un impegno concreto: eliminare la k dalle tastiere italiane

  3. #3
    Utente di HTML.it
    Registrato dal
    Oct 2003
    Messaggi
    1,258
    si certo. Se però al posto di:

    struttura2 = funx01();

    richiamo semplicemente la funzione :

    funx01();

    mi da tanti warning ma me lo lascia eseguire. Quello a cui volevo arrivare io, era che cosa effettivamente restituisce la funzione e se si può utilizzare questa dichiarazione

  4. #4
    Utente di HTML.it
    Registrato dal
    Oct 2003
    Messaggi
    1,258
    aperta parentesi:

    in c posso far restituire alle funzioni solo puntatori e valori singoli, che voi sappiate?

  5. #5
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Innanzitutto a me non dà errori di assegnamento con:

    struttura2 = funx01();

    l'unica cosa da tenere presente è che la struc ritornata dalla funzione è ritornata 'per valore', nel senso che i valori valori della struct ritornata venono ricopiati in 'struttura2'; devi infatti sapere che in c tutte le variabili allocate staticamente (ovvero senza usare la malloc), vengono automaticamente distrutte all'uscita di una funzione, non è come in java in cui puoi costruire un ogetto in una funzione e ritornarlo, e ritorni proprio l'oggetto costruito nella funzione. In c per fare questo allochi dinamicamente memoria per la struct, e poi ritorni il puntatore alla struct, che non sarà distrutta all'uscita della funzione, proprio perche allocata dinamicamente. In effetti questo è ciò che fai anche in java, perche in realtà in java gli oggetti altro non sono che puntatori agli ogetti veri e propri.

    A dimostrazione di quanto detto, puoi usare il tuo programma, stampando l'indirizzo delle variabili usate nella funzione e nel main: puoi osservare che l'indirizzo della variabile struttura2 è sempre quello iniziale, anche dopo l'assegnamento:

    codice:
    #include <stdio.h>
    
    struct a{
     int val1;
     int val2;
    };
    
    struct a funx01(){
      struct a struttura;
      struttura.val1 = 12;
      printf("indirizzo della variabile nella funzione: %d\n", &struttura);
      return struttura;
    }
    
    int main()
    {
      struct a struttura2;
      printf("i ndirizzo della variabile nel main prima: %d\n", &struttura2);
      struttura2 = funx01();
      printf("indirizzo della variabile nel main dopo: %d\n", &struttura2);
      return 0;
    }

  6. #6
    Utente di HTML.it
    Registrato dal
    Oct 2003
    Messaggi
    1,258
    Ora neache a me dà errori, avevo dimenticato il prototipo della funzione.
    ho fatto questi 2 esperimenti che mi sembrano significativi.
    Creo una struttura interna a una funzione, nel primo caso con struct e nel secondo caso con malloc e poi la fnx ritorna un puntatore.
    Nel primo caso richiamando la funzione piu volte ottengo sempre lo stesso indirizzo. Con la malloc ogni volta restituisce indirizzi diversi.
    Ho anche provato a restituire array per valore, ma non ho avuto successo :bubu:

    codice1
    codice:
    #include <stdio.h>
    
    struct a{
     int val1;
     int val2;
    };
    
    struct a *funx01(){
      struct a struttura;
      struttura.val1 = 12;
      return &struttura;
    }
    
    
    int main()
    {
      printf("%d\n", funx01());
      printf("%d", funx01());
    
      getch();
      return 0;
    }
    codice2

    codice:
    #include <stdio.h>
    
    struct a{
     int val1;
     int val2;
    };
    
    struct a *funx01(){
      struct a* p = (struct a*) malloc(sizeof(struct a));
      p->val1 = 12;
    
      return p;
    }
    
    
    int main()
    {
      printf("%d\n", funx01());
      printf("%d", funx01());
    
      getch();
      return 0;
    }

  7. #7
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Il motivo dipende dal fatto che:

    - una variabile locale in una funzione viene distrutta all'uscita dalla funzione (e quindi la relativa memoria viene liberata)

    - una variabile allocata dinamicamente invece continua ad esistere finchè il programmatore non la libera esplicitamente.

    Quindi, chiamando più volte la tua funzione che restituisce direttamente la struct quello che succede è che:

    - il compilatore crea la struct in memoria nella prima zona in cui la può creare, diciamo a partire dall'indirizzo 100;

    - all'uscita libera nuovamente quella memoria;

    - alla chiamata successiva, visto che la memoria non è cambiata, ricrea di nuovo la variabile locale all'indirizzo 100.


    Nel secondo caso invece la memoria allocata non viene ovviamente liberata, e quindi la succesiva malloc restituisce un indirizzo diverso dal precedente; se invece prima di chiamare per la seconda volta la funx02() chiami la free() sul puntatore restituito dalla prima chiamata della funx02(), liberando la relativa memoria, potrai notare che il compilatore utilizza di nuovo lo stesso indirizzo di partenza per allocare la struttura:

    codice:
    int main()
    {
    	struct a* b = funx02();
    	printf("%d\n", b);
    	free(b);
    	b = funx02();
    	printf("%d\n", b);
            getch();
            return 0;
    }
    Infine non puoi dichiarare una funzione che restituisce un array, al massimo puoidichiarare una funzione che restituisce un puntatore e poi restituisce un array nel return, ma alla fine restituisci sempre il valore del puntatore e la memoria a cui esso punta sarà distrutta all'uscita della funzione.



  8. #8
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Una cosa che puoi provare che sembra contraddire quanto detto sopra è ancora:

    codice:
    int * a(){
    	 int e[3];
    	 e[0] = 0;
    	 e[1] = 1;
    	 e[2] = 2;
    	 return e;
    }
    
    int main()
    {
        printf("%d", a()[2]);
        return 0;
    }
    la funzione a restituisce un puntatore a int, e lo fa creando un array locale e e restituendolo (perche un array è un puntatore costatnte).

    Appena restituito il risultato la variablile locale ancora esiste e quindi puoi accedere a un elemento dell'array e stamparlo.


  9. #9
    Utente di HTML.it
    Registrato dal
    Oct 2003
    Messaggi
    1,258
    :metallica

  10. #10
    Originariamente inviato da anx721
    Una cosa che puoi provare che sembra contraddire quanto detto sopra è ancora:

    codice:
    int * a(){
    	 int e[3];
    	 e[0] = 0;
    	 e[1] = 1;
    	 e[2] = 2;
    	 return e;
    }
    
    int main()
    {
        printf("%d", a()[2]);
        return 0;
    }
    la funzione a restituisce un puntatore a int, e lo fa creando un array locale e e restituendolo (perche un array è un puntatore costatnte).

    Appena restituito il risultato la variablile locale ancora esiste e quindi puoi accedere a un elemento dell'array e stamparlo.


    perché ciò è possibile ?
    cioè... appena torna la funzione ancora i dati sono disponibili e si può accedere ad essi, ma già un'istruzione dopo tutto viene distrutto.
    Ke tutto viene distrutto OK, è normale (a meno che i dati non siano static), ma perché immediatamente dopo il ritorno è possibile utilizzare quei dati??


    grazie in anticipo!

    ciao!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.