Ver la versión completa : [Ayuda] Pasar matriz como argumento función en C
FlipFlopX
11/04/2010, 18:38
Hola famigos, me estoy peleando con una dichosa práctica en C:
Tengo que crear un módulo que implemente la entrada de datos del usuario e ir creando una matriz 3x3, en la que se pedira nodo inicial, nodo final y distancia entre nodos. Si meto nodo inicial 0, nodo final 2 y distancia 4, pues en el elemento [0][2] de la matriz se me guardará un 4.
He creado un subprograma que hace esto mismo:
1.//////FUNCION PEDIR DATOS
2.void pedir(int matriz[3][3]){
3.int i, j;
4.i=0;
5.j=0;
6.
7.
8. while (i!=-1){
9. printf("\nIntroduce nodo origen (-1 para salir): ");
10. scanf("%i",&i);
11.
12. if((i)!=(-1)){
13. printf("\nIntroduce nodo destino: ");
14. scanf("%i",&j);
15.
16.
17. printf("\nIntroduce peso: ");
18. scanf("%i",&matriz[i][j]);
19. printf("\n-----------------------------------------------------------");
20. }
21. }
22. }
Ahora en el programa funcional llamo a la matriz para introducir los datos
pedir(matriz[3][3]);
Y no me escribe nada en la matriz, cómo paso la matriz a la función¿?
Grasias
ZarkGhost
11/04/2010, 18:43
Si le pasas matriz[3][3] a la funcion , le estaras pasando el valor contenido en esa posicion de la matriz ya que cada [] resuelve un nivel de puntero.
Debes pasar "matriz" a secas, y recibir **matriz, que indica doble nivel de direccionamiento.
Uhm ahora mismo ando despistado pero creo que era algo así
pedir(**matriz);
Pero en ese caso no sabe el tamaño de la matriz, por lo que podrías ampliar la función añadiéndole el tamaño
pedir (**matriz, 3, 3);
De todos modos ya digo que lo estoy diciendo sin pensarlo mucho, que alguien me corrija si me equivoco (lo más probable)
EDIT: ¿ves? Zarghost va más encaminado que yo :D
FlipFlopX
11/04/2010, 18:48
Si le pasas matriz[3][3] a la funcion , le estaras pasando el valor contenido en esa posicion de la matriz ya que cada [] resuelve un nivel de puntero.
Debes pasar "matriz" a secas, y recibir **matriz, que indica doble nivel de direccionamiento.
Gracias, ya me funciona con pedir(matriz) pero no entiendo lo de doble nivel de direccionamiento, supongo que el procedimiento está mal declarado
SplinterGU
11/04/2010, 19:18
la sintaxis que pusiste -void pedir(int matriz[3][3])- es correcta, pero no funciona en todos los compiladores...
y con solo llamarla "pedir(matriz)" es suficiente...
Gracias, ya me funciona con pedir(matriz) pero no entiendo lo de doble nivel de direccionamiento, supongo que el procedimiento está mal declarado
El doble nivel de direccionamiento viene de que lo que se le pasa a la función es un puntero a un array de punteros. Es lo que te permite acceder a los datos usando dos índices. A mí también me costó comprender esto en su día. Verlo en un dibujo ayuda a aclarar ideas.
ZarkGhost
11/04/2010, 19:29
Demasiadas horas de laboratorio en la uni picando código inútil :P
Si funciona no te preocupes mas por ello, pero ya que me aburro y por si a alguien le interesa
Presupongo que utilizas matrices de tamaño prefijado, cuando declaras un array con tamaño fijo:
int array[5];
Lo que estas haciendo es crear una variable puntero que apunta a una porción de memoria que se ha reservado para 5 ints. Esto es:
array contiene un valor con la dirección donde esta la memoria. Si accedes a (*array) se resuelve un nivel de direccionamiento y accedes el primer valor del array, te puedes desplazas por el array resolviendo direcciones (*(array+salto)) aunque por simpleza se recomienda usar el método estándar array[x]. (Diferentes datos tienen diferente tamaño y varia entre plataformas)
Si declaras una matriz, int matriz[3][3]; estarás reservando otra variable puntero llamada matriz, que apunta a un vector de punteros, cada puntero apuntara a su respectivo espacio de memoria reservado para los ints que formaran la matriz. Esto es, doble nivel de direccionamiento.
Y para que me enrollo tanto!
Por si te apetece usar memoria dinámica tener claro como funciona esto viene bien :)
Seria, crear una variable int **matriz, a la cual se le asigna un puntero a un array de punteros:
int **matriz= malloc(sizeof(int*)*sizeX);
y después, o reservas un array de int para cada fila, o reservas todo junto (que vendrá a ser mas mejor)
int *memoria_matriz=malloc(sizeof(int)*sizeX*sizeY);
y ya solo seria recorrer el array de punteros a punteros de int, dándoles los valores correspondientes, esto es:
recorrer matriz[x] hasta sizeX asignando matriz[x]=&(memoria_matriz[x*sizeY]);
* resuelve nivel de dirección
& devuelve la dirección en memoria de un valor
En la declaración del procedimiento se pondría int **matriz para indicar que recibe un puntero a un doble direccionamiento de int.
Y para terminar, decir que para liberar memoria, habría que liberar el tocho de memoria (o cada fila, si se reservan por separado) y el array de punteros a punteros.
Lo que hace el tiempo libre :P espero que pueda ayudar a alguien.
FlipFlopX
11/04/2010, 22:10
Demasiadas horas de laboratorio en la uni picando código inútil :P
Si funciona no te preocupes mas por ello, pero ya que me aburro y por si a alguien le interesa
Presupongo que utilizas matrices de tamaño prefijado, cuando declaras un array con tamaño fijo:
int array[5];
Lo que estas haciendo es crear una variable puntero que apunta a una porción de memoria que se ha reservado para 5 ints. Esto es:
array contiene un valor con la dirección donde esta la memoria. Si accedes a (*array) se resuelve un nivel de direccionamiento y accedes el primer valor del array, te puedes desplazas por el array resolviendo direcciones (*(array+salto)) aunque por simpleza se recomienda usar el método estándar array[x]. (Diferentes datos tienen diferente tamaño y varia entre plataformas)
Si declaras una matriz, int matriz[3][3]; estarás reservando otra variable puntero llamada matriz, que apunta a un vector de punteros, cada puntero apuntara a su respectivo espacio de memoria reservado para los ints que formaran la matriz. Esto es, doble nivel de direccionamiento.
Y para que me enrollo tanto!
Por si te apetece usar memoria dinámica tener claro como funciona esto viene bien :)
Seria, crear una variable int **matriz, a la cual se le asigna un puntero a un array de punteros:
int **matriz= malloc(sizeof(int*)*sizeX);
y después, o reservas un array de int para cada fila, o reservas todo junto (que vendrá a ser mas mejor)
int *memoria_matriz=malloc(sizeof(int)*sizeX*sizeY);
y ya solo seria recorrer el array de punteros a punteros de int, dándoles los valores correspondientes, esto es:
recorrer matriz[x] hasta sizeX asignando matriz[x]=&(memoria_matriz[x*sizeY]);
* resuelve nivel de dirección
& devuelve la dirección en memoria de un valor
En la declaración del procedimiento se pondría int **matriz para indicar que recibe un puntero a un doble direccionamiento de int.
Y para terminar, decir que para liberar memoria, habría que liberar el tocho de memoria (o cada fila, si se reservan por separado) y el array de punteros a punteros.
Lo que hace el tiempo libre :P espero que pueda ayudar a alguien.
Yo por si las moscas me lo guardo en favoritos como memoria dinámica, gracias por la ayuda :brindis:
Añado que a las funciones (en C) se pasan los datos por copia a excepción de las arrays que se pasan por referencia.
Si la matriz es siempre del mismo tamaño creo que quedaria mejor crear un tipo para ella.
Powered by vBulletin® Version 4.2.5 Copyright © 2026 vBulletin Solutions Inc. All rights reserved.