Matriz como argumento de una función en C

Estoy atascado en lo más básico. No es tarea, solo estoy presentando el problema de una manera simplista.

Necesito una función de impresión matricial, y la matriz se pasa como un argumento junto con la información de filas y colores. La matriz se asigna en la stack.

En la función prototipo mencionada a continuación, MAT_COL es un tiempo de comstackción definido.

void matrix_print(uint8_t (*mat)[MAT_COL], int row, int col) 

e imprimir elementos de matriz como

 print mat[i_row][i_col]; 

El enfoque no funcionará si tengo varias matrices con diferentes tamaños i, e “MAT_COL” ya no está disponible.

Una posible salida sería

 void matrix_print(uint8_t *in_mat, int row, int col) { uint8_t (*mat)[col] = in_mat; // typecast "col" is an arg // access them as eariler print mat[i_row][i_col]; } 

¿Algún problema con este enfoque? ¿Cuál es la solución estándar a este problema en C ?

C99 admite la siguiente forma de statement de función:

 void matrix_print(int row, int col, uint8_t in_mat[row][col]) 

Creo que podrías ir por una estructura para ayudarte con el manejo del tipo. Si el tipo es relevante para su diseño, debe hacerlo explícito.

La siguiente es una versión de Ansi-C desde que escribió C / C ++ como una etiqueta. En C ++ harías de tu matriz una clase.

 typedef struct { int * data; int IsAllocated; unsigned row_max; unsigned col_max; } Matrix; void Matrix_construct(Matrix * m, int cols, int rows); void Matrix_destruct(Matrix * m, int cols, int rows); static int Private_GetElement(Matrix * m, unsigned col, unsigned row, int * element); void Matrix_print(Matrix * m); void Matrix_construct(Matrix * m, int cols, int rows) { m->col_max = cols; m->row_max = rows; m->data = (int*) malloc(sizeof(int) * cols * rows); m->IsAllocated = 1; } void Matrix_destruct(Matrix * m, int cols, int rows) { m->col_max = 0; m->row_max = 0; if(m->IsAllocated) { free(m->data); m->IsAllocated = 0; } } static int Private_GetElement(Matrix * m, unsigned col, unsigned row, int * element) { int e = 0; if(m && element && col < m->col_max && row < m->row_max && m->IsAllocated) { *element = m->data[col + row * m->col_max]; } else { e |= 1; } return e; } void Matrix_print(Matrix * m) { unsigned col, row; int element; for( col = 0; col < m->col_max; ++col) { for( row = 0; row < m->row_max; ++row) { if(!Private_GetElement(m, col, row, &element)) { printf("%i", element); } } printf("\n"); } } 

Si asigna diferentes tamaños en Matrix_construct la impresión aún funcionará ya que Matrix_print utiliza los valores máximos que se almacenan en la estructura.

El uso de diferentes tamaños llevaría a cambiar la estructura en el ejemplo anterior, Matrix_print aún debería funcionar como se esperaba.


EDITAR:

El ejemplo fue editado para mostrar cómo se vería la asignación dinámica de tamaños variables.

He hecho una solución “definitiva” a este problema en gcc C11 / C99 usando estos enlaces:

http://c-faq.com/aryptr/dynmuldimary.html

http://c-faq.com/aryptr/ary2dfunc3.html

 //compile with gcc --std=c11 program.c #include  #include  #define MV(array, ncolumns, i, j) array[i * ncolumns + j] #define MX 9 #define MY 14 void input_matrix(int row, int column, double matrix[row][column]); void print_matrix(int row, int column, double matrix[row][column]); int main() { int i=MX, j=MY; printf("Generate input values and print matrices with functions fn(int w, int k, double matrix[w][k]) (in C99 and C11)\n"); double matrix1[i][j]; input_matrix(MX,MY,matrix1); printf("matrix static\n"); print_matrix(MX,MY,matrix1); double **matrix2; matrix2=malloc(MX*sizeof(double*)); matrix2[0] = (double *)malloc(MX*MY*sizeof(double)); for(i = 1; i < MX; i++) matrix2[i] = matrix2[0]+i*MY; input_matrix(MX,MY,(double (*)[])(*matrix2)); printf("matrix two times allocated one for pointers, the second for data (double (*)[])(m[0])\n"); print_matrix(MX,MY,(double (*)[])(matrix2[0])); free(*matrix2); free(matrix2); double *matrix3; matrix3=malloc(MX*MY*sizeof(double)); input_matrix(MX,MY,(double (*)[])matrix3); printf("matrix alocated as twodimensional array\n"); print_matrix(MX,MY,(double (*)[])matrix3); free(matrix3); j=MY; double (*matrix4)[j]; matrix4 = (double (*)[])malloc(MX * sizeof(*matrix4)); input_matrix(MX,MY,matrix4); printf("matrix alocated as an array of pointers to arrays m = (double (*)[])malloc(MX * sizeof(*m))\n"); print_matrix(MX,MY,matrix4); free(matrix4); printf("\nThe End!\n"); return 0; } void input_matrix(int row, int column, double matrix[row][column]){ for(int i=0; i 

uint8_t su uint8_t de caracteres de un int a un uint8_t por lo que lo siguiente debería funcionar.

 void matrix_print(uint8_t *in_mat, int row, int col) { uint8_t (*mat)[col] = (uint8_t (*)[col])in_mat; // access them like mat[y][x]; } 

Pero si está tratando de evitar las tipografías cuando están disponibles (lo que puede o no ser una buena práctica), podría implementarlo con compensaciones como esas.

 void matrix_print(uint8_t *in_mat, int row, int col) { // access them like mat[x + y*col]; }