Aiuto con i puntatori a funzione

di il
24 risposte

24 Risposte - Pagina 2

  • Re: Aiuto con i puntatori a funzione

    Alexv ha scritto:


    Se gli passi un cont nullo stiamo sempre lì, poi devi caricare il vettore prima di stamparlo.
    Hai 3 strade:
    1) Scansioni il vettore degli studenti due volte, una per trovare il numero di elementi da copiare (e quindi allocare newvet con la dimensione giusta) e un'altra per copiare gli elementi.
    2) Creare newvett direttamente della dimensione del primo.
    3) usare un vettore di appoggio (non so se sia effettivamente più veloce della precedente):
    
    void creaElenco(studente* vet, studente* newvet, int n, float &s, int &cont){
        int temp*;
        temp = new int[n];
        for(int i=0; i<n; i++){
            if(vet[i] -> reddito > s){
               temp[cont] = i;
                cont++;
             }
          }
         newvet = new studente[cont];
         for(int i=0; i<cont; i++) newvet[i] = vet[temp[i]];
         
         delete[] temp;
    }
    
    Oppure usi std::vector su cui alla fine farai un resize sull'effettivo numero di elementi che hai inserito (per risparmiare memoria).
    In goni caso questa funzione non funziona, stampa così:


    Cognome:
    Nome:
    Matricola: -2144444632
    Reddito: 1.4013e-45
    -----------------------
  • Re: Aiuto con i puntatori a funzione

    Se vuoi la l'array dinamico devi usare il <vector>
    Se allochi col new o con la malloc devi avere una dimensione massima e non la puoi oltrepassare.
    Funziona così anche se non ti piace. Il sistema operativo ha una RAM fisica da gestire, con dimensioni limitate, e non può fornire array sparsi a caso a tutti i programmi
  • Re: Aiuto con i puntatori a funzione

    Weierstrass ha scritto:


    Se vuoi la l'array dinamico devi usare il <vector>
    Se allochi col new o con la malloc devi avere una dimensione massima e non la puoi oltrepassare.
    Funziona così anche se non ti piace. Il sistema operativo ha una RAM fisica da gestire, con dimensioni limitate, e non può fornire array sparsi a caso a tutti i programmi
    Non non è questione che mi piaccia o meno, è che non riesco a sviluppare questa parte di programma con la new.
  • Re: Aiuto con i puntatori a funzione

    Giusto per precisare, la dimensione dell'array, anche se allocato dinamincamente con la new, poi non cambia in automatico anche se modifichi la variabile cont, che non rimane in alcun modo legata ad esso.
  • Re: Aiuto con i puntatori a funzione

    cslash89 ha scritto:


    In goni caso questa funzione non funziona, stampa così:

    Cognome:
    Nome:
    Matricola: -2144444632
    Reddito: 1.4013e-45
    -----------------------
    Hai ragione ho sbagliato anche io.
    Per allocare direttamente nella funzione creaElenco bisogna passare il puntatore a newvet (puntatore doppio), altrimenti viene modificata una copia di newvet. Così dovrebbe funzionare.
    
    class studente{
    	//...
        friend void creaElenco(studente* vet, studente** newvet, int n, float &s, int &cont);
    };
    //...
    void creaElenco(studente *vet, studente **newvet, int n, float &s, int &cont);
    
    
    
    void creaElenco(studente* vet, studente** newvet, int n, float &s, int &cont){
        int* temp;
        temp = new int[n];
        for(int i=0; i<n; i++){
            if(vet[i].reddito > s){
               temp[cont] = i;
                cont++;
             }
          }
         *newvet = new studente[cont];
         if(cont > 0 && newvet == nullptr){
            cout<<"Impossibile allocare memoria."<<endl;
            return -1;
           } 
         for(int i=0; i<cont; i++) (*newvet)[i] = vet[temp[i]];
         
         delete[] temp;
    }
    
    
    int main()
    {
    	//...
    	
    	cout<<"Gli studenti con il reddito maggiore alla soglia sono: "<<endl;
        	creaElenco(vet, &newvet, n, s, cont);
        	
            print1(newvet, cont);
            
            //...
    }
    
  • Re: Aiuto con i puntatori a funzione

    Ok adesso funzione... non pensavo che creare un nuovo array con new fosse così rognoso

    Ma la cosa curiosa che non mi so spiegare è che se prendiamo in considerazione il primo codice da me inviato ovvero:
    
    int n=0, cont=0;
        float s=0.0;
        studente* vet=nullptr;
        studente* newvet=nullptr;
        
        cout<<"Inserire il numero di studenti da catalogare: ";
        cin>>n;
        vet=new studente[n];
        if(vet==nullptr){
            cout<<"Impossibile allocare memoria."<<endl;
            return -1;
        }
        procedura(input, vet, n);
        procedura(print, vet, n);
        cout<<"Il reddito maggiore e': "<<operazione(maxredd, vet, n)<<endl;
        cout<<"Il reddito minore e': "<<operazione(minredd, vet, n)<<endl;
        cout<<"--------------------------"<<endl;
        cout<<"Inseire il reddito soglia: ";
        cin>>s;
        
        newvet=new studente[cont];
        
        if(newvet==nullptr){
            cout<<"Impossibile allocare memoria."<<endl;
            return -1;
        }
        cout<<"Gli studenti con il reddito maggiore alla soglia sono: "<<endl;
        creaElenco(vet, newvet, n, s, cont);
        print1(newvet, cont);
        
        delete []vet;
        delete []newvet;
        cout<<"fine programma."<<endl;
        return 0;
    
    Codice: Seleziona tutto
    
    class studente{
    private:
        char cognome[20];
        char nome[20];
        int matricola;
        float reddito;
    public:
        studente();
        void assegna(char*, char*, int, float);
        void stampa();
        friend float maxredd(studente *vet, int);
        friend float minredd(studente *vet, int);
        friend float operazione(float(*pfun)(studente *vet, int), studente *vet, int n);
        friend void creaElenco(studente* vet, studente* newvet, int n, float &s, int &cont);
    };
    void input(studente *vet, int);
    void print(studente*, int);
    void procedura(void(*p)(studente *vet, int), studente *vet, int n);
    float maxredd(studente *vet, int);
    float minredd(studente *vet, int);
    void creaElenco(studente *vet, studente *newvet, int n, float &s, int &cont);
    void print1(studente *newvet, int cont);
    
    Codice: Seleziona tutto
    
    
    
    studente::studente(){
        strcpy(cognome, " ");
        strcpy(nome, " ");
        matricola=0;
        reddito=0.0;
    }
    
    void studente::assegna(char *co, char* no, int mat, float red){
        strcpy(cognome, co);
        strcpy(nome, no);
        matricola=mat;
        reddito=red;
    }
    
    void studente::stampa(){
        cout<<"Cognome: "<<cognome<<endl;
        cout<<"Nome: "<<nome<<endl;
        cout<<"Matricola: "<<matricola<<endl;
        cout<<"Reddito: "<<reddito<<endl;
        cout<<"-----------------------"<<endl;
    }
    
    
    
    void input(studente* vet, int n){
        for(int i=0; i<n; i++){
        char cognome[20], nome [20];
        int matricola;
        float reddito;
        cin.ignore();
        cout<<"Inserire il cognome dello studente: ";
        cin.getline(cognome, 20);
        cout<<"Inserire il nome: ";
        cin.getline(nome, 20);
        cout<<"Inserire la matricola: ";
        cin>>matricola;
        cout<<"Inserire il reddito: ";
        cin>>reddito;
        (vet+i)->assegna(cognome, nome, matricola, reddito);
        cout<<"---------------------------------------"<<endl;
         }
    }
    
    void print(studente* vet, int n){
        for(int i=0; i<n; i++){
            (vet+i)->stampa();
        }
    }
    
    float maxredd(studente *vet, int n){
        float max=(vet+0)->reddito;
        for(int i=0; i<n; i++){
            if((vet+i)->reddito>max){
                max=(vet+i)->reddito;
            }
        }
        return max;
    }
    
    float minredd(studente *vet, int n){
        float min=(vet+0)->reddito;
        for(int i=0; i<n; i++){
            if((vet+i)->reddito<=min){
                min=(vet+i)->reddito;
            }
        }
        return min;
    }
    
    float operazione(float(*pfun)(studente *vet, int), studente *vet, int n){
        float z=0.0;
        z=(*pfun)(vet, n);
        
        return z;
    }
    
    void procedura(void(*p)(studente *vet, int), studente *vet, int n){
        (*p)(vet, n);
    }
    
    void creaElenco(studente* vet, studente* newvet, int n, float &s, int &cont){
        for(int i=0; i<n; i++){
            if((vet+i)->reddito>s){
               *(newvet+cont)=*(vet+i);
                cont++;
             }
        }
    }
    
    void print1(studente* newvet, int c){
        for(int i=0; i<c; i++){
            (newvet+i)->stampa();
        }
    }
    
    
    
    se lo eseguo sul pc portatile (con ubuntu) funziona tutto liscio come l'olio.... Ora sbagliato per sbagliato perche il pc fisso (che è anche più recente e potente del portatile) crasha, invece il portatili esegue tutto alla perfezione??

    Se avessi sviluppato il programma direttamente solo nel portatile, non mi sarei mai accorto degli errori.
  • Re: Aiuto con i puntatori a funzione

    Quando scrivi fuori dal vettore il comportamento è indefinito: può crashare, può non crashare, può non crashare ma dare risultati sballati, dipende da quale area di memoria vai a toccare.
    Un'ultima cosa, adesso che ci penso: puoi togliere tutti gli
    if (puntatore == nullptr) //visualizza errore ed esci
    dopo le new perché non servono a niente. In C++ post 2011 se la new va male genera un'eccezione std::bad_alloc, che se non gestita fa chiudere in automatico il programma.
  • Re: Aiuto con i puntatori a funzione

    Alexv ha scritto:


    Quando scrivi fuori dal vettore, il comportamento è indefinito: può crashare, può non crashare, può non crashare ma dare risultati sballati, dipende da quale area di memoria vai a toccare.
    Un'ultima cosa, adesso che ci penso: puoi togliere tutti gli
    if (puntatore == nullptr) //visualizza errore ed esci
    dopo le new perché non servono a niente. In C++ post 2011 se la new va male genera un'eccezione [url]std::bad_alloc[/url], che se non gestita fa chiudere in automatico il programma.
    Grazie per il consiglio lo terrò a mente.

    PS ma succede a tutti i programmatori (sia giovani come me, che più esperti) che più il problema diventa difficile e più ci si gasa in cerca di una soluzione?? Io personlamente mi rivolgo al forum solo quando esaurisco tutte le idee (poi altre vengono comunque dopo). Lo trovo un "esaurmento" piacevole, non smetterei mai a volte.
  • Re: Aiuto con i puntatori a funzione

    Beh la foga di farlo funzionare serve, altrimenti ci si scoraggia e si lascia. A volte però è meglio dormirci su e riprendere a mente fresca, se hai tempo.

    Nel tuo caso il problema era di conoscenza del linguaggio, quindi non ne saresti uscito.
    In generale (parlo però da studente universitario) avere un programma scomposto in piccoli pezzi e testarlo bene ogni volta che si aggiunge una funzionalità, invece di scriverlo tutto di un fiato, riduce gli errori ed è più facile trovarli quando saltano fuori. Soprattutto quelli di run time che non sono segnalati dal compilatore, che sono i più rognosi.
  • Re: Aiuto con i puntatori a funzione

    Alexv ha scritto:


    Beh la foga di farlo funzionare serve, altrimenti ci si scoraggia e si lascia. A volte però è meglio dormirci su e riprendere a mente fresca, se hai tempo.

    Nel tuo caso il problema era di conoscenza del linguaggio, quindi non ne saresti uscito.
    In generale (parlo però da studente universitario) avere un programma scomposto in piccoli pezzi e testarlo bene ogni volta che si aggiunge una funzionalità, invece di scriverlo tutto di un fiato, riduce gli errori ed è più facile trovarli quando saltano fuori. Soprattutto quelli di run time che non sono segnalati dal compilatore, che sono i più rognosi.
    Hai assulutamente ragione, ma io parto dal fatto che sto imparando ora la OOP, e studiando da solo il tutto, si viene a creare il fatto che magari ho in testa ciò che devo fare, ma errori legati alla teoria o comunque alla non ancora padronanza e perfezione del linguaggio, mi portano a sbagliare. Anche gli esercizi che faccio alla fine sono sempre gli stessi, con la differenza che li modifico a seconda di ciò che studiando/imparando, e li rifaccio tante volte finche ho assimilato bene concetto.
Devi accedere o registrarti per scrivere nel forum
24 risposte