Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Buongiorno ragazzi, so che sto inondando il forum di richieste riguardanti il C, ma scrivendo un piccolo codice per il prodotto riga per colonna tra due matrici utilizzando gli interi generati pseudocasualmente come elementi della matrice mi sono imbattuto in questo tipo di errore logico, ossia che la matrice risultante non è quella che ci si aspettava che sia. Il problema poteva stare proprio nell'elaborazione della funzione, ma l'esercizio è una versione successiva ad un altro esercizio uguale utilizzando i float come elementi pseudocasuali delle due matrici, ed in questo caso funziona perfettamente. Non so il perchè, ho anche provato ad utilizzare la calloc piuttosto che la malloc.
Inoltre vorrei sapere cosa si intende per allocazione della matrice per colonne.. Cioè, ho inteso come si visualizza una matrice per colonne, ma per allocarla non bisogna comunque utilizzare la malloc o la calloc specificando la lunghezza della porzione di memoria, ossia M*N*sizeof(tipo) indifferentemente dal tipo di allocazione della matrice ?!
Ultima modifica effettuata da comtel il 06/09/2018 alle 11:23
Alloca lo spazio per un ARRAY di (row1*col1) elementi, NON una matrice.
Per la matrice PRIMA allochi le righe POI, PER OGNI RIGA, allochi lo spazio per le colonne...tipo:
Codice sorgente - presumibilmente Plain Text
/* righe (ogni elemento è un puntatore) */
mat1 = (int**)malloc( row1 * sizeof(int) );
/* Colonne */
for(i=0; i<row1; i++)
mat1[i] = (int*)malloc( col1 * sizeof(int) );
Ultima modifica effettuata da Mikelius il 06/09/2018 alle 12:12
Per quanto riguarda l'inizializzazione, dovresti assicurarti che il valore contenuto in *(mat3 + i*row1 +j) sia 0 prima di procedere a un += (che somma sul valore già presente, ma il valore già presente è indefinito)
Di solito la memoria è quasi sempre inizializzata a zero per motivi che che ti sono stati accennati nel thread su calloc, ma non c'è questa garanzia in generale.
Prima del for aggiungi una inizializzazione (oppure usa calloc). Ti consiglio per chiarezza maggiore di fare così anzi:
Codice sorgente - presumibilmente C/C++
int elemento = 0;
for (...) {
elemento += ...
}
*(mat3 + i*row1 + j) += elemento;
Lo trovo un po' più chiaro da leggere, inoltre eviti ogni volta un accesso inutile alla memoria: tecnicamente ogni volta che fai *(mat3 + i*row1 + j) fai un indirizzamento alla memoria, che è piu lento di usare una variabile locale siccome di solito il compilatore le salva in un registro. Tutto questo discorso a meno che il compilatore non se ne accorga e ottimizzi, ma ho qualche dubbio su questo.
Ultima modifica effettuata da lumo il 06/09/2018 alle 11:49
Grazie mille per la pronta risposta,
effettuerò dei test con la soluzione che lumo mi ha proposto, ed inoltre ecco qui il codice dell'altro esercizio, che a quanto ho provato e testato funziona:
Codice sorgente - presumibilmente C
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
float* matx_prod(float*,float*,int,int,int,int);
int main(int argc,char*argv[]){
int row1 = atoi(argv[1]), col1 = atoi(argv[2]), row2 = atoi(argv[3]), col2 = atoi(argv[4]), i, j, z;
Osservando la riga di codice, ho fatto un test, quando i = 0; j = 0; z = 1;
Allora la riga dovrebbe essere la seguente: mat3 (ossia primo elemento della matrice risultante) = mat1 + 1 (fin qui ci siamo, ossia il secondo elemento della riga della matrice mat1) * mat2 + 3 (ossia il quarto elemento della matrice mat2, che corrisponde a quello sulla seconda colonna). Il che non dovrebbe andare bene dato che la definizione di prodotto riga per colonna è la seguente:
mat1 =
1 2 3
4 5 6
mat2 =
1 2
3 4
5 6
quindi il primo elemento della matrice risultante dovrebbe essere questo => elemento(1:1) = (1*1 + 2*3 + 3*5).. E così via.
Interessante è però la tua osservazione sulla inizializzazione dell'elemento prima di utilizzarlo, anche se ho utilizzato anche una calloc, che inizializza gli elementi a 0 al suo richiamo. La tua logica di non accedere sempre alla memoria ad ogni passo del ciclo è giusta, ma comunque non ha risolto il mio problema.
Ultima modifica effettuata da comtel il 06/09/2018 alle 12:04
Alloca lo spazio per un ARRAY di (row1*col1) elementi, NON una matrice.
Per la matrice PRIMA allochi le righe POI, PER OGNI RIGA, allochi lo spazio per le colonne...tipo:
/* righe (ogni elemento è un puntatore) */
mat1 = (int**)malloc( row1 * sizeof(int) );
Correggetemi se sto sbagliando qualcosa. E' vero che sto allocando in questo modo un array, ma in memoria una matrice viene comunque vista come un array di N elementi, per tale ragione si accede agli elementi dell'array in quel modo, ad esempio: *(mat1 + i*RIGA + j).
Infatti ho scritto CONCETTUALE.
Ai fini pratici per questo esercizio non da problemi.
Un'altro errore, ma di DIMENTICANZA , è non eseguire i controlli sulle dimensioni delle due matrici (potrei cassare come parametri Stringhe, Numeri negativi...oppure semplicemente righe e colonne di matrici non moltiplicabili.
Queste non sono errori che precludono il funzionamento del programma in se, ma non lo rendono affidabile, tutto qui.
(P.s. hai dichiarato int main(....) è bene far restituire un valore al main. )
Ultima modifica effettuata da Mikelius il 06/09/2018 alle 12:22
Infatti ho scritto CONCETTUALE.
Ai fini pratici per questo esercizio non da problemi.
Va bene, va bene.
Intanto ancora devo risolvere il problema del prodotto (ho anche provato con la soluzione di lumo, per quanto secondo i miei test non sia del tutto esatta), ma continuerò con l'esercizio sperando di trovarla successivamente.
Non è un errore, è più confusione terminologica.
La matrice in matematica è una rappresentazione di una trasformazione lineare, in un programma si può rappresentare in diversi modi tra cui uno di questi è quello con un array ( e anche il più semplice secondo me).
La confusione sta nel fatto che anche in programmazione si dice matrice, ma in realtà si dovrebbe dire array multidimensionale lol