Passando matrizes multidimensionais como argumentos de função em C

StackOverflow https://stackoverflow.com/questions/4051

  •  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.

Foi útil?

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
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top