[risolto] Passaggio di matrici in C

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
edgy
Prode Principiante
Messaggi: 134
Iscrizione: sabato 28 ottobre 2006, 14:32

[risolto] Passaggio di matrici in C

Messaggio da edgy »

Questo è un modo per passare una matrice ad una funzione.

Codice: Seleziona tutto

#include <stdio.h>


void stampa_matrice (int mat[10][10])
{
	int i,j;
	printf("\nLa matrice è:\n");
	for (i=0;i<10;i++)
	{
		printf("\n");
		for(j=0;j<10;j++)
			printf(" %d",mat[i][j]);
	}
	printf("\n");
}


int main()
{
	int matrice[10][10],i,j;

	for (i=0;i<10;i++)
		for(j=0;j<10;j++)
			matrice[i][j]=j;

	stampa_matrice(matrice);

	return(0);
}
L'idea di passare alla funzione la matrice in questo modo non mi piace, quindi c'è un modo per passarla senza inserire da nessuna parte
la grandezza delle righe e delle colonne?
Cioè io vorrei evitare questa stringa di codice

Codice: Seleziona tutto

void stampa_matrice (int mat[10][10])
come si fa?
Ultima modifica di edgy il martedì 29 maggio 2007, 19:38, modificato 1 volta in totale.
Avatar utente
simo_magic
Rampante Reduce
Rampante Reduce
Messaggi: 9496
Iscrizione: lunedì 18 dicembre 2006, 21:37
Località: Piemonte

Re: Passaggio di matrici in C

Messaggio da simo_magic »

ma se è il nome della funzione! non puoi!
magari quello che vuoi far tu è usare una dimensione che cambia dinamicamente a seconda dei dati che ricevi in input...
Avatar utente
jack84
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 493
Iscrizione: lunedì 12 febbraio 2007, 11:13

Re: Passaggio di matrici in C

Messaggio da jack84 »

Un'idea semplice potrebbe essere quella di definire una costante che rappresenti la dimensione della matrice.
Dopo gli include definisci una costante DIM di valore 10
#include
#define DIM 10

Poi modifica la funzione in questo modo:

void stampa_matrice (int mat[DIM][DIM])

In questo modo hai il vantaggio che se vuoi cambiare la dimensione della matrice è sufficente che ne cambi il valore
affianco a #define DIM .
Anche nei cicli per scorrere la matrice invece di scrivere 10 puoi mettere DIM in modo da far sempre riferimento alla dimensione impostata
Ultima modifica di jack84 il lunedì 28 maggio 2007, 16:29, modificato 1 volta in totale.
Non sempre si può prevedere, ma ci si può sempre preparare
Avatar utente
simo_magic
Rampante Reduce
Rampante Reduce
Messaggi: 9496
Iscrizione: lunedì 18 dicembre 2006, 21:37
Località: Piemonte

Re: Passaggio di matrici in C

Messaggio da simo_magic »

oppure passare all'allocazione dinamica della memoria...
Avatar utente
jack84
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 493
Iscrizione: lunedì 12 febbraio 2007, 11:13

Re: Passaggio di matrici in C

Messaggio da jack84 »

Se fosse un array potresti benissimo non passare alcuna dimensione, il problema qui stà nel fatto che il compilatore deve conoscere almeno una delle dimensioni della tua struttura altrimenti dalla funzione non sà come è allocato lo spazio e di conseguenza non sà come organizzarsi.
Ultima modifica di jack84 il lunedì 28 maggio 2007, 16:59, modificato 1 volta in totale.
Non sempre si può prevedere, ma ci si può sempre preparare
edgy
Prode Principiante
Messaggi: 134
Iscrizione: sabato 28 ottobre 2006, 14:32

Re: Passaggio di matrici in C

Messaggio da edgy »

simo_magic ha scritto: oppure passare all'allocazione dinamica della memoria...
ok la questione non è farla dinamica era solo per sapere se creo una matrice del genere se potevo passarla ad una funzione senza quelle
"fastidiose" dimensioni :D
jack84 ha scritto: Se fosse un array potresti benissimo non passare alcuna dimensione, il problema qui stà nel fatto che il compilatore deve conoscere almeno una delle dimensioni della tua struttura altrimenti dalla funzione non sà come è allocato lo spazio e di conseguenza non sà come organizzarsi.
mi approfondiresti questa frase? nel senso che questo è quello che riportano tutte le guide ma esattamente che fa il compilatore?
che succede se passo la dimensione delle colonne o delle righe?
Avatar utente
jack84
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 493
Iscrizione: lunedì 12 febbraio 2007, 11:13

Re: Passaggio di matrici in C

Messaggio da jack84 »

mi approfondiresti questa frase? nel senso che questo è quello che riportano tutte le guide ma esattamente che fa il compilatore?
che succede se passo la dimensione delle colonne o delle righe?
La matrice  viene passata per riferimento alla funzione, cioè in pratica non viene creata una copia della matrice ma la funzione opera direttamente sulla matrice di partenza senza creare alcuna copia (è importante che tu sappia la differenza del passaggio di un parametro per valore o per riferimento, se non la conosci chiedi pure).
La ram del pc è costituita  da una serie di locazioni una dopo l'altra esattamente come un vettore, gestire un vettore quindi è il modo più naturale possibile di usare la memoria.
Quando usi il vettore per fare riferimento a una cella scrivi "vettore[ i ] "  (dove i è la posizione dell'elemento che vuoi considerare) il compilatore per determinare la posizione in memoria si basa sul tipo e sulla posizione iniziale del vettore in memoria dove è allocato il primo elemento in questo modo:
posizione iniziale + ( dimensione del tipo *  i )
Questo spiega anche perchè vettori e puntatori sono di fatto la stessa cosa.
Per le matrici è un pò diverso, è stato creato un artificio per poterle usare, poichè la memoria ha una sola dimensione costituita dagli indirizzi crescenti di memoria, viceversa le matrici hanno due dimensioni una per riga e una per colonna,  il compilatore sarà dunque costetto ad usare un artificio per gestire le matrici .
Usando le matrici in questo modo " matrice [ i ][ j ] " (dove i indice di riga e j di colonna) il compilatore è in grado di fare riferimento alla giusta cella di memoria eseguendo queste operazioni:
posizione iniziale+((dimensione del tipo*i)*numero di colonnedella matrice + dimensione del tipo *j)

esempio: supponiamo che abbiamo questa matrice in memoria:
int vettore[3][3]={{2,3,5}{7,8,1}{4,6,9}}

esempio: quando facciamo riferimento alla locazione vettore[1][2] (non considero posizione iniziale e dimensione dell'intero ma tieni presente che il compilatore lo fà)
j*numero colonne della matrice+i = 1*3+2=5
Infatti se conti gli elementi dall'inizio della matrice (come se fosse un vettore )l'elemento considerato è il sesto (ricordati che sia per le matrici che per i vettori il primo elemento è l'elemento 0 e non 1).
Dopo tutto questo giro di parole cosa rimane? che al compilatore è necessario conoscere la dimensione del numero di colonne della matrice altrimenti non è in grado di indirizzare correttamente i riferimenti alla matrice.  Se qualcosa non è molto chiaro chiedi pure
Ultima modifica di jack84 il martedì 29 maggio 2007, 10:25, modificato 1 volta in totale.
Non sempre si può prevedere, ma ci si può sempre preparare
Avatar utente
mediv
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 365
Iscrizione: mercoledì 28 giugno 2006, 13:13

Re: Passaggio di matrici in C

Messaggio da mediv »

Se il tuo problema è quello che vuoi usare la stessa funzione per diverse matrici(da qui si capisce il fastidio che ti danno quelle dimensioni), una soluzione è la seguente(che si basa su quello che ha detto jack84):

Codice: Seleziona tutto

void stampa_matrice (int *mat,int dimR,int dimC)
{
	int i,j;
	printf("\nLa matrice è:\n");
	for (i=0;i<dimR;i++)
	{
		printf("\n");
		for(j=0;j<dimC;j++)
			printf(" %d",mat[dimC*i+j]);
	}
	printf("\n");
}
e l'invocazione sarà:

Codice: Seleziona tutto

stampa_matrice(&matrice[0][0],10,10);
dove gli ultimi 2 sono rispettivamente il numero di righe e il numero di colonne. Altre invocazioni della stessa funzione sono:

Codice: Seleziona tutto

stampa_matrice(matrice[0],10,10);
stampa_matrice(*matrice,10,10);
Avatar utente
jack84
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 493
Iscrizione: lunedì 12 febbraio 2007, 11:13

Re: Passaggio di matrici in C

Messaggio da jack84 »

Non lo conoscevo questo modo di passare matrici davvero utile  ;D
Non sempre si può prevedere, ma ci si può sempre preparare
Netmaster
Prode Principiante
Messaggi: 161
Iscrizione: giovedì 24 agosto 2006, 11:42

Re: Passaggio di matrici in C

Messaggio da Netmaster »

Quello è il miglior modo per passare le matrici...anche perché ricordati una cosa; se passi una variabile o un array direttamente come hai fatto te all'inizio il programma C passa quei valori "per copia" occupando quindi più spazio in memoria (e nello stack memory). Mentre passandoli per referenza e usando i puntatori (come ti ha illustrato Mediv) non "copi" niente, lo stack rimane piu pulito e in generale il programma è piu efficiente.. Devi solo stare a ttento a controllare bene dove "puntano" i puntatori per evitare di leggere dati sbagliati.
Ricordati inoltre che passando per referenza una matrice, qualsiasi modifica che apporti a quella matrice nella tua funzione si riperquoteranno nella matrice originale (in quanto usando i puntatori te operi DIRETTAMENTE nella matrice originale)
Avatar utente
jack84
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 493
Iscrizione: lunedì 12 febbraio 2007, 11:13

Re: Passaggio di matrici in C

Messaggio da jack84 »

Scusa ma passare la matrice in questo modo:
void stampa_matrice (int mat[DIM][DIM])
è comunque un passaggio per riferimento alla matrice (le modifiche si ripercuotono).
Non sempre si può prevedere, ma ci si può sempre preparare
Avatar utente
mediv
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 365
Iscrizione: mercoledì 28 giugno 2006, 13:13

Re: Passaggio di matrici in C

Messaggio da mediv »

Le matrice vengono sempre passate per riferimento.
Netmaster
Prode Principiante
Messaggi: 161
Iscrizione: giovedì 24 agosto 2006, 11:42

Re: Passaggio di matrici in C

Messaggio da Netmaster »

Pardon ma anni di lavoro in VS/VB mi hanno fatto dimenticare alcuni piccoli particolari propri del C eheh...
chiedo venia  :-[
Avatar utente
jack84
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 493
Iscrizione: lunedì 12 febbraio 2007, 11:13

Re: Passaggio di matrici in C

Messaggio da jack84 »

Non c'è problema, in pratica i due metodi fanno la stessa cosa, solo in uno è il compilatore a occuparsi del passaggio vettore -> matrice mentre nell'altro lo fà manualmente il programma
Non sempre si può prevedere, ma ci si può sempre preparare
Netmaster
Prode Principiante
Messaggi: 161
Iscrizione: giovedì 24 agosto 2006, 11:42

Re: Passaggio di matrici in C

Messaggio da Netmaster »

esatto..diciamo inoltre che se usi i puntatori puoi creare matrici dinamiche ricorrendo alla malloc il che ti permetterebbe di rendere piu generica quella funzione
edgy
Prode Principiante
Messaggi: 134
Iscrizione: sabato 28 ottobre 2006, 14:32

Re: Passaggio di matrici in C

Messaggio da edgy »

Per jack84
Grazie della spiegazione esauriente!
Netmaster ha scritto: esatto..diciamo inoltre che se usi i puntatori puoi creare matrici dinamiche ricorrendo alla malloc il che ti permetterebbe di rendere piu generica quella funzione
Bello il metodo consigliato.
Per quanto rigurda le matrici dinamiche non c'è questo problema in quanto alla fine passi un vettore e non la matrice quindi puoi omettere tranquillamente le dimensioni.
Netmaster
Prode Principiante
Messaggi: 161
Iscrizione: giovedì 24 agosto 2006, 11:42

Re: [risolto] Passaggio di matrici in C

Messaggio da Netmaster »

si esatto, quello che intendevo dire è che in tal caso con questo metodo puoi tranquillamente anche ridimensionarle on the fly se ne hai la necessità  :)
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: Bing [Bot] e 2 ospiti