PROBLEMA Problema programma in C sul prodotto tra matrici

Pubblicità

emmas

Nuovo Utente
Messaggi
1
Reazioni
0
Punteggio
2
Buongiorno, sono alle prime armi e dovrei scrivere un programma in C che, date due matrici in input di dimensione a scelta dall'utente, ne svolge il prodotto (se possibile) e stampa la matrice risultato. Ho scritto il codice ma non riesco a capire dove sto sbagliando, dato che il risultato che ottengo non è sempre corretto. Per esempio, se provo a moltiplicare una matrice 2x3 per una 3x2, mi da come risultato una matrice 3x3.

C:
// Moltiplicazione tra matrici
#include <stdio.h>

int main() {
    int n, m, n1, m1, i, j, k;
    printf("Inserisci dimensione prima matrice\n");
    printf("Numero righe: ");
    scanf("%d", &n);
    printf("Numero colonne: ");
    scanf("%d", &m);// dimensione prima matrice
    printf("Inserisci dimensione seconda matrice\n");
    printf("Numero righe: ");
    scanf("%d", &n1);
    printf("Numero colonne: ");
    scanf("%d", &m1);// dimensione seconda matrice
    if (m!=n1){
        printf("Matrici non moltiplicabili");
    }
    else{
        int a[n][m];
        int b[n1][m1];
        // inserisco le due matrici
        i=0;
        while(i<n){
            while(j<m){
                printf("Valore in posizione a[%d]x[%d]: ", i, j);
                scanf("%d", &a[i][j]);
                j=j+1;
            }
            printf("\n");
            j=0;
            i=i+1;
        }
        i=0;
        while(i<n1){
            while(j<m1){
                printf("Valore in posizione b[%d]x[%d]: ", i, j);
                scanf("%d", &b[i][j]);
                j=j+1;
            }
            printf("\n");
            j=0;
            i=i+1;
        }
        
        // stampo matrici
        printf("\nPrima matrice:\n");
        for (i=0;i<n;++i){
            for (j=0;j<m;++j){
                printf("%d", a[i][j]);
            }
            printf("\n");
        }
        printf("\nSeconda matrice:\n");
        for (i=0;i<n1;++i){
            for (j=0;j<m1;++j){
                printf("%d", b[i][j]);
            }
            printf("\n");
        }
        
        //moltiplicazione
        int c[n][m1];
        k=0;
        for(i=0;i<n;++i){
            j=0;
            for(j=0;j<m1;++j) {
                c[i][j]=0;
                k=0;
                while(k<m){   
                    c[i][j]=c[i][j]+(a[i][k]*b[k][j]);
                    k=k+1;
                }
            }
        }
        // stampo matrice prodotto
        printf("\nLa matrice prodotto è: \n");
        for (i=0;i<m;++i){
            for (j=0;j<n1;++j){
                printf("%d ", c[i][j]);
            }
            printf("\n");
        }
    return 0;
    }
}
 
Cio' che salta subito agli occhi e' che stai utilizzando la variabile j senza averla inizializzata (j=0;), prima di utilizzarla nei cicli while di inizializzazione delle matrici.

C:
        i=0;
        while(i<n){
            j=0;
            while(j<m){
(l'inizializzazione va fatta prima (non dopo), in ognuno dei due cicli while )


Seconda cosa: nella "stampa" delle matrici hai fatto confusione con gli indici:
C:
// devi usare i limiti della matrice:   c[n][m1]; ... ossia n ed m1... al posto di m ed n1
// stampo matrice prodotto
        printf("\nLa matrice prodotto è: \n");
        for (i=0;i<n;++i){    // non m
            for (j=0;j<m1;++j){  // non n1
                printf("%d ", c[i][j]);
            }
            printf("\n");
        }
(per questo stampava una matrice 3x3 nonostante moltoplicassi 2x3 per 3x2)

Un'altra cosa, ma non e' un errore, ti consiglierei di usare il piu' possibile variabili circoscritte ... e.g. nei cicli for:
C:
     for (int i=0;i<n;++i){
            for (int j=0;j<m;++j){
                printf("%d", a[i][j]);
            }
            printf("\n");
        }
In questo modo la variabile nasce e muore (campo di visibilita') nel ciclo for, e si ha minore possibilita' di incappare in errore

Aggiungo:
Hai anche molte ridondanze "inutili"... ma immagino tu le abbia inserite successivamente: quando i risultati non tornavano 😉
C:
        int c[n][m1];
        k=0; // non serve
        for(i=0;i<n;++i){
            j=0; // non serve
            for(j=0;j<m1;++j) {
                c[i][j]=0;
                k=0;
                while(k<m){
                    c[i][j]=c[i][j]+(a[i][k]*b[k][j]);
                    k=k+1; // k++; ... operatore di incremento: e' piu' elegante ... e si puo' usare ovunque... anche fuori dal ciclo for ;-)
                }
            }
 
Ultima modifica:
Concordo con l’analisi di @BrutPitt per cui lascio qui solo due commenti.

  • Quando si usa un ciclo usando un contatore che scorre tra due valori ben definiti e con un incremento constate, sempre usare un for() invece che un while() in quanto il codice è più compatto, più leggibile e si corre meno pericolo di fare errori (per esempio dimenticarsi di inizializzare o incrementare il contatore).
  • In questi casi è assolutamente indispensabile dare buoni nomi alle variabili, una variabile che si chiama semplicemente ‘m’ non vuole dire assolutamente nulla, chi legge il codice non capisce nulla e anche difficile per chi lo ha scritto. Sempre usare nomi descrittivi tipo ‘numeroDiRighe’. Ho scritto una guida a riguardo, la trovi elencata nelle discussioni in rilievo.

Impara queste regole, e vedrai come diventa più facile scrivere il codice e trovare errori.
 
Pubblicità
Pubblicità
Indietro
Top