Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Sicherer en 8 Septiembre 2017, 03:31 am



Título: Problema en C puntero a punteros.
Publicado por: Sicherer en 8 Septiembre 2017, 03:31 am
Buenas, como va?
 Soy nuevo en el foro y tenia una duda sobre Punteros a punteros en C.

 Tengo q hacer una struct matriz

typedef struct {
short filas,col;
int **matriz;
}Matriz;

Ahora, mi duda es la siguiente:
 ¿Es necesario reservar memoria? Si.
 ¿Como la reservo? (la idea del programa es que la matriz se dimensione por teclado y se autocomplete con srand()).
 ¿Las funciones a un puntero puntero, llevan * en el nombre?

Desde ya muchas gracias, y si podrian dar un ejemplo se agradece mucho! saludos y que sigan bien.


Título: Re: Problema en C puntero a punteros.
Publicado por: AlbertoBSD en 8 Septiembre 2017, 03:57 am
Tienes que definir como vas a trabajar. un Puntero de punteros tiene que tener una doble inicializacion, primero para definir cuantos apuntadores vas a tener y posteriormente Cada uno de esos apuntadores recien.

Puedes trabajar con un solo apuntador para toda la matriz

Código
  1. int *matriz;
  2.  
  3. matriz = calloc(filas*columnas,sizeof(int));
  4.  




Ejemplo completo con matriz de punteros y cada puntero a un arreglo de enteros.

Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<time.h>
  4.  
  5. #define MAGIC 354093428
  6.  
  7. typedef struct {
  8. short filas,col;
  9. int **matriz;
  10. }Matriz;
  11.  
  12. int main() {
  13. short filas = 10; // Aqui puedes capturar filas
  14. short col = 5; // Aqui puedes capturar filas
  15. srand(time(NULL)+ MAGIC);
  16. Matriz m;
  17. m.filas = filas;
  18. m.col = col;
  19. m.matriz =  calloc(m.filas,sizeof(int*));
  20. int i = 0,j;
  21. while(i < m.filas) {
  22. m.matriz[i] = calloc(m.col,sizeof(int));
  23. printf("File %2i:\t",i+1);
  24. j =0;
  25.  
  26. while(j < m.col) {
  27. m.matriz[i][j] = rand() % 1000;
  28. printf("[%3i]",m.matriz[i][j]);
  29. j++;
  30. }
  31. printf("\n");
  32. i++;
  33. }
  34. }


Título: Re: Problema en C puntero a punteros.
Publicado por: Sicherer en 14 Septiembre 2017, 00:46 am
Muchas gracias alberto! y una ultima pregunta (me marea como manejar los punteros cuando paso por referencia en una funcion)

en el caso que yo quiera generar la matriz a  travez de una matriz...

Código
  1. Matriz crearMatriz() {
  2.   Matriz *m;
  3.   printf("nº de filas?");
  4.   scanf("%d",m->filas);
  5.   printf("nº de cols?");
  6.   scanf("%d",m->cols);
  7.   m->matriz =  calloc(m.filas,sizeof(int*));
  8. int i = 0,j;
  9. while(i < m->filas) {
  10. m->matriz[i] = calloc(m->col,sizeof(int));
  11. printf("File %2i:\t",i+1);
  12. j =0;
  13.  
  14. while(j < m->col) {
  15. m->matriz[i][j] = rand() % 1000;
  16. printf("[%3i]",m->matriz[i][j]);
  17. j++;
  18. }
  19. printf("\n");
  20. i++;
  21. }
  22. return m;
  23. }
  24.  


o tengo que declararle la cantidad de memoria que usa en el main?


· Los códigos deben ir en etiquetas GeSHi
>aquí las reglas del foro (http://foro.elhacker.net/reglas.htm)
-Engel Lex


Título: Re: Problema en C puntero a punteros.
Publicado por: AlbertoBSD en 14 Septiembre 2017, 03:26 am
Puede quedar asi:

Código
  1. Matriz *crearMatriz();
  2.  
  3. int main() {
  4. Matriz *nueva = crearMatriz();
  5. }
  6.  
  7. Matriz *crearMatriz() {
  8.   Matriz *m;
  9.   m = calloc(1,sizeof(Matriz));
  10.   printf("nº de filas?");
  11.   scanf("%d",m->filas);
  12.   printf("nº de cols?");
  13.   scanf("%d",m->cols);
  14.   m->matriz =  calloc(m.filas,sizeof(int*));
  15. int i = 0,j;
  16. while(i < m->filas) {
  17. m->matriz[i] = calloc(m->col,sizeof(int));
  18. printf("File %2i:\t",i+1);
  19. j =0;
  20.  
  21. while(j < m->col) {
  22. m->matriz[i][j] = rand() % 1000;
  23. printf("[%3i]",m->matriz[i][j]);
  24. j++;
  25. }
  26. printf("\n");
  27. i++;
  28. }
  29. return m;
  30. }

Si la funcion crear Matriz devuelve un apauntador, este debe de tener el *antes del nombre tal como lo puse.


Asi mismo la funcion debe de reservar memoria para la Estructura de la matriz que vas a usar.

Saludos!


Título: Re: Problema en C puntero a punteros.
Publicado por: Tucho en 17 Septiembre 2017, 19:44 pm
Buenas, un par de detalles nomás sobre la respuesta de AlbertoBSD.

En las lineas 11 y 13, falta el & en los scanf.
Por otro lado, no veo por que utilizar calloc en lugar de malloc, es mas lento y de todos modos despues le asignas un valor a cada uno de los elemetos, asi que estaria de más inicializarlos en cero.

En la linea 14 es m->filas (dentro del calloc).

Es una buena practica además, castear lo que devuelve el malloc, si bien todo deberia funcionar igual, te devuelve un void* y lo estas igualando a un Matriz* por ejemplo en la linea 9. Te evitas que te joda el compilador. Otra practica muy recomendable (si no casi obligatoria) es corroborar que todo sale bien, si falla el primer calloc ya todo el resto te va a tirar segmentation fault por todos lados, un:
Código
  1. if(m==NULL){fprintf(stderr,"Error allocando, linea %d\n", __LINE__); exit(EXIT_FAILURE);}

te salva las papas (sobretodo en programas mas complejos.) O definir una funcion por ejemplo:
Código
  1. void *safe_malloc(int n, size_t size){
  2.       void *aux;
  3.       aux = calloc(n,size);
  4.       if(aux==NULL){
  5.             fprintf(stderr,"Error Allocando %d bytes", n*size);
  6.             exit(EXIT_FAILURE);
  7.       }
  8.       return aux;
  9. }

y despues simplemente en llamas a
Código
  1. safe_malloc(cantidad,sizeof(tipo));

Un saludo,
Tucho.


Título: Re: Problema en C puntero a punteros.
Publicado por: AlbertoBSD en 17 Septiembre 2017, 22:05 pm
Buenas practicas y muy recomendables tus observaciones.

Sobre el codigo yo solo copie el código que puso Sicherer, en mi propuesta no use scanf, de hecho casi no recomiendo usar scanf.

Saludos!


Título: Re: Problema en C puntero a punteros.
Publicado por: Sicherer en 29 Septiembre 2017, 00:07 am
Código:
matriz *crearMatriz() {
    matriz *m;
    int i=0,j;
    printf("Ingrese el num de filas.\n");
    scanf("%d",&m->filas);
    printf("Ingrese el num de filas.\n");
    scanf("%d",&m->col);
   
    m->matrix = (int**)malloc(sizeOf(int*));
    while(i<m->filas) {
        m->matrix[i] = (int*)malloc(sizeof(int));
        j = 0;
        while(j < m->col) {
            m->matrix[i][j] = (int*)malloc(sizeof(int));
            j++;
        }
       i++;
    }
}

intenté hacerlo con malloc, pero claramente no me salio, esto fue a lo que mas me acerqué..  :-\



Título: Re: Problema en C puntero a punteros.
Publicado por: AlbertoBSD en 29 Septiembre 2017, 00:37 am
Es una combinación de fgets y strtol

Código
  1. int numero;
  2. char *error = NULL;
  3. char buff_numero[20];
  4. fgets(buff_numero,18,stdin);
  5. numero = (int) strtol(buff_numero,error,10);
  6.  

Aun que otras formas como: fgets y sscanf

https://foro.elhacker.net/programacion_cc/fgets_para_enteros-t348368.0.html;msg1698285

Formas hay varias el problemas del scanf es que si le escribes una letra cunado capturas numeros el programa se cuelga y hace cosas raras.

Saludos!