Output funzioni

di il
6 risposte

Output funzioni

Salve a tutti: ho un problema forse banalissimo: è possibile avere come output di una funzione un vettore o una matrice?

Grazie

6 Risposte

  • Re: Output funzioni

    Scusa ma cosa intendi per 'output'' ?!?
  • Re: Output funzioni

    Chiedo scusa per l'imprecisione... intendevo il valore restituito da una funzione. Per esempio
    
    int min(int a, int b)
    {
    if (a<b)
    return a;
    else return b;
    }
    
    In questo caso l'"output" è il minore tra a e b.
  • Re: Output funzioni

    Spero di aver capito bene il tuo problema....

    se tu vuoi che un funzione restituisca un vettore o 1 matrice devi ragionare per puntatori ovvero quando tu vuoi restituire un vettore non puoi restituire l'intero vettore, ma bensì restituisci un puntatore alla prima cella del vettore (questa cosa vale anche per le matrici).
    (il nome del vettore è il puntatore alla prima cella del vettore).

    fatta questa piccola premessa ti faccio un esempio:
    #include<stdio.h>
    #include<stdlib.h>
    
    int *crea(int n);       /*la funzione crea restituisce il puntatore al vettore creato  */
    void stampa(int vet[],int n);
    
    int main(){
        int n;
        int *vettore;
        printf("inserisci lunghezza vettore:");
        scanf("%d",&n);
        vettore=crea(n);
        printf("stampa:\n");
        stampa(vett,n);
        system("pause");
        return 0;
    }
    
    int* crea(int n){
         int i;
         int * vett;
         vett=(int *)malloc(sizeof(int)*n); /*alloco il vettore di interi lungo n*/
         if(vett==NULL){
                       printf("errore allocazione");
                       return 0;
                       }
    
         for(i=0;i<n;i++){
                          printf("inserisic  vett[%d]:\n",i);
                          scanf("%d",&vett[i]);
                          }
         return vett; /*ritorno il puntatore al main*/
         }
    
    void stampa(int *vet,int n){
    int i;
    for(i=0;i<n;i++){
                     printf("%d\n",vet[i]);
                     }
    }
    
    se non è chiaro dimmi.......
  • Re: Output funzioni

    Grazie mille, il problema è proprio quello. Avevo provato ad usare i puntatori, ma trovavo un problema nell'assegnare la matrice che volevo in uscita:

    Codice: Seleziona tutto
    int *mat()
    {
    int *a[2][3]={ {1,2,3},
    {2,4,5},
    }b=& a[0][0];
    return a;
    }



    questo codice dà errore nella riga di assegnazione della variabile a. Ho aggirato l'ostacolo definendo la matrice a e un puntatore b alla matrice:

    int *mat()
    {
    int *b,a[2][3]={ {1,2,3},
    {2,4,5},
    };
    b=& a[0][0];
    return b;
    }

    ...e così sembrerebbe corretto. Tuttavia, su un libro di testo ho trovato scritto che restituire un puntatore di una variabile definita localmente è un grave errore di compilazione, in quanto lo stack riservato alla funzione viene rilasciato e l'indirizzo di memoria restituito potrebbe subire modifiche inaspettate. L'unica soluzione mi sembra quindi di definire fuori dalla funzione la matrice, passarla alla funzione attraverso un puntatore e lì modificarla, restituendo il puntatore in uscita. La scociatura di questo sistema è che nella funzione (a quanto ne so) bisogna modificare elemento per elemento e se ho una matrice grande devo scrivere una marea di righe solo per l'assegnazione di ogni elemento della matrice. Mi sembra una cosa assurda a farsi.
    ad esempio (tralascia la banalità dell'esempio):

    #include<stdio>
    int *matrice(int m)
    {
    (&m)[0][0]=1;
    (&m)[0][1]=2;
    (&m)[0][2]=3;
    (&m)[1][1]=4;
    (&m)[1][2]=5;
    return m;
    }

    int main()
    {
    int m[2][3], *b;
    b=matrice(&m[0][0]);
    }

    Questo mi sembra che sia un grosso limite, a meno che non ci sia un'altra soluzione...
    grazie
  • Re: Output funzioni

    Io di solito per gestire le matrici con i puntatori creo inizialmente un puntatore che punta ad un vettore di puntatori ogni cella del quale punta ad un altro vettore che corrisponde ad una riga della matrice...eccoti il codice per farti capire...
    #include<stdio.h>
    #include<stdlib.h>
    
    int** crea_matrice(int n);
    void stampa(int ** mat, int n);
    int main (){
        int n;
        int ** aus;
        printf("inserisci dimensione:\n"); /*uso matrice quadrate per fare prima*/    
        scanf("%d",&n);
        aus=crea_matrice(n);
        stampa(aus,n);
        system("pause");
        return 0;
    }
    
    int** crea_matrice(int n){
           int i,j;
           int **aus;
           aus=(int**)malloc(sizeof(int*)*n); /*alloco il puntatore al vettore di puntatori*/
           if(aus==NULL){
                         printf("errore allocazione aus (matrice)");
                         return 0;
                         }
           for(i=0;i<n;i++){
                            aus[i]=(int*)malloc(sizeof(int)*n);/*alloco i vari puntatori all'interno del vettore cioe le varie righe*/
                            if(aus[i]==NULL){
                                             printf("errore allocazione aus[%d]",i);
                                             return 0;
                                             }
                            }
           for(i=0;i<n;i++){
                            for(j=0;j<n;j++){
                                             printf("inserisci valore aus[%d][%d]",i,j);
                                             scanf("%d",&aus[i][j]);                                
                                             }
                            }
           return aus;
           }
    
    void stampa(int ** mat, int n){
         int i,j;
         for(i=0;i<n;i++){
                            printf("\n");
                            for(j=0;j<n;j++){
                                             printf("%d",mat[i][j]);                                         
                                             }
                            }
         }
    


    questo è il metodo che ho sempre visto per gestire matrici....

    ma a te queste matrici servono dinamiche o statiche..??
    perchè se ti servono statiche la cosa è molto semplice in quanto tutti gli array(vettori e matrici) vengono passati in automatico per riferimento -> vengono sempre restituiti.... basta usarle come variabili normali così:
    #include<stdio.h>
    #include<stdlib.h>
    
    #define MAX 30
    
    void stampa_matrice(int mat[MAX][MAX],int n);
    void crea_matrice(int mat[MAX][MAX],int n);
    
    int main(){
        int n,mat[MAX][MAX];
        printf("inserisci numero di righe/colonne:");
        scanf("%d",&n);
        if(n<0 || n>MAX)
               printf("n deve essere compreso tra 0 e MAX");
        crea_matrice(mat,n);
        stampa_matrice(mat,n);
        system("pause");
        return 0;
    }
    void crea_matrice(int mat[MAX][MAX],int n){
         int i,j;
         for(i=0;i<n;i++)
                         for(j=0;j<n;j++){
                                          printf("inserisci mat[%d][%d]",i,j);
                                          scanf("%d",&mat[i][j]);
                                          }
                                         
         }
    void stampa_matrice(int mat[MAX][MAX],int n){
         int i,j;
         for(i=0;i<n;i++){
                         printf("\n");
                         for(j=0;j<n;j++){
                                          printf("%d",mat[i][j]);
                                          }
                         }               
         }
    
    quest'ultima cosa funziona appunto perchè il nome della matrice è il puntatore ad essa...

    per il discorso dello stack ecc ecc mi disp ma non ho capito cosa intendevi.....
  • Re: Output funzioni

    Grazie per i suggerimenti. Il mio discorso sullo stack si riferisce a quando si crea un puntatore all'interno di una funzione e questo viene passato al di fuori. Nel tuo primo programma tu fai proprio questo e a quanto ne so non è molto corretto, anche se il compilatore non dà errori e il programma può funzionare ugualmente. Il problema è che quando "esci" dal campo di visibilità di una funzione la memoria allocata per la funzione stessa viene rilasciata dal programma e quindi utilizzabile per altri scopi. Quindi il puntatore aus (in uscita dalla funzione) fa riferimento ad un'area di memoria "libera" e che può aver subito modifiche.
    Il secondo programma è invece corretto, però ha l'inconveniente che devi fornire in input una grandezza che tu vuoi in uscita... devo solo cambiare un po' mentalità..lavorare con Matlab e Fortran mi avevano abituato a pensare alla funzione in modo diverso.
    Grazie mille
Devi accedere o registrarti per scrivere nel forum
6 risposte