Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: sherry_XD en 21 Abril 2014, 02:55 am



Título: Matrices con punteros
Publicado por: sherry_XD en 21 Abril 2014, 02:55 am
Hola, estoy haciendo una funcion que multiplica dos matrices de orden n;
como he leido, para enviar como parametro una matriz es necesario indicar
el indice de la columna.
Ejemplo:
Código
  1. void multiplicacion(float M1[][2], float M2[][2],float M3[][2],int n){
  2.   //cosas
  3. }
  4.  

Sin embargo, la idea es que este valor sea variable, por lo que no sabria el valor que deberia ir ahi. Al parecer la solucion seria utilizar punteros ._____. La verdad es que no se mucho de punteros, o en realidad no se manejarlos .-.
Mi programa ,sin los punteros es este:
Código
  1. void multiplicacion(float M1[][2], float M2[][2],float M3[][2],int n){
  2.     int i,j,k;
  3.    float a,b;
  4.    for (i=0;i < n; i++){
  5.        for (j=0; j < n; j++){
  6.             M3[i][j] = 0.0;
  7.            for(k=0; k < n; k++){  
  8.                 a= M1[i][k];
  9.                b= M2[k][j];
  10.                M3[i][j] +=( a*b);
  11.             }
  12.                 printf("%f  ", M3[i][j]);
  13.         }
  14.         printf("\n");
  15.     }  
  16. }
  17. int main(){
  18.     int i,j;
  19.     float M1[2][2]= { {2.0,3.0},
  20.                     {2.0,3.0} };
  21.    float M2[2][2]= { {3.0,2.0},
  22.                     {3.0,2.0} };
  23.    float M3[2][2];
  24.        multiplicacion(M1,M2,M3,2);
  25.    for (i=0 ; i < 2 ; i++){
  26.        for (j=0; j< 2 ; j++){
  27.            printf("%f  ", M3[i][j]);
  28.        }
  29.        printf("\n");
  30.    }
  31.    return 0;
  32. }
  33.  

Por favor, alguien que me diga como deberia quedar con punteros.
Se que la funcion deberia recibir los parametros asi:

Código
  1. void multiplicacion(float **M1, float **M2,float **M3,int n){
  2.     // cosas
  3. }
  4.  



Título: Re: Matrices con punteros
Publicado por: xiruko en 21 Abril 2014, 03:17 am
Se que la funcion deberia recibir los parametros asi:
Código
  1. void multiplicacion(float **M1, float **M2,float **M3,int n){
  2.     // cosas
  3. }

Prueba a poner ese prototipo y corre tu programa. Te llevarás una sorpresa.

Saludos.


Título: Re: Matrices con punteros
Publicado por: sherry_XD en 21 Abril 2014, 03:36 am
Hola, primero gracias por responder :D!

Probe asi como me dijiste pero me tira muchas warnings, que dicen basicamente que el tipo de puntero es incompatible, y al ejecutarlo, me dice violacion de segmento ('core' generado)

Me ayudas please  :huh:  :huh:


Título: Re: Matrices con punteros
Publicado por: eferion en 21 Abril 2014, 09:14 am
Si quieres que las matrices sean de tamaño variable tienes dos opciones:

opción 1: Añades a la firma de la función un par "filas-columnas" por cada una de las 3 matrices ( o bien asumes que la matriz donde almacenas el resultado va a tener el tamaño correcto )

Código
  1. void multiplicacion(float **M1, int filasM1, int colsM1, float **M2, int filasM2, int colsM2, float **M3, int filasM3, int colsM3 );

opción 2: Creas una estructura para facilitar la gestión de las matrices y así te aseguras que las dimensiones de cada matriz viajan siempre junto a la matriz:

Código
  1. typedef struct
  2. {
  3.  float** datos;
  4.  int filas;
  5.  int columnas;
  6. } Matriz;
  7.  
  8. void multiplicacion( Matriz* M1, Matriz* M2, Matriz* M3 )
  9. {
  10.  int i,j,k;
  11.  float a,b;
  12.  
  13.  // Se comprueba que las matrices se puedan multiplicar ( falta comprobar M3 )
  14.  if ( M1->columnas != M2->filas )
  15.    return;
  16.  
  17.  for (i=0; i < M3->filas; i++)
  18.  {
  19.    for (j=0; j < M3->columnas; j++)
  20.    {
  21.      M3->datos[ i ][ j ] = 0.0;
  22.      for(k=0; k < M1->columnas; k++)
  23.      {  
  24.        a = M1->datos[ i ][ k ];
  25.        b = M2->datos[ k ][ j ];
  26.        M3->datos[ i ][ j ] += ( a * b );
  27.      }
  28.    printf( "%f  ", M3[ i ][ j ] );
  29.  }
  30.  printf( "\n" );
  31. }

Obviamente, en este caso, las matrices son dinámicas, por lo que tendrás que reservar la memoria necesaria para poder construir las matrices... en este caso lo recomendable es crear una función que permita inicializar dichas matrices y otra para liberar la memoria:

Código
  1.  
  2. void EliminarMatriz( Matriz* m )
  3. {
  4.  if ( m->filas > 0 && m->columnas > 0 )
  5.  {
  6.    int i;
  7.    for ( i = 0; i < m->filas; i++ )
  8.      free( m->datos[ i ];
  9.  
  10.    free( m->datos );
  11.  }
  12.  
  13.  m->filas = 0;
  14.  m->columnas = 0;
  15.  m->datos = 0;
  16. }
  17.  
  18. void InicializarMatriz( Matriz* m, int filas, int columnas )
  19. {
  20.  if ( filas == 0 || columnas == 0 )
  21.  {
  22.    filas = 0;
  23.    columnas = 0;
  24.  }
  25.  
  26.  m->filas = filas;
  27.  m->columnas = columnas;
  28.  
  29.  if ( filas > 0 )
  30.  {
  31.    matriz.datos = (float**)calloc( filas, sizeof( float* ) );
  32.  
  33.    int i;
  34.    for ( i = 0; i < filas; i++ )
  35.      matriz.datos[ i ] = (float*)calloc( columnas, sizeof( float ) );
  36.  }
  37. }

Con estas funciones auxiliares, la creación y eliminación de matrices se convierte en algo trivial.