Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: m@o_614 en 21 Diciembre 2012, 01:08 am



Título: warnings
Publicado por: m@o_614 en 21 Diciembre 2012, 01:08 am
saludos

tengo el siguiente código de una lista simplemente enlazada, pero el problema es que me aparece un warning que dice:

return makes pointer from integer without a cast

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. typedef struct nodo
  5. {
  6.    int dato;
  7.    struct nodo*sig;
  8. }NODO;
  9.  
  10. NODO* crear_nodo(int x);
  11. void insertar_cabeza(NODO **cabeza,int x);
  12. NODO* buscar_elemento(NODO *cabeza);
  13.  
  14. int main()
  15. {
  16.    int i,num,x;
  17.    NODO *cabeza,*ptr;
  18.    cabeza = NULL;
  19.    printf("Cuantos elementos quieres?\n");
  20.    scanf("%d",&num);
  21.    printf("Lista Simplemente Ligada!\n");
  22.    for(i=0;i<num;i++)
  23.    {
  24.        printf("Dame el elemento %d\n",i+1);
  25.        scanf("%d",&x);
  26.        insertar_cabeza(&cabeza,x);
  27.        system("cls");
  28.    }
  29.  
  30.    for(ptr=cabeza;ptr!=NULL;ptr=ptr->sig)
  31.        printf("\n%d\n",ptr->dato);
  32.    buscar_elemento(cabeza);
  33.    return 0;
  34. }
  35.  
  36. NODO* crear_nodo(int x)
  37. {
  38.    NODO *p;
  39.    p = (NODO*)malloc(sizeof(NODO));
  40.    p->dato = x;
  41.    p->sig = NULL;
  42.    return p;
  43. }
  44.  
  45. void insertar_cabeza(NODO **cabeza,int x)
  46. {
  47.    NODO *nuevo;
  48.    nuevo = crear_nodo(x);
  49.    nuevo->sig = *cabeza;
  50.    *cabeza = nuevo;
  51. }
  52.  
  53. NODO* buscar_elemento(NODO *cabeza)
  54. {
  55.    int elemento,encontro=0;
  56.    NODO *indice;
  57.    printf("Buscar elemento\n\n");
  58.    printf("Cual elemento quieres buscar?\n");
  59.    scanf("%d",&elemento);
  60.    for(indice=cabeza;indice!=NULL;indice=indice->sig)
  61.    {
  62.        if(indice->dato==elemento)
  63.           encontro=1;
  64.        else
  65.           encontro=0;
  66.    }
  67.    if(encontro)
  68.       return indice->dato;
  69.    else
  70.       return 0;
  71. }
  72.  
de antemano gracias


Título: Re: warnings
Publicado por: naderST en 21 Diciembre 2012, 01:15 am
El warning es porque en tu caso buscar_elemento debe retornar un apuntador a NODO (NODO*) y tu estás retornando un entero.

Código
  1.   if(encontro)
  2.       return indice->dato;
  3.    else
  4.       return 0;
  5.  


Título: Re: warnings
Publicado por: dato000 en 21 Diciembre 2012, 11:53 am
pero el warning no afecta el funcionamiento del programa, deberia retornar NULL entonces??


Título: Re: warnings
Publicado por: 0xDani en 21 Diciembre 2012, 15:56 pm
pero el warning no afecta el funcionamiento del programa, deberia retornar NULL entonces??

Si.


Título: Re: warnings
Publicado por: m@o_614 en 22 Diciembre 2012, 01:53 am
muchas gracias por sus respuestas, ahora ya no me aparece ese warning pero como ya le agregue la función de eliminar_elemento (en esta metí la función de buscar) pero no me hace lo que le pido

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. typedef struct nodo
  5. {
  6.    int dato;
  7.    struct nodo*sig;
  8. }NODO;
  9.  
  10. NODO* crear_nodo(int x);
  11. void insertar_cabeza(NODO **cabeza,int x);
  12. void eliminar_elemento(NODO **cabeza);
  13.  
  14. int main()
  15. {
  16.    int i,num,x;
  17.    NODO *cabeza,*ptr;
  18.    cabeza = NULL;
  19.    printf("Cuantos elementos quieres?\n");
  20.    scanf("%d",&num);
  21.    printf("Lista Simplemente Ligada!\n\n");
  22.    for(i=0;i<num;i++)
  23.    {
  24.        printf("Dame el elemento %d\n",i+1);
  25.        scanf("%d",&x);
  26.        insertar_cabeza(&cabeza,x);
  27.        system("cls");
  28.    }
  29.  
  30.    for(ptr=cabeza;ptr!=NULL;ptr=ptr->sig)
  31.        printf("%d\t",ptr->dato);
  32.  
  33.    eliminar_elemento(&cabeza);
  34.    for(ptr=cabeza;ptr!=NULL;ptr=ptr->sig)
  35.        printf("%d\t",ptr->dato);
  36.    return 0;
  37. }
  38.  
  39. NODO* crear_nodo(int x)
  40. {
  41.    NODO *p;
  42.    p = (NODO*)malloc(sizeof(NODO));
  43.    p->dato = x;
  44.    p->sig = NULL;
  45.    return p;
  46. }
  47.  
  48. void insertar_cabeza(NODO **cabeza,int x)
  49. {
  50.    NODO *nuevo;
  51.    nuevo = crear_nodo(x);
  52.    nuevo->sig = *cabeza;
  53.    *cabeza = nuevo;
  54. }
  55.  
  56. void eliminar_elemento(NODO **cabeza)
  57. {
  58.   int n;
  59.   NODO *actual,*anterior;
  60.   anterior=NULL;
  61.   printf("Dame el elemento a eliminar\n");
  62.   scanf("%d",&n);
  63.   for(actual=*cabeza;actual!=NULL;actual=actual->sig)
  64.   {
  65.       if(actual->dato==n)
  66.       {
  67.           anterior = actual->sig;
  68.           actual = anterior;
  69.           free(actual);
  70.       }
  71.   }
  72. }
  73.  

estos punteros por qué son tan difíciles?? :rolleyes:


Título: Re: warnings
Publicado por: twins en 22 Diciembre 2012, 02:24 am
Hola pues te explico para eliminar un nodo que este en una posicion distinta del inicio o final necesitas usar dos punteros para poder hacer los enlaces en este caso yo solo modifique la funsion eliminar_elemento tu puedes revisar y ver cuales fueron los cambios cordiales saludos  ;D
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef struct nodo{
  4.    int dato;
  5.    struct nodo *sig;
  6. }NODO;
  7. NODO* crear_nodo(int x);
  8. void insertar_cabeza(NODO **cabeza,int x);
  9. void eliminar_elemento(NODO **cabeza);
  10. int main(void){
  11.    int i,num,x;
  12.    NODO *cabeza,*ptr;
  13.    cabeza = NULL;
  14.    printf("Cuantos elementos quieres?\n");
  15.    scanf("%d",&num);
  16.    printf("Lista Simplemente Ligada!\n\n");
  17.    for(i=0;i<num;i++){
  18.        printf("Dame el elemento %d\n",i+1);
  19.        scanf("%d",&x);
  20.        insertar_cabeza(&cabeza,x);
  21.        system("cls");
  22.    }
  23.    for(ptr=cabeza;ptr!=NULL;ptr=ptr->sig)
  24.        printf("%d\t",ptr->dato);
  25.    eliminar_elemento(&cabeza);
  26.    for(ptr=cabeza;ptr!=NULL;ptr=ptr->sig)
  27.        printf("%d\t",ptr->dato);
  28.    return 0;
  29. }
  30. NODO* crear_nodo(int x){
  31.    NODO *p;
  32.    p = (NODO*)malloc(sizeof(NODO));
  33.    p->dato = x;
  34.    p->sig = NULL;
  35.    return p;
  36. }
  37. void insertar_cabeza(NODO **cabeza,int x){
  38.    NODO *nuevo;
  39.    nuevo = crear_nodo(x);
  40.    nuevo->sig = *cabeza;
  41.    *cabeza = nuevo;
  42. }
  43. void eliminar_elemento(NODO **cabeza){
  44. int n;
  45. NODO *aux1=*cabeza,*aux2=aux1;
  46.    printf("Dame el elemento a eliminar\n");
  47.    scanf("%d",&n);
  48. while(aux2->dato!=n){
  49. aux1=aux2;
  50. aux2=aux2->sig;
  51. }
  52. aux1->sig=aux2->sig;
  53.    free(aux2);
  54. }
  55.  


Título: Re: warnings
Publicado por: rir3760 en 23 Diciembre 2012, 03:09 am
ahora ya no me aparece ese warning pero como ya le agregue la función de eliminar_elemento (en esta metí la función de buscar) pero no me hace lo que le pido
Como ya te comentaron:
A) Si el nodo a eliminar es el primero debes utilizar el parámetro de la función para así afectar la variable "cabeza" de la función main.
B) Para cualquier otro nodo solo hay que actualizar el campo "sig" del nodo anterior.

Para eliminar un nodo de una lista no es necesario utilizar variables auxiliares (en el bucle), en su lugar se trabaja directamente con el parámetro (y sirve para practicar el tema):
Código
  1. void eliminar_elemento(NODO **p)
  2. {
  3.   NODO *aux;
  4.   int dato;
  5.  
  6.   puts("Dame el elemento a eliminar:");
  7.   scanf("%d", &dato);
  8.  
  9.   while (*p != NULL && (*p)->dato != dato)
  10.      p = &(*p)->sig;
  11.   if (*p != NULL){
  12.      aux = *p;
  13.      *p = (*p)->sig;
  14.      free(aux);
  15.   }
  16. }

Un saludo


Título: Re: warnings
Publicado por: durasno en 23 Diciembre 2012, 06:48 am
Hola! muy bueno el aporte rir3760, la verdad me costo entenderlo; trabajar directamente con el puntero a puntero :)


Saludos


Título: Re: warnings
Publicado por: m@o_614 en 28 Diciembre 2012, 03:22 am
Muchas gracias por sus respuestas

Una última pregunta porque cuando le ingreso por ejemplo los números 5,18,67,80 me los imprime al revés 80, 67,18 y 5

no se supone que el puntero *cabeza siempre apunta al inicio de la lista?? ¿por qué la imprime así?

gracias :)


Título: Re: warnings
Publicado por: twins en 28 Diciembre 2012, 16:37 pm
Eso es porque los nodos los estas ingresando al inicio de la lista por ejemplo si ingresas el 1 y despues el 2, en este caso el 2 quedara a la izquierda del 1 es decir 2,1 y tu puntero cabeza apunta al segundo nodo recien ingresado, en este caso el 2, por lo tanto cuando imprimes, imprimes de izquierda a derecha ose 2,1.
si quieres que los nodos sea impresos segun el orden en que fueron ingresados tendras que modificar la funcion insertar_cabeza.


Título: Re: warnings
Publicado por: rir3760 en 28 Diciembre 2012, 18:16 pm
Para imprimirlos en orden inverso se puede desarrollar una función recursiva, mas o menos así:
Código
  1. void imprimir_rev(struct nodo *p)
  2. {
  3.   if (p != NULL){
  4.      imprimir_rev(p->sig);
  5.  
  6.      /* Imprimir informacion del nodo apuntado por p */
  7.   }
  8. }

Un saludo


Título: Re: warnings
Publicado por: m@o_614 en 29 Diciembre 2012, 00:19 am
muchas gracias twins y rir3760 por sus respuestas, disculpen si pregunto mucho lo que pasa es que este tema de punteros es de los que más se me dificulta

ahora quiero que en vez de que me ingrese los elementos por la cabeza me los ingrese por el final, pero tengo una duda, ya se que tengo que tener un puntero que recorra la lista desde la cabeza hasta que apunte a NULL (o sea el final) pero no se si hacerlo así:

Código
  1. NODO *ultimo;
  2.    ultimo=*cabeza;
  3.    while(ultimo->sig!=NULL)
  4.       ultimo=ultimo->sig;

o así

Código
  1. NODO *ultimo;
  2.    ultimo=*cabeza;
  3.    while(ultimo!=NULL)
  4.       ultimo=ultimo->sig;

en uno último tiene campo siguiente y en el otro no


Título: Re: warnings
Publicado por: rir3760 en 29 Diciembre 2012, 01:33 am
Código
  1. NODO *ultimo;
  2.    ultimo=*cabeza;
  3.    while(ultimo->sig!=NULL)
  4.       ultimo=ultimo->sig;
Con esto el programa revienta al procesar una lista vacía.

Código
  1. NODO *ultimo;
  2.    ultimo=*cabeza;
  3.    while(ultimo!=NULL)
  4.       ultimo=ultimo->sig;
Y aquí no se actualizaría correctamente si, de nuevo, la lista esta vacía.

Para insertar un nodo al final:
Código
  1. void insertar_ultimo(struct nodo **p, struct nodo *nodo)
  2. {
  3.   while (*p != NULL)
  4.      p = &(*p)->sig;
  5.  
  6.   *p = nodo;
  7. }
Donde el primer argumento es la dirección en memoria de la variable que almacena la dirección en memoria del primer nodo (Ouch!), usualmente "&primero". El segundo argumento es la dirección en memoria del nodo a insertar.

Por ultimo y en el caso ideal cada función debe realizar una sola operación, por ejemplo la función que agrega pide los datos y llama a las funciones para 1) Crear un nodo y 2) Insertarlo en la lista.

Un saludo


Título: Re: warnings
Publicado por: m@o_614 en 31 Diciembre 2012, 01:23 am
saludos

tenías razón si tronaba el programa al querer insertar por el final ya que la lista está vacia, lo que hice fue primero comprobar si estaba vacía, ahora el programa ya compila perfectamente pero me gustaría agregar la función

Código
  1. int vacia(NODO *cabeza)
  2. {
  3.    if(cabeza==NULL)
  4.       return 1;
  5.    else
  6.       return 0;
  7. }
  8.  


dentro de mi otra función, como una llamada para verificar si hay o no más elementos en la lista

Código
  1. void insertar_final(NODO **cabeza,int x)
  2. {
  3.    NODO *ultimo;
  4.    if(*cabeza==NULL)//Aquí checa si está vacía
  5.        *cabeza = crear_nodo(x);
  6.    else
  7.    {
  8.        ultimo=*cabeza;
  9.        while(ultimo->sig!=NULL)
  10.           ultimo=ultimo->sig;
  11.  
  12.        ultimo->sig = crear_nodo(x);
  13.        ultimo = ultimo->sig;
  14.        ultimo->sig = NULL;
  15.    }
  16. }
  17.  

pero el problema es que cabeza la tengo como doble puntero **cabeza y no sabría como hacerlo aunque en si ya imprime lo que le pido

gracias y feliz áño nuevo ;D