• Domingo 22 de Diciembre de 2024, 12:26

Autor Tema:  Punteros A Funcion  (Leído 1620 veces)

Rombus

  • Miembro MUY activo
  • ***
  • Mensajes: 105
  • Nacionalidad: ar
    • Ver Perfil
    • http://myspace.com/punkrecycle
Punteros A Funcion
« en: Sábado 18 de Octubre de 2008, 17:39 »
0
Hola gente!

estoy realizando una estructura generica de lista (sigo con mis estructuras genercias XD) y estoy teniendo un problema a la hora de implementar una funcion insertaOrdenado(); que lo que debe hacer es , justamente, insertar nodos de manera ordenada segun el campo a comparar que se le sea especificado con un puntero a funcion.


el codigo con el problema aislado es el siguiente, esta completo para poder probarlo directamente:

Código: C
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4. #include <string.h>
  5. #define FALSE 0
  6. #define TRUE !FALSE
  7. typedef char boolean;
  8. typedef int (*list_funCmp_t)(void *a, void *b);
  9. typedef void (*list_funPrint_t)(void *a);
  10.  
  11. #define INT 0
  12. /*
  13. #define STRING 0
  14. #define CHAR 0
  15. */
  16.  
  17. typedef struct lPtr{
  18.     void *valor;
  19.     struct lPtr *next;
  20. }list_t;
  21.  
  22. typedef struct{
  23.     list_t *entrada;    //Entrada a la lista;
  24.     int sizeTipo;
  25.     list_funCmp_t funCmp;
  26.     list_funPrint_t funPrint;
  27. }listAdm_t;
  28.  
  29.  
  30. ///Funciones de COMPARACION---------------------------------------///
  31. int comparaEnteros(void *a, void *b){
  32.     return *(int *)a - *(int *)b;
  33. }
  34. int comparaCadenas(void *a, void *b){
  35.     return ((int)strcpy((char *)a, (char*)b));  //0 si son iguales, > 1 si b < a; < 1 si a < b
  36. }
  37.  
  38. ///Funciones de IMPRESION----------------------------------------///
  39. void imprimeEnteros(void *a){
  40.     printf("%d",*(int *)a);
  41. }
  42. void imprimeCadenas(void *a){
  43.     printf("%s",(char *)a);
  44. }
  45.  
  46. ///Servicios de LISTA
  47. listAdm_t *lAdmCreate(int sizeTipo, list_funCmp_t funCmp, list_funPrint_t funPrint){    //Crea La estructura administrativa
  48.     listAdm_t *listAdm = (listAdm_t *)malloc(sizeof(listAdm_t));
  49.     assert(listAdm);
  50.  
  51.     listAdm->funCmp = funCmp;
  52.     listAdm->funPrint = funPrint;
  53.  
  54.     listAdm->sizeTipo = sizeTipo;
  55.     listAdm->entrada = NULL;
  56.  
  57.     return listAdm;
  58. }
  59. list_t *creaNodo(listAdm_t *lista, list_t *pNext, void *elemento){  //necesito la estructura administrativa para el peso de dato
  60.     list_t *nodo = (list_t *)malloc(sizeof(list_t));
  61.     assert(nodo);
  62.  
  63.     nodo->valor = malloc(lista->sizeTipo);      assert(nodo->valor);
  64.     nodo->next = pNext;
  65.     memcpy((char *)nodo->valor, (char *)elemento, lista->sizeTipo);
  66.  
  67.     return nodo;
  68. }
  69. list_t *lInsertOrdered(listAdm_t *listAdm, list_t *lista, void *elemento){  //Ordenado de menor a mayor
  70.     if( !lista || (listAdm->funCmp(lista->valor,elemento)) >= 0  ){
  71.         return creaNodo(listAdm, listAdm->entrada, elemento);
  72.     }
  73.     lista->next = lInsertOrdered(listAdm, lista->next, elemento);
  74.     return lista;
  75. }
  76. void printList(listAdm_t *listAdm, list_t *list){
  77.     if(list){   //Si existe la lista
  78.         listAdm->funPrint(list->valor);
  79.         printf(" - ");
  80.         printList(listAdm, list->next);
  81.     }
  82. }
  83.  
  84. int main(void){
  85.     #ifdef STRING
  86.         char i[50] = "iber", b[50] = "jose";
  87.         listAdm_t *lista = lAdmCreate(sizeof(i), comparaCadenas,imprimeCadenas);
  88.     #endif
  89.     #ifdef CHAR
  90.         char i = 'a', b = 'g';
  91.         listAdm_t *lista = lAdmCreate(sizeof(char), comparaCaracteres,imprimeCaracteres);
  92.     #endif
  93.     #ifdef INT
  94.         int i= 6, b = 9;
  95.         listAdm_t *lista = lAdmCreate(sizeof(int), comparaEnteros,imprimeEnteros);
  96.         printf("hellon");
  97.     #endif
  98.  
  99.     lista->entrada = lInsertOrdered(lista, lista->entrada, (void *)&i);
  100.     lista->entrada = lInsertOrdered(lista, lista->entrada, (void *)&b);
  101.  
  102.     printList(lista, lista->entrada);
  103.     return 0;
  104. }
  105.  

tiene un par de ifndefs para realizarle distintas pruebas con los diferentes tipos de datos y verificar que en verdad sea generica.
ahora lo que pasa es q se queda iterando hasta un segmentation fault en el ciclo de impresion, antes habia logrado que funcione correctamente la inserta ordenado pero solo lo hacia con int's (poco generico q digamos XD).

esca esta la funcion problematica (tambien esta en el codigo anterior pero para que se vea mas directo)
Código: C
  1. list_t *lInsertOrdered(listAdm_t *listAdm, list_t *lista, void *elemento){  //Ordenado de menor a mayor
  2.     if( !lista || (listAdm->funCmp(lista->valor,elemento)) >= 0  ){
  3.         return creaNodo(listAdm, listAdm->entrada, elemento);
  4.     }
  5.     lista->next = lInsertOrdered(listAdm, lista->next, elemento);
  6.     return lista;
  7. }
  8.  

la logica creo q esta bien.
si no tengo lista, o si el valor es menor al que tengo en la lista inserto a la cabeza, sino llamo recursivamente a la funcion pasandole el siguiente elemento de la lista.


estoy dandole vueltas al codigo pero no logro decifrar el error.

espero sus comentarios!


saludos!

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Punteros A Funcion
« Respuesta #1 en: Sábado 18 de Octubre de 2008, 17:49 »
0
Ambos elementos apuntan entre si en el next asi que nunca termina el bucle ...

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Rombus

  • Miembro MUY activo
  • ***
  • Mensajes: 105
  • Nacionalidad: ar
    • Ver Perfil
    • http://myspace.com/punkrecycle
Re: Punteros A Funcion
« Respuesta #2 en: Sábado 18 de Octubre de 2008, 18:10 »
0
:O!

si! ahi lo arregle!

return creaNodo(listAdm, lista, elemento);

en vez de

return creaNodo(listAdm, listAdm->entrada, elemento);


y me anda pero solo con enteros, pruebo con string y no me anda :S

mira:
Código: C
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4. #include <string.h>
  5. #define FALSE 0
  6. #define TRUE !FALSE
  7. typedef char boolean;
  8. typedef int (*list_funCmp_t)(void *a, void *b);
  9. typedef void (*list_funPrint_t)(void *a);
  10.  
  11. //#define INT 0
  12.  
  13. #define STRING 0
  14. //#define CHAR 0
  15.  
  16.  
  17. typedef struct lPtr{
  18.     void *valor;
  19.     struct lPtr *next;
  20. }list_t;
  21.  
  22. typedef struct{
  23.     list_t *entrada;    //Entrada a la lista;
  24.     int sizeTipo;
  25.     list_funCmp_t funCmp;
  26.     list_funPrint_t funPrint;
  27. }listAdm_t;
  28.  
  29.  
  30. ///Funciones de COMPARACION---------------------------------------///
  31. int comparaEnteros(void *a, void *b){
  32.     return *(int *)a - *(int *)b;
  33. }
  34. int comparaCadenas(void *a, void *b){
  35.     return ((int)strcpy((char *)a, (char*)b));  //0 si son iguales, > 1 si b < a; < 1 si a < b
  36. }
  37.  
  38. ///Funciones de IMPRESION----------------------------------------///
  39. void imprimeEnteros(void *a){
  40.     printf("%d",*(int *)a);
  41. }
  42. void imprimeCadenas(void *a){
  43.     printf("%s",(char *)a);
  44. }
  45.  
  46. ///Servicios de LISTA
  47. listAdm_t *lAdmCreate(int sizeTipo, list_funCmp_t funCmp, list_funPrint_t funPrint){    //Crea La estructura administrativa
  48.     listAdm_t *listAdm = (listAdm_t *)malloc(sizeof(listAdm_t));
  49.     assert(listAdm);
  50.  
  51.     listAdm->funCmp = funCmp;
  52.     listAdm->funPrint = funPrint;
  53.  
  54.     listAdm->sizeTipo = sizeTipo;
  55.     listAdm->entrada = NULL;
  56.  
  57.     return listAdm;
  58. }
  59. list_t *creaNodo(listAdm_t *lista, list_t *pNext, void *elemento){  //necesito la estructura administrativa para el peso de dato
  60.     list_t *nodo = (list_t *)malloc(sizeof(list_t));
  61.     assert(nodo);
  62.  
  63.     nodo->valor = malloc(lista->sizeTipo);      assert(nodo->valor);
  64.     nodo->next = pNext;
  65.     memcpy((char *)nodo->valor, (char *)elemento, lista->sizeTipo);
  66.  
  67.     return nodo;
  68. }
  69. list_t *lInsertOrdered(listAdm_t *listAdm, list_t *lista, void *elemento){  //Ordenado de menor a mayor
  70.     if( !lista || (listAdm->funCmp(lista->valor,elemento)) >= 0  ){
  71.         return creaNodo(listAdm, lista, elemento);
  72.     }
  73.     lista->next = lInsertOrdered(listAdm, lista->next, elemento);
  74.     return lista;
  75. }
  76. void printList(listAdm_t *listAdm, list_t *list){
  77.     if(list){   //Si existe la lista
  78.         listAdm->funPrint(list->valor);
  79.         printf(" - ");
  80.         printList(listAdm, list->next);
  81.     }
  82. }
  83.  
  84. int main(void){
  85.     #ifdef STRING
  86.         char i[] = "AAZ", b[] = "AAA";
  87.         listAdm_t *lista = lAdmCreate(sizeof(i), comparaCadenas,imprimeCadenas);
  88.     #endif
  89.     #ifdef CHAR
  90.         char i = 'a', b = 'g';
  91.         listAdm_t *lista = lAdmCreate(sizeof(char), comparaCaracteres,imprimeCaracteres);
  92.     #endif
  93.     #ifdef INT
  94.         int i= 6, b = 9;
  95.         listAdm_t *lista = lAdmCreate(sizeof(int), comparaEnteros,imprimeEnteros);
  96.     #endif
  97.  
  98.     lista->entrada = lInsertOrdered(lista, lista->entrada, (void *)&i);
  99.     lista->entrada = lInsertOrdered(lista, lista->entrada, (void *)&b);
  100.    
  101.     #ifdef INT  
  102.         i = 0;
  103.         b = 8;
  104.     #endif
  105.     #ifdef STRING
  106.         strcpy(i,"ZZZ");
  107.         strcpy(b,"BBB");
  108.     #endif
  109.    
  110.     lista->entrada = lInsertOrdered(lista, lista->entrada, (void *)&i);
  111.     lista->entrada = lInsertOrdered(lista, lista->entrada, (void *)&b);
  112.  
  113.     printList(lista, lista->entrada);
  114.     return 0;
  115. }
  116.  
  117.  

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Punteros A Funcion
« Respuesta #3 en: Sábado 18 de Octubre de 2008, 18:23 »
0
Tenes que depurar un poco mas:

int comparaCadenas(void *a, void *b){
    return ((int)strcpy((char *)a, (char*)b));  //0 si son iguales, > 1 si b < a; < 1 si a < b
}


strcpy es string copy, strcmp es lo que queres, string compare.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

Rombus

  • Miembro MUY activo
  • ***
  • Mensajes: 105
  • Nacionalidad: ar
    • Ver Perfil
    • http://myspace.com/punkrecycle
Re: Punteros A Funcion
« Respuesta #4 en: Sábado 18 de Octubre de 2008, 18:29 »
0
ufff

 :wacko: siempre se me confunden


gracias Eternal IDOL!! :beer:

cuando tenga todas las estructuras genericas las voy a compratir con la comunidad XD

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Punteros A Funcion
« Respuesta #5 en: Sábado 18 de Octubre de 2008, 18:33 »
0
De nadas  B)

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.