Domanda Risolto prodotto matrice per vettore

alessina02

Utente Iron
2 Gennaio 2022
14
6
0
9
Non riesco a capire l'errore...il prodotto dà un output sbagliato, come se il ciclo for girasse più del dovuto.
C++:
/*Programma che legge un intero positivo
n minore di 6, gli elementi di una matrice
A nxn e un vettore u e calcola il vettore
v=Au, il vettore w che contiene la somma
della corrispondente colonna di A e il
prodotto scalare tra u e w*/
#include <stdio.h>
#include <math.h>
#define N 10
typedef int Matrice[N][N];
int leggi_dato (int&);
int controllo_dato (int);
void leggi_matrice (int [N][N], int);
int leggi_vettore (int&);
void prodotto_matrice (int [N][N], int[], int);
int main ()
{int n=leggi_dato (n);
if (controllo_dato (n)==0) return 0;
Matrice A;
leggi_matrice (A, n);
int u[n];
u[n]=leggi_vettore (n);
int w[n];
prodotto_matrice (A, u, n);
return 0;}


int leggi_dato (int&a)
{printf ("Inserire numero minore di 6="); scanf("%d", &a);
if (controllo_dato (a)==0) {printf ("Numero errato"); return 0;}
return a;}

int controllo_dato (int a)
{if (a>10||a<1) return 0; else return 1;}

void leggi_matrice (int A[N][N], int n)
{for (int i=0; i<n; i++) {for (int j=0; j<n; j++) {printf ("Matrice %d %d=", i+1, j+1); scanf("%d", &A[i][j]);}}
return;
}

int leggi_vettore (int&n)
{int a[n]; for (int i=0; i<n; i++) {printf ("Inserire %d componente del vettore u=", i+1);
scanf ("%d", &a[i]);} return a[n];
}

void prodotto_matrice (int a[N][N], int u[N], int n)
{int i, j;
int w[N];
for (i=0; i<n; i++) {w[i]=0; for (j=0; j<n; j++) {w[i]+=(a[i][j]*u[j]);}}
for (int k=0; k<n; k++) printf ("%d\n", w[k]); return;
}
 

St3ve

Utente Jade
12 Ottobre 2011
2,314
5
1,648
680
Stai usando C o C++? In C la sintassi int &a; (variabile di tipo riferimento) non esiste e oltretutto la stai usando in modo sbagliato. In C quando definisci una variabile con la sintassi tipo nome_variabile; non puoi usare il simbolo &, se vuoi un puntatore puoi usare il simbolo *. Puoi usare la & solo se la variabile l'hai già definita e vuoi prendere il suo indirizzo, ma a quel punto non devi specificare il tipo.

C:
int leggi_dato() {
  int a;
  printf("Inserire numero minore di 6=");
  scanf("%d", &a);
  if (controllo_dato(a) == 0) {
    printf("Numero errato");
    return 0;
  }
  return a;
}

Stai ancora facendo l'errore di usare VLA invece di array normali: int u[n]; dovrebbe essere int u[N]; e int w[n]; dovrebbe essere int w[N];. Le funzioni non possono restituire un array, quindi anche u[n] = leggi_vettore(n); è sbagliato. Dovresti implementare leggi_vettore allo stesso modo in cui hai implementato leggi_matrice:
C:
void leggi_vettore(int a[N], int n) {
  for (int i = 0; i < n; i++) {
    printf("Inserire %d componente del vettore u=", i + 1);
    scanf("%d", &a[i]);
  }
}

Prova a fare la stessa cosa anche con prodotto_matrice. Devi creare una funzione void prodotto_matrice(int[N], int[N][N], int[N], int); dove il primo argomento è il vettore int w[N]; che sei interessata a riempire e gli altri tre parametri sono la matrice, il vettore e la dimensione.

Ci sono dei difetti di stile, ma io ne riparlerei solo dopo aver sistemato gli errori.
 
  • Mi piace
Reazioni: DanyDollaro

nfvblog

Moderatore
9 Dicembre 2021
489
42
202
313
Non riesco a capire l'errore...il prodotto dà un output sbagliato, come se il ciclo for girasse più del dovuto.
C++:
/*Programma che legge un intero positivo
n minore di 6, gli elementi di una matrice
A nxn e un vettore u e calcola il vettore
v=Au, il vettore w che contiene la somma
della corrispondente colonna di A e il
prodotto scalare tra u e w*/
#include <stdio.h>
#include <math.h>
#define N 10
typedef int Matrice[N][N];
int leggi_dato (int&);
int controllo_dato (int);
void leggi_matrice (int [N][N], int);
int leggi_vettore (int&);
void prodotto_matrice (int [N][N], int[], int);
int main ()
{int n=leggi_dato (n);
if (controllo_dato (n)==0) return 0;
Matrice A;
leggi_matrice (A, n);
int u[n];
u[n]=leggi_vettore (n);
int w[n];
prodotto_matrice (A, u, n);
return 0;}


int leggi_dato (int&a)
{printf ("Inserire numero minore di 6="); scanf("%d", &a);
if (controllo_dato (a)==0) {printf ("Numero errato"); return 0;}
return a;}

int controllo_dato (int a)
{if (a>10||a<1) return 0; else return 1;}

void leggi_matrice (int A[N][N], int n)
{for (int i=0; i<n; i++) {for (int j=0; j<n; j++) {printf ("Matrice %d %d=", i+1, j+1); scanf("%d", &A[i][j]);}}
return;
}

int leggi_vettore (int&n)
{int a[n]; for (int i=0; i<n; i++) {printf ("Inserire %d componente del vettore u=", i+1);
scanf ("%d", &a[i]);} return a[n];
}

void prodotto_matrice (int a[N][N], int u[N], int n)
{int i, j;
int w[N];
for (i=0; i<n; i++) {w[i]=0; for (j=0; j<n; j++) {w[i]+=(a[i][j]*u[j]);}}
for (int k=0; k<n; k++) printf ("%d\n", w[k]); return;
}
Ti posso dare un consiglio? Indenta meglio il codice, perché altrimenti diventa anche più difficile comprendere dove hai fatto l'errore, un altro consiglio è quello di utilizzare il debugger perché molte volte è illuminante.
 

SpeedJack

Sviluppatore
Amministratore
18 Febbraio 2010
5,788
74
3,824
1,413
alessina, agli inizi potrebbe sembrarti poco importante ma scrivere un codice ben indentato, formattato e ordinato è molto importante.
Molti degli errori che commetti sono probabilmente dovuti al fatto che dopo aver scritto il codice hai difficoltà pure tu a rileggerlo per cercare i problemi. Seguire delle buone regole di stile è più importante di quanto pensi per evitare errori e trovarli successivamente quando qualcosa non funziona.

Ad esempio, dovresti evitare di scrivere più istruzioni sulla stessa riga; ogni volta che inizi un blocco (funzioni, if, while, for, ...) dovresti indentare di un livello il codice dentro, in modo da distinguerlo dal resto; dopo il nome di una funzione non dovresti mettere uno spazio prima della parentesi tonda aperta.
Puoi dare un'occhiata alle regole di stile del kernel Linux. A parte alcune cose specifiche per lo sviluppo del kernel, sono buone regole di stile generali per la programmazione in C/C++.
Vedrai che già soltanto adottando regole di stile migliori ridurrai di molto gli errori che commetti.

Di seguito il tuo codice originale (compreso di errori) con uno stile migliore - dovresti notare anche tu che si legge molto meglio:
C:
/*
 * Programma che legge un intero positivo n minore di 6, gli elementi di una
 * matrice A nxn e un vettore u e calcola il vettore v=Au, il vettore w che
 * contiene la somma della corrispondente colonna di A e il prodotto scalare
 * tra u e w
 */

#include <stdio.h>
#include <math.h>

#define N 10

typedef int Matrice[N][N];

int leggi_dato(int&);
int controllo_dato(int);
void leggi_matrice(int[N][N], int);
int leggi_vettore(int&);
void prodotto_matrice(int[N][N], int[], int);

int main()
{
        int n = leggi_dato(n);
        if (controllo_dato(n) == 0)
                return 0;

        Matrice A;
        leggi_matrice(A, n);

        int u[n];
        u[n] = leggi_vettore(n);

        int w[n];
        prodotto_matrice(A, u, n);
        return 0;
}


int leggi_dato(int &a)
{
        printf("Inserire numero minore di 6=");
        scanf("%d", &a);
        if (controllo_dato(a) == 0) {
                printf("Numero errato");
                return 0;
        }
        return a;
}

int controllo_dato(int a)
{
        if (a > 10 || a < 1)
                return 0;
        else
                return 1;
}

void leggi_matrice(int A[N][N], int n)
{
        for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++) {
                        printf("Matrice %d %d=", i + 1, j + 1);
                        scanf("%d", &A[i][j]);
                }
}

int leggi_vettore(int &n)
{
        int a[n];
        for (int i = 0; i < n; i++) {
                printf("Inserire %d componente del vettore u=", i + 1);
                scanf("%d", &a[i]);
        }
        return a[n];
}

void prodotto_matrice(int a[N][N], int u[N], int n)
{
        int i, j;
        int w[N];

        for (i = 0; i < n; i++) {
                w[i] = 0;
                for (j = 0; j < n; j++)
                        w[i] += a[i][j] * u[j];
        }

        for (int k = 0; k < n; k++)
                printf("%d\n", w[k]);
}