Visualizzazione dei risultati da 1 a 10 su 15

Hybrid View

  1. #1
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,589
    Nessun problema. Nota che io ti ho offerto 2 coppie di funzioni in ogni caso: una usa malloc e free, l'altra new e delete.
    Se c'è qualcosa che non capisci chiedi pure (:
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

  2. #2
    Quote Originariamente inviata da Scara95 Visualizza il messaggio
    Nessun problema. Nota che io ti ho offerto 2 coppie di funzioni in ogni caso: una usa malloc e free, l'altra new e delete.
    Se c'è qualcosa che non capisci chiedi pure (:
    Ciao scara! Il tuo programma funziona correttamente, ho preferito utilizzare le funzioni con new int e delete che, a mio parere, sono più semplici da ricordare e da scrivere. Ho continuato il programma, ora è a buon punto, ho aggiunto una funzione che mi calcola l'indice minimo nelle colonne, te lo faccio vedere



    codice:
    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    
    
    using namespace std;
    
    
    int **readMat(int**&m, size_t& size) 
    {
    	ifstream in("mat.txt");
        in >> size;
        m = new int *[size];
        for(int i = 0; i < size; ++i)
            m[i] = new int[size];
        for(int i = 0; i < size; ++i)
            for(int j = 0; j < size; ++j)
                in >> m[i][j];
        return m;
    }
    
    
    void freeMat(int **&m, size_t size) {
        for(int i = 0; i < size; ++i)
            delete[] m[i];
        delete[] m;
    }
    
    
    int   calc_ind_min(int **&m,int size,int r)
    {
    	int min=m[r][0];
    	int i,indmin=0;
    	for (i=0;i<size;i++)
    	{
          if (m[r][i]<min)
          {
          	min=m[r][i];
          	indmin=i;
          }
    	}
    	cout<<indmin;
    	return indmin;
    }
    
    
    int main(void) {
        size_t size;
        int **m;
        readMat(m, size);
        for(int i = 0; i < size; ++i) {
            for(int j = 0; j < size; ++j)
                cout << m[i][j] << '\t';
            cout << endl;
        }
        int r;
        for(r=0;r<size;r++)
    	{
    		calc_ind_min(m,size,r);
        }
        freeMat(m, size);
        return 0;
    }
    Però ti vorrei chiedere alcune cose. Nel programma mi è quasi tutto chiaro, devo solo capire, qual'è precisamente la funzione di new int? La funzione di delete è quella di liberare la memoria altrimenti si appesantisce il sistema, ma new int, prima di size nella prima funzione, a che serve precisamente?
    E poi, size_t che tipo è? Ha la stessa funzione di unsigned int? Grazie per il tuo tempo!!

  3. #3
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,589
    Un consiglio, mai eseguire istruzioni di input output all'interno di una funzione che non dovrebbe prevedere IO, come quella che hai scritto tu.
    Quindi parto con qualche correzione
    codice:
    void freeMat(int **&m, size_t size) {
        for(int i = 0; i < size; ++i)
            delete[] m[i];
        delete[] m;
        //correzione sul mio stesso codice :D anche se non strettamente necessaria
        m = NULL; //in caso di doppia deallocazione non lancia errore
    }
    
    
    int calc_ind_min(int ** m,int size,int r) //non è necessaria &, ti lascio approfondire
    {
        int min=m[r][0];
        int i,indmin=0;
        for (i=0;i<size;i++)
        {
          if (m[r][i]<min)
          {
            min=m[r][i];
            indmin=i;
          }
        }
        //meglio evitare IO all'interno di funzione non create SPECIFICATAMENTE per IO
        return indmin;
    }
    
    
    //...
        for(r=0;r<size;r++)
        {
            cout << calc_ind_min(m,size,r);
        }
    //...
    Passiamo ora a rispondere alle tue domande.
    size_t non è altro che un intero positivo che rappresenta le grandezze in bytes, è definito proprio come typedef unsigned int size_t;.
    Analizziamo la funzione per l'allocazione della matrice. In particolare, assumendo size l'ordine della matrice quadrata e m una variabile int **,
    codice:
        m = new int *[size];
        for(int i = 0; i < size; ++i)
            m[i] = new int[size];
    Per l'allocazione della matrice non la si considera come tale, ma come array di array: ad esempio la matrice
    codice:
    m
    1 2 3
    4 5 6
    7 8 9
    è rappresentata dome un array
    codice:
    m = A B C
    dove A B C sono
    codice:
    A = 1 2 3
    B = 4 5 6
    C = 7 8 9
    Perciò l'allocazione di divide in due parti: una prima parte che alloca un array di puntatori ad interi
    codice:
        m = new int *[size];
    e una parte dove ad ogni puntatore è assegnato un array di interi
    codice:
        for(int i = 0; i < size; ++i)
            m[i] = new int[size];
    La deallocazione avviene all'inverso, prima si deallocano i blocchi interni, poi quelli esterni. Qui per la precisione si parla di jagged arrays. Puoi cercare su internet.
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

  4. #4
    Aggiungo solo una coppia di brevi esempi (ormai una FAQ) sull'allocazione dinamica "da manuale" di array multidimensionali.

    Esempio di base, volutamente incompleto:
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
        size_t righe, colonne, i, j;
        int **matrice;
    
        printf(" Righe........: ");
        scanf("%d", &righe);
        printf(" Colonne......: ");
        scanf("%d", &colonne);
        puts("");
    
        matrice = (int **)malloc(righe * sizeof(int *));
        if (NULL == matrice)
        {
            fputs("Errore di allocazione base array !\n", stderr);
            return 1;
        }
        
        for (i = 0; i < righe; ++i)
        {
            int *p;
            p = (int *)malloc(colonne * sizeof(int));
            if (NULL != p)
            {
                matrice[i] = p;
            }
            else
            {
                fprintf(stderr, "Errore di allocazione alla riga %d!\n", i);
                while (i--)
                {
                    free(matrice[i]);
                }
                free(matrice);
                return 2;
            }
        }
    
        for(i = 0; i < righe; ++i)
        {
            for(j = 0; j < colonne; ++j)
            {
                printf("Inserisci elemento riga %d e colonna %d: ", i, j);
                scanf("%d", &matrice[i][j]);
                puts("");
            }
        }
    
        for(i = 0; i < righe; ++i)
        {
            printf("matrice[%d] = {%d", i, matrice[i][0]);
            for(j = 1; j < colonne; ++j)
            {
                printf(", %d", matrice[i][j]);
            }
            puts("}");
            free(matrice[i]);
        }
        free(matrice);
    
        return 0;
    }
    Esempio di allocazione indiretta, entro una funzione accessoria.
    codice:
    /************************************************************************/
    /** Scopo del programma:...............................................**/
    /************************************************************************/
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    
    #define ASIZE (8)
    
    typedef enum {FALSE, TRUE} Bool_t;
    
    Bool_t matrix_alloc(int ***m, const size_t row, const size_t col)
    {
        size_t i;
    
        assert(row > 0);
        assert(col > 0);
    
        /*
        ** PRIMO STEP: allocazione array di base
        */
        *m = (int **)malloc(row * sizeof(int *));
        if (NULL == *m)
        {
            fputs("Errore di allocazione base array !\n", stderr);
            return (FALSE);
        }
    
        for (i = 0; i < row; ++i)
        {
            int *p;
            /*
            ** SECONDO STEP: allocazione di ogni singolo array-riga
            */
            p = (int *)malloc(col *sizeof(int));
            if (NULL != p)
            {
                /*
                ** TERZO e ULTIMO STEP: collegamento riga ad array base
                */
                (*m)[i] = p;
            }
            else
            {
                fprintf(stderr, "Errore di allocazione alla riga %d!\n", i);
                while (i--)
                {
                    free((*m)[i]);
                    fprintf(stderr, "%d ", i);
                }
                free(*m);
                return (FALSE);
            }
        }
        return (TRUE);
    }
    
    int main(void)
    {
        int **array;
        size_t righe, colonne;
        size_t i, j;
        Bool_t status;
    
        righe   = ASIZE;
        colonne = ASIZE;
    
        printf("Allocazione dinamica di un array "
               "bidimensionale %d x %d\n",
               righe, colonne);
    
        status = matrix_alloc(&array, righe, colonne);
    
        if(status)
        {
            printf("** Allocazione effettuata. "
                   "Inizializzazione di %d celle in corso...\n",
                   righe * colonne);
    
            for (i = 0; i < righe; ++i)
            {
                for (j = 0; j < colonne; ++j)
                {
                    array[ i ][ j ] = i * 10 + j;
                }
            }
    
            puts("** Contenuto dell'array:");
            for (i = 0; i < righe; ++i)
            {
                for (j = 0; j < colonne; ++j)
                {
                    printf( "array[%d][%d] = %02d\n", i, j, array[ i ][ j ]);
                }
                free(array[i]);
            }
            free(array);
        }
    
        return (EXIT_SUCCESS);
    }/* EOF: alloc_array.c */
    Infine, un esempio ancora più avanzato che mostra una panoramica di metodi di allocazione dinamica a vari livelli di indirezione.

    Aggiungo solo un paio di note che forse potranno tornare utili all'OP solo in una fase più avanzata dello studio.

    1) L'uso di jagged arrays va imparato (per scopi scolastici) e poi dimenticato. Nel real world l'allocazione in un blocco unico impera nel 99% del codice, per motivi che spaziano dalle prestazioni, alla robustezza, alla manutenibilità del codice: i rari casi nei quali si ricorre ad un array di arrays come nella manualistica e nella didattica sono legati, ad esempio, alla rappresentazione di matrici sparse e/o di array di liste, alberi ed altri ADT che possano beneficiare della potenzialità di una simile struttura, ossia la capacità di referenziare con un solo array di base altri array di lunghezze potenzialmente molto diverse tra loro.

    2) In linguaggio C++ è comunque del tutto sconsigliato l'uso degli array C-alike. Esistono apposite classi come vector, valarray, list, string e altre. Si veda questo famoso thread per una spiegazione in merito.
    Ultima modifica di M.A.W. 1968; 11-06-2014 a 13:42
    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

  5. #5
    Ringrazio entrambi! Quindi Scara se ho capito bene non sempre devo dichiarare parametri di I/O per le funzioni? Ma se non lo faccio non rischio che il compilatore mi dia errori?
    Mi è molto più chiaro lo scopo di size_t, e ho compreso concettualmente come funziona l'allocazione di array di array! Inoltre poco fa ho aggiunto una nuova funzione al mio programma, completandolo. Ecco qui:

    codice:
    #include <iostream>#include <fstream>
    #include <cstdlib>
    
    
    
    
    using namespace std;
    
    
    // lettura matrice da file + allocazione
    int **readMat(int**&m, size_t& size) 
    {
        ifstream in("mat.txt");
        in >> size;
        m = new int *[size];
        for(int i = 0; i < size; ++i)
            m[i] = new int[size];
        for(int i = 0; i < size; ++i)
            for(int j = 0; j < size; ++j)
                in >> m[i][j];
        return m;
    }
    
    
    // Liberazione memoria
    void freeMat(int **&m, size_t size) {
        for(int i = 0; i < size; ++i)
            delete[] m[i];
        delete[] m;
    }
    
    
    // Calcolo del minimo delle righe
    int   calc_ind_min(int **m,int size,int r)
    {
        int min=m[r][0];
        int i,indmin=0;
        for (i=0;i<size;i++)
        {
          if (m[r][i]<min)
          {
            min=m[r][i];
            indmin=i;
          }
        }
        
        return indmin;
    }
    // Calcolo del massimo delle colonne + calcolo e stampa del punto di sella
    
    int trova_punto_sella(int**m,int size, int t)
    {
          int sella;
          int posc;
          posc = calc_ind_min(m,size,t);
          int maxcol=m[t][posc];
          for(int i=0;i<size;i++)
          {
                  if(maxcol<m[i][posc])
                     maxcol=m[i][posc];
          }
          if(maxcol==m[t][posc])
          {
                  sella=maxcol;
                  cout<<sella<<" Punto di sella in posizione "<<t<<" "<<posc<<endl;
                  return sella;
           }
           else
           return -1;
     
    }
    
    
    int main(void) {
        size_t size;
        int **m;
        readMat(m, size);
       // stampa a video della matrice allocata
        for(int i = 0; i < size; ++i) {
            for(int j = 0; j < size; ++j)
                cout << m[i][j] << '\t';
            cout << endl;
        }
        
        int r;
        for(r=0;r<size;r++)
        {
            calc_ind_min(m,size,r);
        }
        cout << endl;
        cout << endl;
        
        int t;
        for(t=0;t<size;t++)
        
    { trova_punto_sella(m,size,t);
    }
        freeMat(m, size);
        return 0;
    }
    Ultima modifica di DaemonDestroyer; 11-06-2014 a 16:00

  6. #6
    Ti ringrazio MAW per i materiali da te fornitomi, poiché sono diciamo nella fase iniziale dello studio del C++, mi saranno molto utili. Mi permetto di dire, che spesso confronti come questo sui forum (almeno nel mio caso) risultano molto più utili alla comprensione e allo studio dei linguaggi informatici che non leggere dai libri universitari, spesso non molto chiari...

  7. #7
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,589
    Quote Originariamente inviata da DaemonDestroyer Visualizza il messaggio
    Quindi Scara se ho capito bene non sempre devo dichiarare parametri di I/O per le funzioni?
    No hai mal interpretato: devi evitare operazioni di IO all'interno delle funzioni se non create appositamente per quello scopo, cioè devi evitare cin>> cout<< ...
    Il principio è: se non è necessario alla funzione non includerlo nella funzione, ma nel main.
    Concordo con M.A.W. che è molto migliore l'allocazione di un blocco unico.
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

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 © 2026 vBulletin Solutions, Inc. All rights reserved.