1

como andan? Tengo una duda respecto a los punteros en C. Estoy haciendo un ejercicio, el cual tengo que multiplicar dos matrices 2x2. No es tan dificil, solamente que estoy intentando hacerlo con punteros y se me complica la vida. Alguien podria explicarme que estoy haciendo mal? Gracias!!

Estos son algunos errores de los que me salta.

$gcc 2-Ejercicio.cpp 
2-Ejercicio.cpp: In function ‘int main()’:
2-Ejercicio.cpp:33:15: error: cannot convert ‘int (*)[2]’ to ‘int**’
   33 |   multiplicar(m1, m2, m3);
      |               ^~
      |               |
      |               int (*)[2]
2-Ejercicio.cpp:10:23: note:   initializing argument 1 of ‘void multiplicar(int**, int**, int**)’
   10 | void multiplicar(int *ma1[M], int *ma2[M], int *ma3[M]){
      |**                  ~~~~~^~~~~~

El problema empieza aca.

//(aa   ab)
//(ba   bb)

#include <stdio.h>
#define M 2

void multiplicar(int *ma1[M], int *ma2[M], int *ma3[M]){

  ma3[0][0] = ((ma1[0][0] * ma2[0][0]) + (ma1[0][1] * ma2[1][0]));
  ma3[0][1] = ((ma1[0][0] * ma2[0][1]) + (ma1[0][1] * ma2[1][1]));
  ma3[1][0] = ((ma1[1][0] * ma2[0][0]) + (ma1[1][1] * ma2[1][0]));
  ma3[1][1] = ((ma1[1][0] * ma2[0][1]) + (ma1[1][1] * ma2[1][1]));
}

void imprimir(int ma3[M][M]){
  for(int i = 0; i < M; i++){
    for(int j = 0; j < M; j++){
      printf("%d\t", ma3[i][j]);
    }
    printf("\n");
  }
}

int main(){

  int m1[M][M] = {{10, 11}, {12, 13}};
  int m2[M][M] = {{14, 15}, {16, 17}};
  int m3[M][M];

  multiplicar(m1, m2, m3);
  imprimir(m3);

  return 0;
}

3 respuestas 3

1

Como sabrás, en C los arreglos decaen en punteros. Por lo tanto, estas 2 declaraciones son similares:

int numeros[];
// Decae en
int *numeros;

Sin embargo, si quieres un puntero a un arreglo la sintaxis es la siguiente:

int matriz[][M];
// Decae en
int (*matriz)[M];

Sin los paréntesis tendrías un arreglo de punteros.

int *arregloDePunteros[M];

Si te resulta más cómodo de leer, puedes usar typedef para las filas o hacerlo mediante structs.

typedef int fila[M];
typedef fila matriz[M];

typedef struct {
    int elementos[M];
} Vector;

typedef struct {
    Vector columnas[M];
} Matriz;
1

En el parámetro de la función multiplicar se está pasando un array de punteros.

Cuando se llamó a la función dentro del main, se pasaron arrays de enteros a los parámetros y no punteros a punteros.

Cuando los parámetros de una función son punteros y al inicializar con valores usando variables, el compilador interpretará el valor de las variables como dirección de memoria, pero el valor en sí no apunta a ningún otro valor.

Para corregir, pasa puntero a puntero

 int main(){
      int m1[M][M] = {{10, 11}, {12, 13}};
      int m2[M][M] = {{14, 15}, {16, 17}};
      int m3[M][M];
    
       //Crear punteros
      int *puntero_m1[M];
      int *puntero_m2[M];
      int *puntero_m3[M];
       
     //En el LOOP se inicializan los punteros.
      for (int i = 0; i < M; i++) {
        puntero_m1[i] = m1[i];
        puntero_m2[i] = m2[i];
        puntero_m3[i] = m3[i];
      }
    
      multiplicar(puntero_m1, puntero_m2, puntero_m3);
    
      imprimir(m3);
    
      return 0;
    }
0

El principal problema es que punteros y arrays no son la misma cosa aunque a veces sean intercambiables y eso hace que resulte complicado usarlos a la vez.

El código siguiente muestra como acceder al array usando punteros:

#include <stdio.h>

#define N 2

int main () {
  int *p;
  int m[N][N] = {{10,20},{30,40}};
  p = (int *)m;

  printf ("%d\n", *(p + 2)); // *( p + 0 + 1 *N)
  printf ("%d\n", m[1][0]);
}

Los datos se almacenan de forma consecutiva en memoria y puedes acceder utilizado el operador [][] o calculando el offset desde el principio del array. De esta forma puedes pasar un puntero a tu array como parámetro a tu función y acceder a sus elementos calculando el offset correcto.

Cuando declaras int *m1[N] como en tu función, lo que estás declarando es un array de N punteros a int que no tienen nada que ver con el tipo original que pasas a tu función, y eso es lo que el compilador te está diciendo.

Si quisieras usar punteros para pasar los parámetros pero luego acceder a los datos como si fuera un array, tendrías que hacer algo como esto:

#include <stdio.h>

#define N 2
typedef int MATRIX[N][N];

int main () {
  int p[N*N] = {10, 20, 30, 40};
  MATRIX *m = (MATRIX*)&p;

  printf ("%d\n", *(p +2));
  printf ("%d\n", *m[0][1]);
}

Como puedes ver las declaraciones se vuelven engorrosas incluso tras utilizar un typedef.

Los arrays no los puedes modificar (o asignar valores si prefieres). Y tampoco se puede castear nada a un array, solo puede castear un puntero a un puntero a un array de un determinado tipo (como hicimos en el segundo fragmento de código).

Si lo intentas el compilador simplemente no te deja:

MATRIX m = (MATRIX)p;

Produce el siguiente error:

c.c: In function ‘main’:
c.c:8:14: error: cast specifies array type
    8 |   MATRIX m = (MATRIX)p;
      |              ^
c.c: In function ‘main’:
c.c:8:14: error: cast specifies array type
    8 |   MATRIX m = (MATRIX)p;
      |              ^

¿No es la respuesta que buscas? Examina otras preguntas con la etiqueta o formula tu propia pregunta.