Pasar matrices multidimensionales como argumentos de función en C

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

  •  08-06-2019
  •  | 
  •  

Pregunta

En C, ¿puedo pasar una matriz multidimensional a una función como un argumento único cuando no sé cuáles serán las dimensiones de la matriz?

Además, mi matriz multidimensional puede contener tipos distintos de cadenas.

¿Fue útil?

Solución

Puede hacer esto con cualquier tipo de datos.Simplemente conviértalo en un puntero a puntero:

typedef struct {
  int myint;
  char* mystring;
} data;

data** array;

Pero no olvides que aún tienes que asignar mal la variable, y se vuelve un poco complejo:

//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");
  }
}

El código para desasignar la estructura es similar: ¡no olvides llamar a free() en todo lo que hayas asignado mal!(Además, en aplicaciones robustas debes comprobar el retorno de malloc().)

Ahora digamos que quieres pasar esto a una función.Todavía puedes usar el puntero doble, porque probablemente quieras realizar manipulaciones en la estructura de datos, no el puntero a punteros de estructuras de datos:

int whatsMyInt(data** arrayPtr, int x, int y){
  return arrayPtr[y][x].myint;
}

Llame a esta función con:

printf("My int is %d.\n", whatsMyInt(array, 2, 4));

Producción:

My int is 6.

Otros consejos

Pase un puntero explícito al primer elemento con las dimensiones de la matriz como parámetros separados.Por ejemplo, para manejar matrices 2D de int de tamaño arbitrario:

void func_2d(int *p, size_t M, size_t N)
{
  size_t i, j;
  ...
  p[i*N+j] = ...;
}

que se llamaría como

...
int arr1[10][20];
int arr2[5][80];
...
func_2d(&arr1[0][0], 10, 20);
func_2d(&arr2[0][0], 5, 80);

El mismo principio se aplica a matrices de dimensiones superiores:

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);

Puedes declarar tu función como:

f(int size, int data[][size]) {...}

Luego, el compilador hará toda la aritmética de punteros por usted.

Tenga en cuenta que los tamaños de las dimensiones deben aparecer antes la propia matriz.

GNU C permite el reenvío de declaraciones de argumentos (en caso de que realmente necesite pasar dimensiones después de la matriz):

f(int size; int data[][size], int size) {...}

La primera dimensión, aunque también se puede pasar como argumento, es inútil para el compilador de C (incluso para el operador sizeof, cuando se aplica sobre una matriz pasada como argumento, siempre se tratará como un puntero al primer 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top