Passaggio di matrici di dimensioni diverse a funzione

WonderZ
Salve a tutti,
nella scrittura di un programma in linguaggio C ho creato una funzione leggiMatrice con l'obiettivo di leggere delle matrici di numeri da file, con dimensioni diverse (la prima ad esempio di dimensione N, la seconda M entrambe definite con #define). Il problema è che le dimensioni M e N sono differenti. Inizialmente come dichiarazione della funzione avevo scritto:
void leggiMatrice(int dim, int matrice[][dim]);
e, passando prima N, poi M, alla funzione il programma funziona correttamente.
Il professore, tuttavia, ci ha poi invitato a lezione di non passare dei valori di dimensioni alle funzioni in questo modo, perché il C11 ha fatto marcia indietro sull'utilizzo di questo codice (nonostante alcuni compilatori, come il mio, lo leggano perfettamente).
Poiché ancora non conosco l'allocazione dinamica ed abbiamo appena visto l'utilizzo dei puntatori (relativi tuttavia ad un vettore al massimo, non alle matrici come nel caso di un **matrice), mi sto quindi interrogando su come risolvere il problema. Per mantenere la modularità del programma, preferirei mantenere la funzione, ma è possibile modificarla senza ricorrere all'allocazione dinamica ed utilizzando al massimo dei puntatori?
Vi ringrazio :)

Risposte
vict85
La scrittura
void leggiMatrice(int dim, int matrice[][dim]);
non alloca nuova memoria ed è sinceramente un peccato che non possa essere usato a causa dell'altro uso che si fa dei VLA. Diciamo che la maggiore ragione per non usarlo è che il C++ non lo permette, quindi se ti abitui troppo e poi ti trovi a programmare in C++ potresti incorrere in errori del compilatore difficili da decifrare.

In ogni caso la scrittura
int matrice[][dim]
in una chiamata di funzione è equivalente a
int (* matrice)[dim]
ovvero ad un puntatore ad un array di dimensione dim. Le differenze da un più semplice
int* matrice
le puoi vedere nel seguente codice (prova a compilarlo e giocarci):
#include <stdio.h>
#define N 4

int main(void)
{
	int a[5][N] = { [2][3] = 1 };	// i valori non assegnati vanno a 0
	int *b = (int *) a;
	int (*c)[N] = a;
	printf("%d %d %d\n", *(b + 2*N + 3), c[2][3], (*(c + 2))[3] ); // stampa 1 1 1
}


In sostanza in genere si sostituisce
int matrice[][dim]
con
int * matrice
e si accede all'elemento in questo modo
matrice[i*dim +j]; // per accedere a matrice[i][j]

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.