Passando matrizes multidimensionais como argumentos de função em C
-
08-06-2019 - |
Pergunta
Em C posso passar um array multidimensional para uma função como um único argumento quando não sei quais serão as dimensões do array?
Além disso, meu array multidimensional pode conter outros tipos além de strings.
Solução
Você pode fazer isso com qualquer tipo de dados.Basta torná-lo um ponteiro a ponteiro:
typedef struct {
int myint;
char* mystring;
} data;
data** array;
Mas não esqueça que você ainda precisa fazer o malloc da variável, e isso fica um pouco complexo:
//initialize
int x,y,w,h;
w = 10; //width of array
h = 20; //height of array
//malloc the 'y' dimension
array = malloc(sizeof(data*) * h);
//iterate over 'y' dimension
for(y=0;y<h;y++){
//malloc the 'x' dimension
array[y] = malloc(sizeof(data) * w);
//iterate over the 'x' dimension
for(x=0;x<w;x++){
//malloc the string in the data structure
array[y][x].mystring = malloc(50); //50 chars
//initialize
array[y][x].myint = 6;
strcpy(array[y][x].mystring, "w00t");
}
}
O código para desalocar a estrutura é semelhante - não se esqueça de chamar free() em tudo que você alocou!(Além disso, em aplicações robustas você deve verifique o retorno de malloc().)
Agora digamos que você queira passar isso para uma função.Você ainda pode usar o ponteiro duplo, porque provavelmente deseja fazer manipulações na estrutura de dados, e não o ponteiro para ponteiros de estruturas de dados:
int whatsMyInt(data** arrayPtr, int x, int y){
return arrayPtr[y][x].myint;
}
Chame esta função com:
printf("My int is %d.\n", whatsMyInt(array, 2, 4));
Saída:
My int is 6.
Outras dicas
Passe um ponteiro explícito para o primeiro elemento com as dimensões da matriz como parâmetros separados.Por exemplo, para lidar com matrizes 2-d de tamanho arbitrário de int:
void func_2d(int *p, size_t M, size_t N)
{
size_t i, j;
...
p[i*N+j] = ...;
}
que seria chamado como
...
int arr1[10][20];
int arr2[5][80];
...
func_2d(&arr1[0][0], 10, 20);
func_2d(&arr2[0][0], 5, 80);
O mesmo princípio se aplica a matrizes de dimensão superior:
func_3d(int *p, size_t X, size_t Y, size_t Z)
{
size_t i, j, k;
...
p[i*Y*Z+j*Z+k] = ...;
...
}
...
arr2[10][20][30];
...
func_3d(&arr[0][0][0], 10, 20, 30);
Você pode declarar sua função como:
f(int size, int data[][size]) {...}
O compilador fará toda a aritmética de ponteiros para você.
Observe que os tamanhos das dimensões devem aparecer antes a própria matriz.
GNU C permite o encaminhamento de declaração de argumentos (caso você realmente precise passar dimensões após o array):
f(int size; int data[][size], int size) {...}
A primeira dimensão, embora você também possa passar como argumento, é inútil para o compilador C (mesmo para o operador sizeof, quando aplicado sobre um array passado como argumento sempre o tratará como um ponteiro para o primeiro elemento).
int matmax(int **p, int dim) // p- matrix , dim- dimension of the matrix
{
return p[0][0];
}
int main()
{
int *u[5]; // will be a 5x5 matrix
for(int i = 0; i < 5; i++)
u[i] = new int[5];
u[0][0] = 1; // initialize u[0][0] - not mandatory
// put data in u[][]
printf("%d", matmax(u, 0)); //call to function
getche(); // just to see the result
}