Passaggio matrice dinamica a funzione C++

di il
10 risposte

Passaggio matrice dinamica a funzione C++

Ho un problema riguardo una cosa che non riesco a capire e in realtà non so neanche se si possa fare...
In pratica, se ho ben capito quando si crea una funzione/procedura che lavora su una matrice che gli deve essere passata non posso dichiararla come :
void miafunzione(int mat[][]), ma devo necessariamente rendere noto alla funzione almeno il numero delle colonne, ossia (int mat [][4]) per fare un esempio. Non riesco allora a capire come si procede se devo allocare dinamicamente la matrice che poi passerò alla funzione e quindi non conosco a priori il numero di colonne su cui dovrà lavorare la mia funzione... in questi casi non si può fare oppure (come molto probabilmente sarà) mi sfugge qualcosa?
grazie in anticipo per eventuali risposte

10 Risposte

  • Re: Passaggio matrice dinamica a funzione C++

    Se lavori con i puntatori, a mio avviso, ti semplifichi la vita (anche se apparentemente non sembrerebbe) e invece di passare qualcosa del tipo int mat[][4] passi semplicemente int *pmat e il numero di righe e colonne
  • Re: Passaggio matrice dinamica a funzione C++

    candaluar ha scritto:


    Se lavori con i puntatori, a mio avviso, ti semplifichi la vita (anche se apparentemente non sembrerebbe) e invece di passare qualcosa del tipo int mat[][4] passi semplicemente int *pmat e il numero di righe e colonne
    stavo iniziando a pensare anche io una cosa del genere, ma se dovessi lavorare con i puntatori allora non dovrei passare il puntatore a puntatore? ad esempio int** mat ..... è questo che non riesco a capire ... potresti spiegarmelo per favore?
  • Re: Passaggio matrice dinamica a funzione C++

    Dipende da come hai allocato: se hai allocato un'unica area di dimensione N x M ti basta avere il puntatore a tale area e ci "navighi" dentro con il puntatore, conoscendo N ed M. Questa di solito è la soluzione che adotto io.
    Oppure fai come qui dove è ottimamente spiegato da M.A.W. 1968
  • Re: Passaggio matrice dinamica a funzione C++

    Penso che ti basterebbe scrivere qualcosa del genere:
    
    	int** matrix;
    
    	int lenx = 10;
    	int leny = 10;
    
    	//Crea un array di puntatori ad int di dimensione lenx
    	matrix = new int*[lenx];
    
    	//Inizializza matrice puntatori
    	for (int i = 0; i < lenx; ++i)
    		*(matrix + i) = new int[leny];
    
    	//Inizializza ogni cella
    	int tot =0;
        	for (int i = 0; i < lenx; ++i)
          	for (int j = 0; j < leny; ++j){
            	++tot;
             	matrix[i][j] = tot;
          }
    
    
    	//legge matrice
    	printMatrix(matrix, lenx,leny);
    
    	return 0;
    
    Definendo una funzione come questa, (nell'esempio si legge i valori, poi nella tua puoi farci quello che ti occorre):
    
    void printMatrix(int** pMatrix,int lenx,int leny){
    	
       for (int i = 0; i < lenx; ++i)
          for (int j = 0; j < leny; ++j)
             std::cout << pMatrix[i][j] << std::endl;
    
    }
    
    
  • Re: Passaggio matrice dinamica a funzione C++

    candaluar ha scritto:


    Dipende da come hai allocato: se hai allocato un'unica area di dimensione N x M ti basta avere il puntatore a tale area e ci "navighi" dentro con il puntatore, conoscendo N ed M. Questa di solito è la soluzione che adotto io.
    Oppure fai come qui dove è ottimamente spiegato da M.A.W. 1968
    Io invece solitamente alloco nel seguente modo :
    int** MAT;
    MAT= new int* [numerorighe];
    for(int i=0;i<numerorighe;i++)
    {
    MAT = new int[numerocolonne];
    }

    è corretto? se si come si procede in questo caso? nel link che mi hai mandato non sono riuscito a capire perchè è scritto in C ed il C non lo conosco per niente...

    EDIT: non avevo letto il messaggio di CarDeFusco (o meglio, ho scritto la mia risposta in contemporanea alla sua a quanto pare), quindi da quanto ho capito se alloco nel modo in cui ho scritto sopra poi mi basta passare alla funzione MAT nel mio caso?
  • Re: Passaggio matrice dinamica a funzione C++

    I numerosi problemi e conflitti di standard inerenti il passaggio di un array a subscritti multipli come parametro sono ampiamente spiegati in questo famoso thread. Si tratta di un tema spinoso e ben noto.

    In breve: programmando in C++, si usano le classi apposite come vector, string e valarray. Gli array C-style sono deprecati da Stroustrup in persona e non andrebbero semplicemente usati nel real world.

    Nella prassi, programmando in C, si usa comunque una singola allocazione e si gioca poi con la banale aritmetica degli indici, per motivi prestazionali e di sintesi del codice, richiamati anche più oltre nel noto thread sopra linkato.
    La soluzione meramente scolastica, well behaved, basata su allocazioni multiple è invece quella presentata per esteso (incluso un esplicito supporto per la programmazione difensiva e il fail test) nel thread già referenziato da Candaluar. Il tutto vale comunque per il C: per C++ vale la parola del creatore Stroustrup, ripresa in decine di guide di stile.
  • Re: Passaggio matrice dinamica a funzione C++

    leonidus ha scritto:


    candaluar ha scritto:


    Dipende da come hai allocato: se hai allocato un'unica area di dimensione N x M ti basta avere il puntatore a tale area e ci "navighi" dentro con il puntatore, conoscendo N ed M. Questa di solito è la soluzione che adotto io.
    Oppure fai come qui dove è ottimamente spiegato da M.A.W. 1968
    Io invece solitamente alloco nel seguente modo :
    int** MAT;
    MAT= new int* [numerorighe];
    for(int i=0;i<numerorighe;i++)
    {
    MAT = new int[numerocolonne];
    }

    è corretto? se si come si procede in questo caso? nel link che mi hai mandato non sono riuscito a capire perchè è scritto in C ed il C non lo conosco per niente...

    EDIT: non avevo letto il messaggio di CarDeFusco (o meglio, ho scritto la mia risposta in contemporanea alla sua a quanto pare), quindi da quanto ho capito se alloco nel modo in cui ho scritto sopra poi mi basta passare alla funzione MAT nel mio caso?


    Rivedi il codice perché ho fatto una po' di modifiche in quanto prima funzionava solo con matrici quadrate, ora dovrebbe andare anche con matrici rettangolari.

    Comunque in linea generale si. Puoi allocare le strutture come nel mio esempio e poi passare alla funzione che deve gestire la matrice 3 parametri: un puntatore a puntatore e le due dimensioni per vedere fino a dove puoi muoverti nella matrice.

    Sicuramente potresti usare le strutture dati standard del C++ come accennava M.A.W. 1968.
    Tuttavia la mia soluzione alla fine non fa niente altro che allocare un array di n puntatori ad intero e per ognuno di questi puntatori alloca la memoria per contenere esattamente m interi. Quindi sono due new(ovvero due blocchi di memoria, ai quali alla fine dovranno corrispondere due delete[]), una new per i puntatori, l'altra per associare blocchi di memoria a questi puntatori.
    In questo modo puoi navigare in una struttura dati che rappresenta una matrice nxm di interi.
  • Re: Passaggio matrice dinamica a funzione C++

    CarDeFusco ho visto la modifica al codice ed effettivamente funziona, grazie mille

    M.A.W. 1968 ha scritto:


    I numerosi problemi e conflitti di standard inerenti il passaggio di un array a subscritti multipli come parametro sono ampiamente spiegati in questo famoso thread. Si tratta di un tema spinoso e ben noto.

    In breve: programmando in C++, si usano le classi apposite come vector, string e valarray. Gli array C-style sono deprecati da Stroustrup in persona e non andrebbero semplicemente usati nel real world.

    Nella prassi, programmando in C, si usa comunque una singola allocazione e si gioca poi con la banale aritmetica degli indici, per motivi prestazionali e di sintesi del codice, richiamati anche più oltre nel noto thread sopra linkato.
    La soluzione meramente scolastica, well behaved, basata su allocazioni multiple è invece quella presentata per esteso (incluso un esplicito supporto per la programmazione difensiva e il fail test) nel thread già referenziato da Candaluar. Il tutto vale comunque per il C: per C++ vale la parola del creatore Stroustrup, ripresa in decine di guide di stile.
    M.A.W. 1968 ti ringrazio molto per l'interessante discussione che mi hai postato, ma ,ahimè, dovendo sostenere il primo esame di fondamenti di informatica non posso ancora utilizzare strutture come quelle che hai nominato ma devo cavarmela "old style" A quanto dici invece mi è parso di capire che al posto della soluzione che adotto solitamente io (allocazioni multiple) sia consigliabile una singola allocazione giocando poi con l'aritmetica degli indici... sapresti spiegarmi perchè dici che la seconda è migliore della prima?
  • Re: Passaggio matrice dinamica a funzione C++

    leonidus ha scritto:


    A quanto dici invece mi è parso di capire che al posto della soluzione che adotto solitamente io (allocazioni multiple) sia consigliabile una singola allocazione giocando poi con l'aritmetica degli indici... sapresti spiegarmi perchè dici che la seconda è migliore della prima?
    La spiegazione è universalmente nota e riportata ampiamente in letteratura. Un accenno è presente, tra l'altro, in coda al lungo thread già referenziato. D'altro canto, è esattamente in tale modo che vengono allocati internamente gli array multidimensionali statici.

    Come ben spiegato anche qui, si tratta di una fondamentale questione di sintesi del codice e di aumento di prestazioni (si eliminano chiamate inutili a funzioni di libreria), con centralizzazione e riduzione dei rischi (fallimento di una malloc) e abbassamento della complessità ciclomatica del codice. In sostanza, si ottengono numerosi vantaggi al costo di un impercettibile cambio di notazione. A proposito della quale, vale la pena di notare che gli standard in proposito sono molto più bizzarri di quanto si possa supporre.
  • Re: Passaggio matrice dinamica a funzione C++

    Ho capito, grazie mille!
Devi accedere o registrarti per scrivere nel forum
10 risposte