¿Cómo pasar una matriz 2D (matriz) en una función en C?

Resuelto Shweta asked hace 14 años • 4 respuestas

También necesito hacer esto para persistir las operaciones en la matriz. ¿Eso significa que debe pasarse por referencia?

¿Será esto suficiente?

void operate_on_matrix(char matrix[][20]);

Shweta avatar Oct 12 '10 10:10 Shweta
Aceptado

C realmente no tiene matrices multidimensionales, pero hay varias formas de simularlas. La forma de pasar dichas matrices a una función depende de la forma utilizada para simular las múltiples dimensiones:

1) Utilice una serie de matrices. Esto solo se puede usar si los límites de su matriz están completamente determinados en el momento de la compilación, o si su compilador admite VLA :

#define ROWS 4
#define COLS 5

void func(int array[ROWS][COLS])
{
  int i, j;

  for (i=0; i<ROWS; i++)
  {
    for (j=0; j<COLS; j++)
    {
      array[i][j] = i*j;
    }
  }
}

void func_vla(int rows, int cols, int array[rows][cols])
{
  int i, j;

  for (i=0; i<rows; i++)
  {
    for (j=0; j<cols; j++)
    {
      array[i][j] = i*j;
    }
  }
}

int main()
{
  int x[ROWS][COLS];

  func(x);
  func_vla(ROWS, COLS, x);
}

2) Utilice una matriz de punteros (asignados dinámicamente) a matrices (asignadas dinámicamente). Esto se usa principalmente cuando los límites de la matriz no se conocen hasta el tiempo de ejecución.

void func(int** array, int rows, int cols)
{
  int i, j;

  for (i=0; i<rows; i++)
  {
    for (j=0; j<cols; j++)
    {
      array[i][j] = i*j;
    }
  }
}

int main()
{
  int rows, cols, i;
  int **x;

  /* obtain values for rows & cols */

  /* allocate the array */
  x = malloc(rows * sizeof *x);
  for (i=0; i<rows; i++)
  {
    x[i] = malloc(cols * sizeof *x[i]);
  }

  /* use the array */
  func(x, rows, cols);

  /* deallocate the array */
  for (i=0; i<rows; i++)
  {
    free(x[i]);
  }
  free(x);
}

3) Utilice una matriz unidimensional y arregle los índices. Esto se puede utilizar tanto con matrices asignadas estáticamente (tamaño fijo) como asignadas dinámicamente:

void func(int* array, int rows, int cols)
{
  int i, j;

  for (i=0; i<rows; i++)
  {
    for (j=0; j<cols; j++)
    {
      array[i*cols+j]=i*j;
    }
  }
}

int main()
{
  int rows, cols;
  int *x;

  /* obtain values for rows & cols */

  /* allocate the array */
  x = malloc(rows * cols * sizeof *x);

  /* use the array */
  func(x, rows, cols);

  /* deallocate the array */
  free(x);
}

4) Utilice un VLA asignado dinámicamente. Una ventaja de esto sobre la opción 2 es que hay una única asignación de memoria; otra es que se necesita menos memoria porque no se requiere la matriz de punteros.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

extern void func_vla(int rows, int cols, int array[rows][cols]);
extern void get_rows_cols(int *rows, int *cols);
extern void dump_array(const char *tag, int rows, int cols, int array[rows][cols]);

void func_vla(int rows, int cols, int array[rows][cols])
{
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            array[i][j] = (i + 1) * (j + 1);
        }
    }
}

int main(void)
{
    int rows, cols;

    get_rows_cols(&rows, &cols);

    int (*array)[cols] = malloc(rows * cols * sizeof(array[0][0]));
    /* error check omitted */

    func_vla(rows, cols, array);
    dump_array("After initialization", rows, cols, array);

    free(array);
    return 0;
}

void dump_array(const char *tag, int rows, int cols, int array[rows][cols])
{
    printf("%s (%dx%d):\n", tag, rows, cols);
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
            printf("%4d", array[i][j]);
        putchar('\n');
    }
}

void get_rows_cols(int *rows, int *cols)
{
    srand(time(0));           // Only acceptable because it is called once
    *rows = 5 + rand() % 10;
    *cols = 3 + rand() % 12;
}

(Ver srand(): ¿por qué llamarlo solo una vez? ).

Bart van Ingen Schenau avatar Oct 12 '2010 08:10 Bart van Ingen Schenau

La forma más sencilla de pasar una matriz 2D de longitud variable

La técnica más limpia tanto para C como para C++ es: pasar una matriz 2D como una matriz 1D y luego usarla como 2D dentro de la función.

#include <stdio.h>

void func(int row, int col, int* matrix){
    int i, j;
    for(i=0; i<row; i++){
        for(j=0; j<col; j++){
            printf("%d ", *(matrix + i*col + j)); // or better: printf("%d ", *matrix++);
        }
        printf("\n");
    }
}

int main(){
    int matrix[2][3] = { {0, 1, 2}, {3, 4, 5} };
    func(2, 3, matrix[0]);

    return 0;
}

Internamente, no importa cuántas dimensiones tenga una matriz, C/C++ siempre mantiene una matriz 1D. Y entonces, podemos pasar cualquier matriz multidimensional como esta.

Minhas Kamal avatar Jan 09 '2019 05:01 Minhas Kamal