Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: h0oke en 20 Mayo 2010, 23:32 pm



Título: [C] - Duda estructuras
Publicado por: h0oke en 20 Mayo 2010, 23:32 pm
¿Cuál es el método utilizado en C para el ingreso de una estructura de datos? Me refiero a que si se deben leer las variables de la estructura por apartey luego asignarlas a los miembros de la esctructura... o bien, si se deben asignar directamente a cada miembro de la esctructura luego de un scanf().


Título: Re: [C] - Duda estructuras
Publicado por: nicolasblues86 en 20 Mayo 2010, 23:37 pm
no entiendo bien la pregunta pero bueno te pongo un ejemplo de uso de estrocturas en c que tenía por ahí tirado

Código
  1. #include <stdio.h>
  2.  
  3.  
  4. struct Ficha {
  5.  
  6. char Nombre[80];
  7. int  Num_unidades;
  8. int Precio_unidad;
  9. int Estado;   // 0 = moroso; 1 = atrasado; 2 = pagado
  10. };
  11.  
  12.  
  13. typedef struct Ficha Fichas;
  14.  
  15.  
  16. int main(int argc, char** argv)
  17. {
  18. Fichas Cliente[100];
  19. int i;
  20. char nombre[80];
  21.  
  22. for (i = 0; i < 99; i++)
  23. {
  24. if (nombre == Cliente[i].Nombre)
  25. {
  26. printf ("%s", Cliente[i].Nombre);
  27. printf ("%i", Cliente[i].Num_unidades);
  28. printf ("%i", Cliente[i].Precio_unidad);
  29. switch  (Cliente[i].Estado)
  30. {
  31. case 0 : printf ("Moroso");
  32.  break;
  33. case 1 : printf ("Atrasado");
  34.  break;
  35. case 2 : printf ("Pagado");
  36.  break;
  37. };
  38.    }
  39. }
  40.  
  41.  
  42. return 0;
  43. }
  44.  
  45.  
  46.  
  47.  
  48.  








Saludos!!


Título: Re: [C] - Duda estructuras
Publicado por: h0oke en 20 Mayo 2010, 23:46 pm
Me refiero a las asignaciones:

Código
  1. //Suponemos la esctructura
  2. struct Ficha {
  3.  
  4. char Nombre[80];
  5. int  Num_unidades;
  6. int Precio_unidad;
  7. int Estado;   // 0 = moroso; 1 = atrasado; 2 = pagado
  8. };
  9. ...
  10. //Es esta la forma de asignacion?
  11. int num, int pre;
  12. Ficha F;
  13. scanf("%d",&num);
  14. scanf("%d",&pre);
  15. F.Num_Unidades = num;
  16. F.Precio_Unidad = pre;
  17. ...
  18. /* O lo correcto seria que en el scanf haga una asignación directa?*/
  19.  


Título: Re: [C] - Duda estructuras
Publicado por: nicolasblues86 en 20 Mayo 2010, 23:54 pm
seee.. lo podes hacer tanto así como directamente en el scanf


Código
  1.  
  2. scanf ("%d" &f.numero);
  3.  
  4.  

o si nosotros pasamos por referencia el struct se haria

Código
  1.  
  2. void ejemplo ( struct nom_del_struct *p )
  3.  
  4. scanf ("%d" &p->numero);
  5.  
  6.  

osea se utilaza  "->" en vez de de "."

saludos!!


Título: Re: [C] - Duda estructuras
Publicado por: .:BlackCoder:. en 20 Mayo 2010, 23:55 pm
Weno como no son clases... ni POO lo puedes hacer directamente... pero en la POO no es recomendable... Tu sabes para que no aya acceso directo con los miembros privados...

Saludos...

EDITO: aya xD!! va con 'h'... sorry


Título: Re: [C] - Duda estructuras
Publicado por: h0oke en 21 Mayo 2010, 00:06 am
Exacto a eso último me refería.

OFFTOPIC : Para que no hallan creo que es lo correcto  :xD


Título: Re: [C] - Duda estructuras
Publicado por: @synthesize en 21 Mayo 2010, 02:01 am
Para acceder o asignar a una variable normal dentro de una estructura:
Código
  1. estructura.elemento;
  2.  

Para acceder o asignar a un puntero, dentro de una estructura:

Código
  1. estructura->puntero;


También te recomiendo declarar las estructuras como typedef:

Código
  1. typedef struct Nodo
  2. {
  3.     elementos...
  4. };
  5.  


Título: Re: [C] - Duda estructuras
Publicado por: h0oke en 21 Mayo 2010, 03:19 am
Gracias por la aclaración, pero no me refería a eso.


Título: Re: [C] - Duda estructuras
Publicado por: h0oke en 21 Mayo 2010, 17:03 pm
Miren el siguiente code:

Código
  1. #include <stdlib.h>
  2. #include <string.h>
  3.  
  4. #define MAX_LIMIT 50
  5.  
  6. struct Persona{
  7.  char *nom, *dom, *tel;
  8.  int edad;  
  9. };
  10.  
  11. typedef struct Persona stPersona;
  12.  
  13. void _ingreso(stPersona *);
  14. void _imprimir(stPersona *);
  15.  
  16. int main()
  17. {
  18.  stPersona *User;
  19.  //Aqui creo que deberia reservar el espacio para User
  20.  _ingreso(User);
  21.  _imprimir(User);
  22.  
  23.  return 0;
  24. }
  25.  
  26. void _ingreso(stPersona *stP)
  27. {
  28.  char *nom;
  29.  nom = (char *)(malloc((MAX_LIMIT)*sizeof(char)));
  30.  stP = (stPersona *)(malloc(sizeof(stPersona)));
  31.  stP->nom = (char *)(malloc((MAX_LIMIT)*sizeof(char)));
  32.  fgets(nom,MAX_LIMIT,stdin);
  33.  strcpy(stP->nom,nom);
  34. }
  35.  
  36. void _imprimir(stPersona *stP)
  37. {
  38.  puts("------SALIDA------");
  39.  puts(stP->nom);
  40. }

¿Por qué se produce un error de segmentación en la salida?

EDITADO : Si reservo espacio para User, y luego utilizo printf("%s") la salida es (null).


Título: Re: [C] - Duda estructuras
Publicado por: Littlehorse en 21 Mayo 2010, 18:33 pm
Es que reservas memoria utilizando el puntero stP pero dicho puntero deja de existir cuando termina el contexto de la función. User no apunta al contenido adecuado cuando se lo pasas a _imprimir y ademas cuando sales de _ingresar pierdes la referencia para liberar la memoria que reservaste.

Saludos.

PD: Necesitas incluir stdio.h para stdin.


Título: Re: [C] - Duda estructuras
Publicado por: h0oke en 21 Mayo 2010, 21:03 pm
Disculpas por el stdio.h olvidé copiarlo

Ahora bien, no me queda otra opción que la siguiente?

Código
  1. int main()
  2. {
  3.  stPersona *User;  
  4.  User = (stPersona *)(malloc(sizeof(stPersona)));
  5.  User->nom = (char *)(malloc(sizeof(char) * MAX_LIMIT));
  6.  
  7.  _ingreso(User);
  8.  printf("%s\n",User->nom);
  9.  
  10.  return 0;
  11. }
  12.  
  13. void _ingreso(stPersona *P)
  14. {
  15.  puts("Ingrese nombre>");
  16.  fgets(P->nom,MAX_LIMIT,stdin);
  17. }

Lo que quedaría destacar es que para manipular estructuras(en realidad en todos los casos creo), hay que reservar la memoria antes de llamar a una función(procedimiento en este caso)?


Título: Re: [C] - Duda estructuras
Publicado por: h0oke en 21 Mayo 2010, 21:29 pm
Se me ocurrió lo siguiente para no estar reservando memoria a cada instante:
Código
  1. int main(){
  2.  st_p *user;
  3.  
  4.  data_reserve(&user);
  5.  data_input(user);
  6.  
  7.  printf("Nombre : %s", user->name);
  8. }
  9.  
  10. void data_reserve(st_p **P){
  11.  (*P) = (st_p *)(malloc(sizeof(st_p)));
  12.  (*P)->name = (char *)(malloc(sizeof(char) * LIMIT));
  13.  (*P)->dir = (char *)(malloc(sizeof(char) * LIMIT));
  14.  (*P)->phone = (char *)(malloc(sizeof(char) * LIMIT));
  15. }
  16.  
  17. void data_input(st_p *P){
  18.  puts("Ingrese nombre");
  19.  fgets(P->name, LIMIT, stdin);
  20. }


Título: Re: [C] - Duda estructuras
Publicado por: Littlehorse en 21 Mayo 2010, 21:30 pm
No hay una regla estricta para lo que quieres hacer ya que depende de la organización del programa, de su objetivo y de los datos que vayas a manejar.

Es decir, si la pregunta viene por el lado de "Que me conviene hacer" te puedo responder, pero si lo que estas preguntando es "Que opciones tengo" la respuesta es que solo lo que tus conocimientos y tu imaginación te permitan.
Uno de los grandes atributos de la memoria dinámica y los punteros es la flexibilidad y la versatilidad por lo tanto ten por seguro que tendrás muchas opciones dependiendo como encares la situación.

Para que te des una idea, una función podría devolver la referencia de la estructura manipulada -stPersona * func(params)- y dicha referencia la puedes recibir con un puntero en main. Las posibilidades utilizando los elementos mencionados son interminables.

Saludos

Advertencia - mientras estabas escribiendo, una nueva respuesta fue publicada. Probablemente desees revisar tu mensaje.

No hagas doble post por favor, usa el botón modificar.

Edit:
No leí el código atentamente pero la idea se ve a simple vista. Efectivamente, suele ser una buena practica hacer una función que se encargue de la reserva de memoria de determinado tipo de estructura, en pos que los cambios sean mas fáciles de realizar en caso que los elementos de la estructura cambien en el futuro.


Título: Re: [C] - Duda estructuras
Publicado por: h0oke en 21 Mayo 2010, 21:40 pm
Gracias littlehorse. Sobre las recomendaciones, sólo necesito opiniones, porque aveces hay estándares los cuales permiten un mejor entendimiento del programa. Ahora bien, por ejemplo me gustaría ver algunos sources de grandes programas, para ver su organización y demás.

Conoces algún libro que trate sobre practicas sanas en C/C++? Aparte de las que estoy leyendo del libro de deitel&deitel?

EDIT: Existe alguna forma para saber si una puntero fue liberado correctamente con free()?
EDIT2: Creo que la forma sería que si utilizo el free(), entonces la información en mi puntero quedará en NULL.
EDIT3: En el caso que quiera manipular una gran cantidad de usuarios, en vez de un array de estructuras lo correcto sería utilizar una lista enlazada, verdad?


Título: Re: [C] - Duda estructuras
Publicado por: Littlehorse en 21 Mayo 2010, 22:34 pm
Citar
Existe alguna forma para saber si una puntero fue liberado correctamente con free()?

Lo ideal es inicializar los punteros, trabajar con ellos, y luego volver al valor inicial cuando no los necesites. Por supuesto esa es la forma mas fácil, pero también es la mas sencilla y mas efectiva en el común de los casos:

Código
  1. free(ptr);
  2. ptr=NULL;
  3.  

Entonces podrás comprobar fácilmente en cualquier contexto del programa si los punteros son validos o no.

dangling pointers C (http://www.google.com.ar/#hl=es&source=hp&q=dangling+pointers+C&aq=f&aqi=g10&aql=&oq=&gs_rfai=&fp=8a54748c72dc742d)
wild pointers C (http://www.google.com.ar/#hl=es&safe=off&q=wild+pointers+C&aq=&aqi=&aql=&oq=&gs_rfai=&fp=776e7a30c205b67)

Citar
En el caso que quiera manipular una gran cantidad de usuarios, en vez de un array de estructuras lo correcto sería utilizar una lista enlazada, verdad?

Podría ser, depende como sea la estructura del programa. Lo importante es tener en cuenta que siempre que necesites insertar y/o borrar datos una lista va a tener mejor rendimiento que un arreglo -por mas que tengamos en contra las llamadas para reservar memoria-. Por el contrario el acceso es bastante mas rápido en un array.

Citar
Conoces algún libro que trate sobre practicas sanas en C/C++? Aparte de las que estoy leyendo del libro de deitel&deitel?

La verdad en este momento no me acuerdo de ninguno. Ahora reviso a ver si encuentro algo en el HD externo.