PDA

View Full Version : [C] allocazione matrice dinamica


Rikka
14-09-2004, 19:13
Ciao,
sto imparando ora ad usare il C...ho praovato ad allocare un vettore dinamicamente e sembra che funzioni tranne il fatto che nn mi prende la lettera "è":

#include <stdio.h>
#include <conio.c>
#include<stdlib.h>

void leggi(int*,int);
void stampa_vettore(int*,int);
void main(void)
{
int n,*v;
printf("Inserisci il numero degli elementi del vettore (Numero Intero)");
scanf("%d",&n);
v =(int*)malloc(n*sizeof(int));
leggi(v,n);
stampa_vettore(v,n);
getch();
system("PAUSE");
}

void leggi(int*p,int l)
{
int i;
printf("inserisci i numeri nel vettore\n");
for( i = 0 ; i<l ; i++)
scanf("%d",&p[i]);
}

void stampa_vettore(int*p, int l)
{
int i;
printf("il vettore è....\n");
for( i=0;i<l;i++)
printf("%3d\n",p[i]);
printf("\n");
}



ma il problema è la matrice!!!! nn capisco dove sbaglio!!

#include <stdio.h>
#include <conio.c>
#include <stdlib.h>

int n,m;
void leggi_mat(int[][m],int,int);
void stampa_matrice(int[][m],int,int);

void main(void)

{

int i,n,m;
int **mat;
printf("Dammi il valore di n");
scanf("%d", &n);
printf("Dammi il valore di m");
scanf("%d", &m);
mat=(int**)malloc(n*sizeof(int*));
for (i=0;i<m;i++) mat[i]=(int)malloc(m*sizeof(int));


}

void leggi_mat(int pmat[][m], int righe, int colonne)

{

int i,j;
clrscr ();
gotoxy (25,1);
printf("Inserisci i dati");

for (i=0;i<righe;i++)
for (j<0;j<colonne;j++)


{

gotoxy(10+3*j,5+i);
scanf("%d",&pmat[i][j]);

}




Grazie....

Ziosilvio
14-09-2004, 21:44
Ciao.

Il primo programma va bene, a parte il fatto che in C l'header conio.h non è standard, e la funzione main dovrebbe essere dichiarata come int, e restituire:
- 0 in caso di terminazione con successo;
- 1 in caso di terminazione senza errori, ma non soddisfacente;
- valori maggiori di 1 se si verificano errori.

Passando alla matrice...

#include <stdio.h>
#include <conio.c>
#include <stdlib.h>

int n,m;
void leggi_mat(int[][m],int,int);
void stampa_matrice(int[][m],int,int);

void main(void)

{

int i,n,m;
int **mat;
printf("Dammi il valore di n");
scanf("%d", &n);
printf("Dammi il valore di m");
scanf("%d", &m);
mat=(int**)malloc(n*sizeof(int*));
for (i=0;i<m;i++) mat[ i]=(int)malloc(m*sizeof(int));


}

void leggi_mat(int pmat[][m], int righe, int colonne)

{

int i,j;
clrscr ();
gotoxy (25,1);
printf("Inserisci i dati");

for (i=0;i<righe;i++)
for (j<0;j<colonne;j++)


{

gotoxy(10+3*j,5+i);
scanf("%d",&pmat[ i][j]);

}
Il tuo codice si ferma qui e mancano un po' di parentesi graffe.
L'allocazione della matrice sembra corretta (suppongo che n sia il numero di righe ed m il numero di colonne: perché non usi rows e cols, o anche solo r e c?); leggi_mat non viene chiamata, ma se all'inizio del programma fai:
int n,m;
void leggi(int[][m],int,int);
ti ritrovi con una funzione che ha come primo argomento una matrice con un numero imprecisato di righe, e non-si-sa-quante colonne (la variabile m ha un valore arbitrario all'avvio del programma), cosa tra l'altro inutile perché il numero di colonne è anche l'ultimo argomento della funzione.
Ora, in C, al momento del passaggio dei parametri a una funzione, gli array vengono automaticamente convertiti in puntatori: perciò il primo argomento di leggi_mat dovrebbe essere un int**.
Altra cosa: non ricordo cosa fa gotoxy, ma mi sembra che si usi in modalità grafica, mentre tutto l'input-output del tuo programma avviene da riga di comando; così non riesco a capire a cosa serve.
Infine, un trucchetto: in C, p[x] corrisponde esattamente a *(p+x), quindi nella scanf puoi scrivere p+x invece di &p[x]. (Per le matrici la cosa si fa più complicata.)

Rikka
15-09-2004, 10:41
L ho cambiata cosi....pero dopo che ho finito di inserire gli elementi della matrice la schermata in dos va via e torna al programma! Come mai?
Poi come faccio a visualizzare infine la matrice che ho creato?

#include <stdio.h>
#include <stdlib.h>

void main(void)
{
int **mat;
int righe, colonne, r, c;

printf("Inserisci il numero delle righe della matrice: ");
scanf("%d", &righe);
printf("Inserisci il numero delle colonne della matrice: ");
scanf("%d", &colonne);

mat = (int **)malloc(righe * sizeof(int *));
for (r=0; r<righe; r++)
mat[r] = (int *)malloc(colonne * sizeof(int));

for (r=0; r<righe; r++)
for (c=0; c<colonne; c++)
{
printf("Inserisci elemento di riga %d e colonna %d: ", r, c);
scanf("%d", &mat[r][c]);

}
}

Ziosilvio
15-09-2004, 14:22
Originariamente inviato da Rikka
L ho cambiata cosi....pero dopo che ho finito di inserire gli elementi della matrice la schermata in dos va via e torna al programma! Come mai?
Stai usando Borland Turbo C++?
E' normale che faccia cosi': semplicemente, appena la main del tuo programma termina, lui chiude la finestra DOS e torna all'ambiente di sviluppo integrato.
Ci dovrebbe essere un'opzione nei menu per visualizzare la schermata DOS.
Per far terminare la main quando dici tu, un metodo portabile e':
printf("Premi Invio per continuare...");
while (getchar() != '\n')
;
Ti spiego: quando premi Invio, lui comincia a leggere uno dopo l'altro tutti i caratteri che hai messo sullo standard input, l'ultimo dei quali e' un carattere di andata a capo; con questo codice glieli fai leggere tutti uno per uno, esattamente fino al newline.
Poi come faccio a visualizzare infine la matrice che ho creato?
Devi inventarti un modo carino di visualizzare i vari valori; riga per riga a spaziatura fissa va bene, leggi la guida della printf per sapere come fare.
Piuttosto: prima di uscire dal programma, ricordati di deallocare la matrice. Non basta chiamare subito free(mat), devi prima liberare ciascuna delle sue righe.
void main(void)
main dovrebbe essere int.
Molti compilatori accettano che sia dichiarata come void, ma non e' ne' standard ne' portabile.

Rikka
15-09-2004, 15:24
Ciao,
innanzitutto grazie di tutti i consigli....cmq uso il Dev.

Ora provo a rifare la matrice ma con le funzioni, in pratica riprendo la prima che avevo iniziato.

In pratica quante funzioni mi occorrono per creare questa matrice nel modo piu semplice possibile? Mi conviene includerci anche la stampa_matrice?

Scusa per le domande stupide....però se nn capisco questa cosa nn so come andare avanti.

Dovrei creare questa matrice dinamica(come ho gia fatto per il vettore) da usare come "base" per poi fare tutti quegli altri programmini (trasposta, utilizza l ultima riga per memorizzare i totali della colonna, gira la matrice ecc......).

Grazie di tutto!!!

Ziosilvio
15-09-2004, 18:16
Originariamente inviato da Rikka
innanzitutto grazie di tutti i consigli....cmq uso il Dev.
Prego. Ottima scelta il Dev-C++.
In pratica quante funzioni mi occorrono per creare questa matrice nel modo piu semplice possibile? Mi conviene includerci anche la stampa_matrice?
Direi che dipende, in generale, da quanto vuoi che le tue matrici siano generiche.
Se vuoi poter fare tutto in tranquillità, forse ti conviene usare una struttura dati in cui memorizzi numero di righe, numero di colonne, ed elementi: in questo modo, prima di fare un'operazione, controlli se si può fare davvero (es.: la somma si può fare solo tra matrici che hanno uguale numero di righe e di colonne).
Anzi: mi sa che ti conviene fare proprio così, ti servirà anche da allenamento quando dovrai gestire dei casi altrettanto complicati nella "vita reale".

Rikka
15-09-2004, 19:09
ho provato cosi ma ci sono sempre degli errori.....sembra che ci sia qualcosa di sbagliato in "visualizza"


#include <stdlib.h>
#include <stdio.h>
#include <conio.c>

/* dichiarazione dei prototipi di funzione */

int leggi_numero(char*);
void inserisci(char*,int**,int,int);
void visualizza(char*,int**,int,int,int);

/* programma principale */

void main (void)

{

int righe,colonne;
int **mat; /* puntatore a puntatore */
int i;

righe = leggi_numero ("Inserisci il numero delle righe della matrice...");
colonne = leggi_numero ("Inserisci il numero delle colonne della matrice...");
mat = (int**)malloc(righe*sizeof(int*));

for (i=0;i<righe;i++)
mat[i] = (int *)malloc(colonne*sizeof(int));

inserisci("Hai inserito la matrice:\n",mat,righe,colonne);
visualizza("Hai inserito la matrice:\n",mat,righe,colonne);

getch();

}

/* definizione delle funzioni */

int leggi_numero(char*s)

{

int num;

printf ("%s", s);
scanf ("%d", &num);
clrscr();

return (num);

}

void inserisci (char*s,int**x,int rig,int col)

{

int i,j;
printf("%s Numero_righe: %d Numero_colonne: %d", s,rig,col);

for (i=0;i<rig;i++)
for (j=0;j<col;j++)

scanf ("%d", &x[i][j]);
clrscr();

}


void visualizza (char*s, int**x,int rig,int col)

{

int i,j;
printf("\n\n%s", s);

for (i=0;i<rig;i++){
for (j=0;j<col;j++)
printf("%d ", x[i][j]);
printf("\n");
}
printf("\n");

}

Ziosilvio
16-09-2004, 11:05
Originariamente inviato da Rikka
ho provato cosi ma ci sono sempre degli errori.....sembra che ci sia qualcosa di sbagliato in "visualizza"
Che messaggi ti da' il compilatore?
void main(void)
int main(void)

{

int righe,colonne;
int **mat; /* puntatore a puntatore */
int i;

righe = leggi_numero ("Inserisci il numero delle righe della matrice...");
colonne = leggi_numero ("Inserisci il numero delle colonne della matrice...");
mat = (int**)malloc(righe*sizeof(int*));

for (i=0;i<righe;i++)
mat[i] = (int *)malloc(colonne*sizeof(int));

inserisci("Hai inserito la matrice:\n",mat,righe,colonne);
visualizza("Hai inserito la matrice:\n",mat,righe,colonne);

getch();

}
Hai dimenticato di deallocare mat (e i vari mat[0],...,mat[rig-1]).
Potrebbe farlo il programma da solo; ma anche no.
E poi, e' una buona abitudine da prendere.
for (i=0;i<rig;i++)
for (j=0;j<col;j++)

scanf ("%d", &x[i][j]);
clrscr();

}
Usa il tag "code" per conservare l'indentazione.
A proposito: cosi' e' piu' chiaro per l'utente:
for (i=0; i<rig; i++) {
for (j=0: j<col; j++) {
printf("Inserire elemento di riga %d e colonna %d: ",i,j);
x[i][j] = leggi_int("");
} /* for j */
} /* for i */
clrscr();
(leggi_int e' come leggi_numero, ma senza la chiamata a clrscr)

Rikka
16-09-2004, 12:48
Ciao....ti ringrazio veramente!!!!

Oggi pomeriggio proverò a farla una senza char.....
Stamattina ho provato a fare un altro programmino che crea un vettore con la somma delle righe di una matrice.....ovviamente mi da un errore!!!!

Nn saprei veramente come fare la parte principale del programma, quella che calcola la somma delle righe. Mi potresti aiutare?? Scusa se ti chiedo cosi tante cose ma sei l unico che mi ha risposto....

Grazie

Ciao ciao

/*programma che crea un vettore con la somma delle righe di una matrice */


#include <conio.c>
#include <stdlib.h>
#include <stdio.h>

const int rig = 3; /* dichiaro le costanti righe e colonne*/
const int col = 3;

void leggi_matrice(int m[rig][col]); /* prototipi di funzioni*/
void stampa_matrice(int m[rig][col]);
void stampa_vettore(int v[], int dim);
void somma_righe(int m[rig][col], int vetMaxrig[]);




void leggi_matrice(int m[rig][col])

{

int i,j;
for (i = 0; i < rig; i++)
for (j = 0; j < col; j++)
scanf("%d", &m[i][j]);

}

void stampa_matrice(int m[rig][col])

{

int i, j;

for (i = 0; i < rig; i++)
for (j = 0; j < col; j++)
printf("%5d", m[i][j]);
printf("\n");

}

void stampa_vettore(int v[], int dim)

{

int i;
printf("Indice Elemento\n");
for (i = 0; i < rig; i++)
printf("%6d %8d\n", i, v[i]);

}

void somma_righe(int m[rig][col], int vetMaxrig[])

/*crea il vettore somma delle righe*/

{

int i,j;
for (i = 0; i < rig; i++)
vetMaxrig[i] = m[i][0];
for (j = 0; j < [0]col; j++)
vetMatrig += m[i][j];


}

int main(void) /*corpo principale funz. main*/

{

int mat[rig][col];
int vetRighe [rig];

leggi_matrice (mat);
somma_righe (mat, vetRighe);
printf ("Vettore della somma delle righe...\n");
stampa_vettore (vetRighe, rig);
system ("PAUSE");


}

Ziosilvio
16-09-2004, 14:17
Originariamente inviato da Rikka
Stamattina ho provato a fare un altro programmino che crea un vettore con la somma delle righe di una matrice.....ovviamente mi da un errore!!!!
Ti posso aiutare di piu' se posti i messaggi di errore che ti da' il compilatore.
void somma_righe(int m[rig][col], int vetMaxrig[])

/*crea il vettore somma delle righe*/

{

int i,j;
for (i = 0; i < rig; i++)
vetMaxrig[i] = m[i][0];
for (j = 0; j < [0]col; j++)
vetMatrig += m[i][j];


}
j deve partire da 1 (il primo elemento lo hai gia' usato per inizializzare la coordinata del vettore); inoltre qui leggo "j < [0]col", sicuramente un errore di battitura.
int main(void) /*corpo principale funz. main*/

{

int mat[rig][col];
int vetRighe [rig];

leggi_matrice (mat);
somma_righe (mat, vetRighe);
printf ("Vettore della somma delle righe...\n");
stampa_vettore (vetRighe, rig);
system ("PAUSE");


}
Come ultima istruzione della main:
return 0;

Rikka
16-09-2004, 17:21
Ok....ogni volta che mi da un errore te lo scrivo!!

Ora il prog funziona però nn fa assolutamente quello che vorrei che facesse!!!!

Credo che l'errore sia nella funzione somma_righe.....

però nn saprei come correggerlo per fargli memorizzare in un vettore la somma delle righe....potresti darmi qualche consiglio??

Grazie!!!!!!!!!!!

/*programma che crea un vettore con la somma delle righe di una matrice */


#include <conio.c>
#include <stdlib.h>
#include <stdio.h>

const int rig = 2; /* dichiaro le costanti righe e colonne*/
const int col = 2;

void leggi_matrice(int m[rig][col]); /* prototipi di funzioni*/
void stampa_matrice(int m[rig][col]);
void stampa_vettore(int v[], int dim);
void somma_righe(int m[rig][col], int vetMaxrig[]);




void leggi_matrice(int m[rig][col])

{

int i,j;
printf("Inserire i dati nella matrice %dx%d\n\n",rig, col);
for (i = 0; i < rig; i++)
for (j = 0; j < col; j++)
scanf("%d", &m[i][j]);

}

void stampa_matrice(int m[rig][col])

{

int i, j;

for (i = 0; i < rig; i++)
{
for (j = 0; j < col; j++)
printf("%5d", m[i][j]);
printf("\n\n");
}
}

void stampa_vettore(int v[], int dim)

{

int i;
printf("Indice Elemento\n");
for (i = 0; i < rig; i++)
printf("%6d %8d\n", i, v[i]);

}

void somma_righe(int m[rig][col], int vetMaxrig[])

/*crea il vettore somma delle righe*/

{

int i,j;
for (i = 0; i < rig; i++)
vetMaxrig[i] = 0;
for (j = 1; j < col; j++)
vetMaxrig += m[i][j];


}

int main(void) /*corpo principale funz. main*/

{

int mat[rig][col];
int vetRighe [rig];

leggi_matrice (mat);
printf("La matrice che hai inserito...\n\n");
stampa_matrice (mat);
somma_righe (mat, vetRighe);
printf ("Vettore della somma delle righe...\n");
stampa_vettore (vetRighe, rig);
system ("PAUSE");
return 0;


}

Ziosilvio
16-09-2004, 18:23
Originariamente inviato da Rikka
Credo che l'errore sia nella funzione somma_righe.....
Infatti hai dimenticato le parentesi graffe al ciclo su i, e incrementato un puntatore invece del contenuto della zona di memoria puntata.