PDA

View Full Version : [C] problema con matrice!!!!


Rikka
08-01-2005, 15:46
Devo creare un programma che, acquisita una matrice dinamica, verifica se il primo elemento di una riga è divisibile per la somma della riga stessa....

Ho buttato giu qualcosa.......ma nn so come fare la parte finale.

Chi mi aiuta??


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

void inserisci (int **,int,int);
void visualizza (int **,int,int);
int elemento_somma (int **,int,int);

int main(void)
{
int rig,col,i,j,ok;
int **mat;

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

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

inserisci(mat,rig,col);
visualizza(mat,rig,col);
ok=elemento_somma(mat,rig,col);
printf("vettore somma=%d", ok);
getch();
system("PAUSE");
}


void inserisci (int **mat,int rig,int col)
{int i,j;
clrscr();
printf("Inserisci per righe la matrice");
for(i=0;i<rig;i++)
for(j=0;j<col;j++)
{gotoxy(30+3*j,3+i);
scanf("%d",&mat[i][j]);
}
}

void visualizza (int **m,int rig,int col)
{int i,j;
for (i=0;i<rig; i++)
for(j=0;j<col;j++)
{gotoxy(30+3*j,15+i);
printf("%d",m[i][j]);
}
}

int elemento_somma (int **mat, int rig, int col)

{int i,j,elemento_somma;

for (i=0;i<rig; i++)
elemento_somma=0;
for (j = 1; j < col; j++)
elemento_somma = mat [rig][j];
return (elemento_somma);

}

LimiT-MaTz
08-01-2005, 18:42
eccolo...
fatto spero di aver capito il testo.

eccoti il link (http://MaTz1.altervista.org/FILE/matrice.rar)

Rikka
08-01-2005, 18:55
ma cosa devo cercare in quel sito che mi hai dato??

Vash88
08-01-2005, 19:03
clicca col destro e fai salva con nome ;)

VegetaSSJ5
08-01-2005, 19:18
scusa ma il primo numero di una riga non può essere diviso per la somma dei numeri di quella riga, a meno che gli altri elementi non siano tutti nulli, ma in questo caso non vedo l'utilità del programma. ti puoi spiegare meglio su cosa deve fare il programma? se hai il testo puoi incollarlo qui?

Rikka
08-01-2005, 19:22
Il programma deve acquisire da tastiera una matrice in modo dinamico e dire se il primo numero della riga è divisibile per la somma della riga stessa.
Esempio:

3 7 8 ----------> la somma è 18 ed è divisibile per il primo numero 3.

LimiT-MaTz
08-01-2005, 19:42
Originariamente inviato da VegetaSSJ5
scusa ma il primo numero di una riga non può essere diviso per la somma dei numeri di quella riga, a meno che gli altri elementi non siano tutti nulli, ma in questo caso non vedo l'utilità del programma. ti puoi spiegare meglio su cosa deve fare il programma? se hai il testo puoi incollarlo qui?

esattamente ...
infatti se leggi nel programma che ho scritto ho specificato nei commenti questo fatto :)

Alla fine per logica ho deciso di fare arbtrariamente somma % primo elemento :)

VegetaSSJ5
08-01-2005, 19:59
Originariamente inviato da Rikka
Il programma deve acquisire da tastiera una matrice in modo dinamico e dire se il primo numero della riga è divisibile per la somma della riga stessa.
Esempio:

3 7 8 ----------> la somma è 18 ed è divisibile per il primo numero 3.
beh allora è il contrario.... cioè devi sapere de la somma dei numeri di una riga è divisibile per il primo numero di quella riga.

VegetaSSJ5
08-01-2005, 20:46
l'ho fatto in 5 minuti e senza ricontrollarlo cmq dovrebbe essere una cosa del genere#include <stdlib.h>
#include <stdio.h>

int main () {
int righe, colonne, **matrice, i, j, el, somma;
printf("Inserisci il numero di righe: ");
scanf("%d", &righe);printf("\nInserisci il numero di colonne: ");
scanf("%d", &colonne);
if (righe<=0 || colonne<=0) {
printf("\n\nInserire numeri positivi!!");
exit(-1);
}
matrice=(int **) calloc (righe, sizeof(int **));
for (i=0; i< righe; ++i) matrice[i]= (int *) calloc (colonne, sizeof(int *));
for (i=0; i< righe; ++i) {
for (j=0; j< colonne; ++j) {
printf("\nInserisci l'elemento in posizione %d, %d: ", i, j);
scanf ("%d", &el);
matrice[i][j]= el;
}
}
somma=0;
for (i=0; i< righe; ++i) {
for (j=0; j< colonne; ++j) somma+= matrice[i][j];
if (!(somma%matrice[i][0])) printf("La riga %d (somma= %d) e' divisibile per il primo elemento %d\n", i, somma, matrice[i][0]);
else printf("La riga %d (somma= %d) non e' divisibile per il primo elemento %d\n", i, somma, matrice[i][0]);
}
system("pause");
}

LimiT-MaTz
08-01-2005, 20:52
meglio usare funzioni per il debugging :rolleyes:

VegetaSSJ5
08-01-2005, 21:05
Originariamente inviato da LimiT-MaTz
meglio usare funzioni per il debugging :rolleyes:
cosa intendi?

LimiT-MaTz
08-01-2005, 21:13
se tu scrivi un programma (nel vero senso della parola) complesso.
Se tu fai tutto nel main e' un lavoro immenso se tu dividi il problema in tanti sottoinsiemi e ne analizzi uno alla volta e poi una soluzione. Quando compili e non ti gira ci metti poco a debuggare lavori sulle funzioni.
Cio' ti rende tutto piu' facile.

VegetaSSJ5
08-01-2005, 21:18
e quello ti sembra un programma su cui effettuare un complesso debugging??:rolleyes:
e cmq come ho detto l'ho fatto in poco tempo e non ho pensato per niente alla ottimizzazione e manutenzione futura, era solo per fare un esempio funzionante da mettere a disposizione di Rikka

LimiT-MaTz
08-01-2005, 21:23
l'avevo già fattp nel 2 post :rolleyes:

Cmq e' un fatto di abitudine scrivere tutto usando funzioni :)

Rikka
09-01-2005, 01:29
grazie a tutti!!!!!

Rikka
09-01-2005, 18:07
Ho un altro problema......questo programma acquisisce da tastiera un vettore e dovrebbe visualizzare un altro vettore con gli elementi che si ripetono nel primo vettore.

Sembra che funzioni ma quando lo stesso numero si ripete per piu di 1 volta es.( 345323 compare tre volte il numero 3) nn visualizza il numero 3 che si ripete, ma 333!!!!! Dovè l errore?????

Poi come faccio a visualizzare i numeri che si ripetono cosi:

3
4
5

anziche cosi 3 4 5

Grazie!!!

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

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

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

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

int ripetuti(int*p, int l)
{
int i,j,c;

c=0;
for (i=0; i<l; i++)
{
for (j=i+1; j<l; j++){
if (p[i]==p[j]){
c=c+1;
printf ("L'elemento che si ripete è: ");

printf("%d", p[i]);
}
}
}
}

VegetaSSJ5
09-01-2005, 19:01
#include <stdlib.h>
#include <stdio.h>

int esiste (int *vet, int dim, int num);

int main (void) {
int dim, i, j, *vet, *rip;
printf("Inserisci la dimensione del vettore: ");
scanf("%d", &dim);
if (dim<=0) {
printf("La dimensione del vettore deve essere positiva!");
exit(-1);
}
vet= (int *) calloc (dim, sizeof(int));
rip= (int *) calloc (dim, sizeof(int));
j=0;
for (i=0; i<dim; ++i) {
printf("\nInserisci il numero %d: ", i+1);
scanf("%d", &vet[i]);
if (esiste(vet, i, vet[i]) && !esiste(rip, j, vet[i])) {
rip[j]=vet[i];
++j;
}
}
if (j>0) {
printf("\n\nGli elementi che si ripetono sono:");
for (i=0; i<j; ++i) printf("\n%d", rip[i]);
}
else printf("\n\nNon ci sono elementi che si ripetono\n");
system("pause");
}

int esiste (int *vet, int dim, int num) {
int i;
for (i=0; i<dim; ++i) if (vet[i]==num) return 1;
return 0;
}

Rikka
10-01-2005, 11:33
Ringrazio tutti per i consigli.

Ma l'ultimo programma.......quello del vettore......si puo fare con le funzioni modificando quello che avevo postato???

Prendendo i programmi che mi avete fatto vedere ho rifatto quello con la matrice inserendoci le funzioni.......pero cè un problemino.......ad ogni riga mi memorizza anche il totale della riga precedente.......

Grazie veramente a tutti!!!!!!!!

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

void inserisci (int **,int,int);
void visualizza (int **,int,int);
int elemento_somma (int **,int,int);

int main(void)
{
int rig,col,i,j,ok;
int **mat;

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

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

inserisci(mat,rig,col);
visualizza(mat,rig,col);
ok=elemento_somma(mat,rig,col);
getch();
system("PAUSE");
}


void inserisci (int **mat,int rig,int col)
{int i,j;
clrscr();
printf("Inserisci per righe la matrice");
for(i=0;i<rig;i++)
for(j=0;j<col;j++)
{gotoxy(30+3*j,3+i);
scanf("%d",&mat[i][j]);
}
}

void visualizza (int **m,int rig,int col)
{int i,j;
for (i=0;i<rig; i++)
for(j=0;j<col;j++)
{gotoxy(30+3*j,15+i);
printf("%d",m[i][j]);
}
}

int elemento_somma (int **mat, int rig, int col)

{int i,j,elemento_somma;

elemento_somma=0;
for (i=0;i<rig; i++)
{ for (j=0; j<col; j++)
elemento_somma += mat [i][j];
{gotoxy(30+3*j,15+i);
if (!(elemento_somma%mat[i][0]))
printf("La riga %d (somma= %d) e' divisibile per il primo elemento %d\n", i, elemento_somma, mat[i][0]);
else printf("La riga %d (somma= %d) non e' divisibile per il primo elemento %d\n", i, elemento_somma, mat[i][0]);
}
}
}

Vault
16-01-2005, 23:39
Sto studiando anch'io informatica (in particolare C) e ti faccio una domanda... Cosa ti ha spinto a definire una matrice come **matrice e non come matrice[][]?
Ho l'impressione che puntatori e vettori non siano così interscambiabili come sembra... La matrice che crei con due puntatori non ha una dimensione finita (magari mi dirai che questo è il bello) né i suoi elementi sono consecutivi...

VegetaSSJ5
17-01-2005, 08:10
Originariamente inviato da Vault
Ho l'impressione che puntatori e vettori non siano così interscambiabili come sembra... La matrice che crei con due puntatori non ha una dimensione finita (magari mi dirai che questo è il bello) né i suoi elementi sono consecutivi...
la dimensione invece è finita eccome! che cosa va fatta a fare allora la malloc?? e poi anche se i suoi elementi non sono consecutivi (cosa che cmq non credo) al programmatore questo non interessa visto che cmq il vettore si può visitare incrementando l'indice.

Vault
17-01-2005, 14:28
La malloc è in un capitolo che devo ancora studiare :D

E comunque 'sti puntatori all'inizio sono un po' ostici :muro:

sirus
17-01-2005, 15:05
si all'inizio ma poi non ti verrà + in mente di gestire un array con un indice e userai sempre i puntatori ;) e poi la possibilità di avere un puntatore ad una area di memoria allocata dinamicamente è una cosa stupenda :D cmq impara ad usare i puntatori come si deve questo è un consiglio

Vault
17-01-2005, 22:00
Mi sto impegnando per comprenderli al meglio... :)

Il fatto è che il puntatore mi sembra troppo dispersivo... Un vettore mi dà l'idea di essere un bel trenino di dati, coi suoi vagoni in ordine... Il puntatore mi sembra troppo vago, non vedo i suoi elementi come uno in fila all'altro...
Mi sbaglio? Mi rendo conto che magari la figata sta proprio qui... Mi con tutte le cose in ordine mi sento meglio :D

VegetaSSJ5
17-01-2005, 22:54
il vettore è un trenino di dati e funziona così. se io dichiaro il vettore comeint A[10];vuol dire che sto creando riservando un'area di memoria adatta a contenere 10 elementi di tipo int. per accedere a quell'area di memoria io ho il suo indirizzo base che è A (quindi la variabile A contiene un indirizzo di memoria!). quindi se io scrivo A+4 vuol dire letteralmente "indirizzo di memoria A più quattro locazioni di memoria" (più altre cose che però al momento non ti interessano). quindi vuol dire che il numero A+4 corrisponde all'indirizzo di memoria del quinto (ricordati che vale anche lo 0) numero del vettore. la scrittura A[4] vuol dire "il valore contenuto nell'indirizzo di memoria A+4".
una cosa importante è che la dimensione di un vettore non può essere variata a tempo d'esecuzione e rimane tale (in questo caso 10) fino al termine del programma.
capirai bene che se A, come abbiamo detto, è un indirizzo di memoria, quando io dichiaro un puntatore vuol dire che dichiaro qualcosa di sostanzialmente uguale ad A, cioè un vettore. la dichiarazione di un puntatore avviene scrivendoint *B;in questo modo ho creato una variabile che al suo interno ha un indirizzo di memoria, proprio come A!! ;) solo che B ancora non è un vettore perchè come ricordi ad A abbiamo assegnato 10 locazioni. per assegnare una quantità di memoria ad un puntatore si usa la malloc cosìB= (int *) malloc (10*sizeof(int))te la spiego passo passo: assegna a B (che è un indirizzo di memoria) un indirizzo di memoria (che potrebbe non coincidere con quello che gli era stato assegnato nel momento della dichiarazione di B) e riserva 10*sizeof(int) locazioni a partire da quell'indirizzo. quindi se io scrivo B+4 vale la stessa definizione che ho dato prima per A, e lo stesso vale anche se scrivo B[4]. se io volessi riallocare (leggi ridimensionare, ma in realtà viene riallocata per davvero) l'area di memoria puntata da B dovrei usare la funzione realloc().
ti riporto una serie di scritture equivalenti che possono essere usate indifferentemente sia nel caso la variabile sia stata dichiarata come un vettore che come un puntatore (con il simbolo = intendo "equivalente")

A[0] = *(A)
A[6] = *(A+6)
&A[0] = A
&A[6] = A+6

al momento non me ne vengono altre... :D cmq spero che ti abbia schiarito un po' le idee...:)

Vault
17-01-2005, 23:52
Adesso so a che serve la malloc, grazie :D

Se non la usassi, un vettore dichiarato tramite puntatori potrebbe avere dimensione potezialmente infinita? Questo nei limiti della memoria fisica, dei confini dedicati al programma ecc...
Che rischi si correrebbero quando scorro gli indici del puntatore? Accedo a dati che non mi interessano?

VegetaSSJ5
18-01-2005, 07:11
Originariamente inviato da Vault
Adesso so a che serve la malloc, grazie :D

Se non la usassi, un vettore dichiarato tramite puntatori potrebbe avere dimensione potezialmente infinita? Questo nei limiti della memoria fisica, dei confini dedicati al programma ecc...
Che rischi si correrebbero quando scorro gli indici del puntatore? Accedo a dati che non mi interessano?
se tu non dichiarassi la dimensione di un puntatore, nessuno ti vieta di scorrere gli indici in questo modofor (i=0; i<n; ++i) A[i]= ...nonostante nessuno ti vieta di fare questo devi ricordare che scorrere un puntatore quando non hai allocato memoria è SBAGLIATO! infatti in questo modo andresti ad indicizzare delle celle di memoria che potrebbero far parte della zona delle istruzioni del programma oppure potresti andare oltre i limiti di quel programma in memoria. Nel primo caso se sovrascrivi quelle celle di memoria è probabile che il programma ti vada in crash. Nel secondo caso si dice che il programma va in "segmentation fault", ti restituisce un errore e termina. quando non assegni la dimensione ad un puntatore, ricorda che hai a disposizione UN solo elemento, proprio come se avessi dichiarato una variabile solo che per accedere al suo valore devi fare *var=... invece che var=...
chiaro??;)

Vault
18-01-2005, 19:58
Proprio come pensavo :D

Il segmentation fault ho già avuto modo di conoscerlo in laboratorio :rolleyes:

Grazie ancora!