elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Lista Genérica en c
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Lista Genérica en c  (Leído 3,531 veces)
elProfeta1979

Desconectado Desconectado

Mensajes: 9


Ver Perfil
Lista Genérica en c
« en: 10 Octubre 2014, 18:25 pm »

que les parece mi implementación?

Código:


typedef enum _TIPO
{

  INT = 0,
  FLOAT,
  STRING

} TIPO;

typedef struct _NODO_LISTA
{

  TIPO   tipo;

  int    dato_int;
  float  dato_float;

  char   *dato_s;

  struct NODO_LISTA *sig;

} NODO_LISTA;


typedef NODO_LISTA *ListaGenerica;

ListaGenerica LGListaVacia();

ListaGenerica LGApilarInt(ListaGenerica l, int var);

ListaGenerica LGApilarFloat(ListaGenerica l, float var);

ListaGenerica LGApilarString(ListaGenerica l, char* var);

void LGImprimirEnPantalla(ListaGenerica l);



--

Código:
#include <stdio.h>
#include "ListaGenerica.h"

ListaGenerica LGListaVacia()
{
  return NULL;
}

ListaGenerica LGApilarInt(ListaGenerica l, int var)
{
  ListaGenerica p;
  p = (ListaGenerica)malloc(sizeof(NODO_LISTA));
  p->dato_int = var;
  p->tipo = INT;

  if(l==NULL){
    p->sig = NULL;
  }else{
    p->sig = l;
  }

  return p;
}

ListaGenerica LGApilarFloat(ListaGenerica l, float var)
{
  ListaGenerica p;
  p = (ListaGenerica)malloc(sizeof(NODO_LISTA));
  p->dato_float = var;
  p->tipo = FLOAT;

  if(l==NULL){
    p->sig = NULL;
  }else{
    p->sig = l;
  }

  return p;
}

ListaGenerica LGApilarString(ListaGenerica l, char *var)
{
  ListaGenerica p;
  p = (ListaGenerica)malloc(sizeof(NODO_LISTA));
  p->dato_s = var;
  p->tipo = STRING;

  if(l==NULL){
    p->sig = NULL;
  }else{
    p->sig = l;
  }

  return p;
}

void LGImprimirEnPantalla(ListaGenerica l)
{
  putchar('[');
  while(l != NULL)
  {
    if(l->tipo==INT)
      printf("%d", l->dato_int);

    else if(l->tipo==FLOAT)
      printf("%f", l->dato_float);

    else if (l->tipo==STRING)
      printf("%s", l->dato_s);

    if (l->sig != NULL)
      printf(", ");

    l=l->sig;
  }
  putchar(']');
}



Código:
#include "ListaGenerica.h"

int main()
{
  ListaGenerica l;
  l = LGListaVacia();
  l = LGApilarInt(l, 2);
  l = LGApilarInt(l, 20);
  l = LGApilarInt(l, 21);
  l = LGApilarInt(l, 12);
  l = LGApilarInt(l, 22);
  l = LGApilarFloat(l, 42.41);
  l = LGApilarFloat(l, 242.41);
  l = LGApilarFloat(l, 342.41);
  l = LGApilarString(l, "Pila");
  l = LGApilarString(l, "Generica");
  l = LGApilarString(l, "Anno 2014");

  LGImprimirEnPantalla(l);

  return 0;
}



« Última modificación: 10 Octubre 2014, 18:28 pm por elProfeta1979 » En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Lista Genérica en c
« Respuesta #1 en: 11 Octubre 2014, 18:26 pm »

que les parece mi implementación?
Para empezar esta bien pero, como todo en programación, se puede mejorar.

Lo primero es eliminar el valor inicial de la enumeración ya que estas siempre empiezan con el valor cero, salvo una razón de peso se debe preferir el tipo double sobre el tipo float y evitar nombres en mayúsculas reservando estos para las macros y las constantes enumeradas.

Ademas:

* Los distintos tipos se pueden agrupar en una union:
Código
  1. #include <stdio.h>
  2.  
  3. enum tipo {INT, DOUBLE, STRING};
  4. typedef enum tipo Tipo;
  5.  
  6. struct nodo {
  7.   union {
  8.      int Int;
  9.      double Double;
  10.      char   *str;
  11.   } val;
  12.   Tipo tipo;
  13.  
  14.   struct nodo *sig;
  15. };
  16. typedef struct nodo Nodo;
  17.  
  18. typedef Nodo *Lista;

* En lugar de una función por cada tipo puedes utilizar una función con un numero variable de argumentos donde el ultimo argumento con nombre indica el tipo del valor, de esa forma cuando agregues tipos solo debes modificar las sentencias de selección y no crear tantas funciones.

Mas o menos así:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5.  
  6. enum tipo {INT, DOUBLE, STRING};
  7. typedef enum tipo Tipo;
  8.  
  9. struct nodo {
  10.   union {
  11.      int Int;
  12.      double Double;
  13.      char *String;
  14.   } val;
  15.   Tipo tipo;
  16.  
  17.   struct nodo *sig;
  18. };
  19. typedef struct nodo Nodo;
  20.  
  21. typedef Nodo *Lista;
  22.  
  23. /* ... */
  24.  
  25. Lista LG_Apilar(Lista lst, Tipo tipo, ...);
  26. void LG_Imprimir(FILE *out, Lista lst);
  27.  
  28. int main(void)
  29. {
  30.   Lista lst = NULL;
  31.  
  32.   lst = LG_Apilar(lst, INT, 1);
  33.   lst = LG_Apilar(lst, INT, 2);
  34.   lst = LG_Apilar(lst, INT, 3);
  35.  
  36.   lst = LG_Apilar(lst, DOUBLE, 1.2);
  37.   lst = LG_Apilar(lst, DOUBLE, 3.4);
  38.   lst = LG_Apilar(lst, DOUBLE, 5.6);
  39.  
  40.   lst = LG_Apilar(lst, STRING, "Hugo");
  41.   lst = LG_Apilar(lst, STRING, "Paco");
  42.   lst = LG_Apilar(lst, STRING, "Luis");
  43.  
  44.   LG_Imprimir(stdout, lst);
  45.  
  46.   return EXIT_SUCCESS;
  47. }
  48.  
  49. /* ... */
  50.  
  51. Lista LG_Apilar(Lista lst, Tipo tipo, ...)
  52. {
  53.   Lista nuevo;
  54.  
  55.   if ((nuevo = malloc(sizeof *nuevo)) != NULL){
  56.      char *str;
  57.      va_list ap;
  58.  
  59.      va_start(ap, tipo);
  60.      switch (tipo){
  61.      case INT:
  62.         nuevo->val.Int = va_arg(ap, int);
  63.         break;
  64.      case DOUBLE:
  65.         nuevo->val.Double = va_arg(ap, double);
  66.         break;
  67.      case STRING:
  68.         str = va_arg(ap, char *);
  69.         nuevo->val.String = malloc(strlen(str) + 1);
  70.         strcpy(nuevo->val.String, str);
  71.         break;
  72.      }
  73.      va_end(ap);
  74.  
  75.      nuevo->tipo = tipo;
  76.      nuevo->sig = lst;
  77.   }
  78.  
  79.   return nuevo;
  80. }
  81.  
  82. void LG_Imprimir(FILE *out, Lista p)
  83. {
  84.   while (p != NULL){
  85.      switch (p->tipo){
  86.      case INT:
  87.         fprintf(out, "%d", p->val.Int);
  88.         break;
  89.      case DOUBLE:
  90.         fprintf(out, "%.2f", p->val.Double);
  91.         break;
  92.      case STRING:
  93.         fprintf(out, "%s", p->val.String);
  94.         break;
  95.      }
  96.      fputc('\n', out);
  97.  
  98.      p = p->sig;
  99.   }
  100. }

En ambos programas faltan muchas cosas como una validación robusta y la liberación de la memoria antes de finalizar el programa.

Un saludo


En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
elProfeta1979

Desconectado Desconectado

Mensajes: 9


Ver Perfil
Re: Lista Genérica en c
« Respuesta #2 en: 13 Octubre 2014, 05:03 am »

ese código esta muy bueno!

pienso que las funciones que implementé tienen cierta ventaja a la hora de exportar el código a otro lenguaje.

validación robusta? no tengo idea que significa.

saludos
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Lista Genérica en c
« Respuesta #3 en: 13 Octubre 2014, 17:13 pm »

validación robusta? no tengo idea que significa.
Significa que se debe verificar que toda entrada este dentro de los parámetros esperados, por ejemplo ponte a pensar que pasara si a la función que crea un nodo se le pasa un valor que no es parte de la enumeración de tipos. También se debe verificar el resultado de toda función que pueda fallar (el mejor ejemplo es la lectura de datos de un archivo y las funciones de reserva de memoria).

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Descargar vídeos página genérica Tele 5? « 1 2 3 »
Multimedia
nichihack 25 26,161 Último mensaje 27 Abril 2013, 13:42 pm
por Senior++
GTX 650 TI para fuente genérica 500w.
Hardware
ScareWoW 3 4,423 Último mensaje 30 Diciembre 2013, 02:15 am
por 0x98364
Configuración genérica en Windows 7
Windows
senseye3led 0 1,821 Último mensaje 19 Diciembre 2015, 13:27 pm
por senseye3led
¿Es normal que una fuente real caliente más que una genérica?
Hardware
Br1ant 0 1,912 Último mensaje 24 Abril 2016, 10:59 am
por Br1ant
C# Parámetro Clase Genérica
.NET (C#, VB.NET, ASP)
Miseryk 4 3,494 Último mensaje 16 Noviembre 2016, 07:01 am
por Novlucker
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines