Pasar matriz bidimensional mediante puntero

¿Cómo paso la matriz m a foo ()? si no puedo cambiar el código o el prototipo de foo ()?

void foo(float **pm) { int i,j; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) printf("%f\n", pm[i][j]); } int main () { float m[4][4]; int i,j; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) m[i][j] = i+j; foo(???m???); } 

Si insiste en la statement anterior de foo , es decir,

 void foo(float **pm) 

y sobre el uso de una matriz 2D incorporada, es decir,

 float m[4][4]; 

entonces la única forma de hacer que tu foo trabaje con m es crear una matriz extra de “índice de fila” y pasarla en lugar de m

 ... float *m_rows[4] = { m[0], m[1], m[2], m[3] }; foo(m_rows); 

No hay forma de pasar de foo a foo directamente. Es imposible. El tipo de parámetro float ** es irremediablemente incompatible con el tipo de argumento float [4][4] .

Además, desde C99, lo anterior se puede express de una manera más compacta como

 foo((float *[]) { m[0], m[1], m[2], m[3] }); 

PD: Si miras detenidamente, verás que esto es básicamente lo mismo que Carl Norum sugirió en su respuesta. Excepto que Carl está malloc -ing la memoria de la matriz, que no es absolutamente necesaria.

Si no puede cambiar foo() , tendrá que cambiar m . Declararlo como float **m , y asignar la memoria apropiadamente. Luego llama a foo() . Algo como:

 float **m = malloc(4 * sizeof(float *)); int i, j; for (i = 0; i < 4; i++) { m[i] = malloc(4 * sizeof(float)); for (j = 0; j < 4; j++) { m[i][j] = i + j; } } 

¡No te olvides de free() después!

No puedes. m no es compatible con el argumento de foo . Tendría que usar una matriz temporal de punteros.

 int main() { float m[4][4]; int i,j; float *p[4]; p[0] = m[0]; p[1] = m[1]; p[2] = m[2]; p[3] = m[3]; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) m[i][j] = i+j; foo(p); 

Si tiene un comstackdor que admite C99, el estándar C actual, puede hacer esto:

 foo((float *[]){ m[0], m[1], m[2], m[3] }); 

(Tenga en cuenta que esto es exactamente lo mismo que la respuesta de AndreyT , excepto que renuncia a tener que nombrar la matriz temporal)

  • no es necesario realizar ningún cambio en el principal, pero su función funcionará correctamente si cambia el prototipo formal de su función a (* pm) [4] o pm [] [4] porque ** pm significa puntero a puntero de entero while (* pm) [4] o pm [] [4] significa puntero a poiner de 4 enteros.

    m aquí también es un puntero a puntero de 4 enteros y no puntero a puntero de enteros y, por lo tanto, no es compatible.

     #include void foo(float (*pm)[4]) { int i,j; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) printf("%f\n", pm[i][j]); } int main () { float m[4][4]; int i,j; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) m[i][j] = i+j; foo(m); } 

¿ foo(m) no funciona?

void foo(float **pm) es lo mismo que void foo(float *pm[]) que no es una matriz bidimensional de flotantes. Es un conjunto de float* . Ahora, esos float* pueden señalar matrices flotantes, pero eso es un asunto aparte.

 typedef float Float4[4]; void foo(Float4 *pm) { int i,j; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) printf("%f\n", pm[i][j]); } main() { Float4 m[4]; int i,j; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) m[i][j] = i+j; foo(m); return 0; } 

Usando C99 que soporta arreglos de tamaño de tiempo de ejecución, la siguiente es una manera posible de pasar una matriz de 2 dim:

 void foo(void *pm, int row, int col) { float (*m)[col] = pm; for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) printf("%4.1f%s", m[i][j], (j == col-1)?"\n":" "); } int main() { float m[4][4]; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) m[i][j] = i+j; foo(m, 4, 4); return 0; }