Error!

Iniciado por rodrigo_103, 7 Noviembre 2012, 22:41 PM

0 Miembros y 2 Visitantes están viendo este tema.

rodrigo_103

Hola, ¿como les va?
estoy haciendo un programa para copiar una lista simplemente enlazada y imprimirla, la cuestion es que me tira 2 errores que deben ser sencillos, pero no logro resolverlos..

Agradeceria mucho su ayuda.

Citar
listas.c|62|error: expected '=', ',', ';', 'asm' or '__attribute__' before 's_copy'|
listas.c||In function 'main':|
listas.c|105|warning: assignment makes pointer from integer without a cast|
||=== Build finished: 1 errors, 1 warnings ===|

#include <stdio.h>
#include <stdlib.h>

struct registro
{
    int valor;
    struct registro *sig;
};

typedef struct registro _nodo;

_nodo *crearlista(_nodo *apuntador)
{
    return (apuntador=NULL);
}

_nodo *insertarEnLista(int numero, _nodo *apuntador )
{
    _nodo *registroNuevo, *apuntadorAuxiliar;

    registroNuevo = (_nodo*)/*casteo*/ malloc(sizeof(_nodo));

    if(registroNuevo!=NULL)
    {/*lleno el nuevo nodo suelto*/
        registroNuevo->valor=numero;
        registroNuevo->sig=NULL;

        if(apuntador==NULL)
            apuntador=registroNuevo;
        else
        {
            apuntadorAuxiliar = apuntador;

            while(apuntadorAuxiliar->sig != NULL)
                apuntadorAuxiliar = apuntadorAuxiliar->sig;

            apuntadorAuxiliar->sig = registroNuevo;
        }
    }

    return apuntador;
}

void imprimirLista(_nodo *apuntador)
{
    _nodo *apuntadorAuxiliar;

    apuntadorAuxiliar=apuntador;

    printf("Contenido de la lista: inicioLista->");

    while(apuntadorAuxiliar != NULL)
    {
        printf("%d -> ", apuntadorAuxiliar->valor);
        apuntadorAuxiliar = apuntadorAuxiliar->sig;
    }
    printf("NULL\n");

    return;
}

_nodo *apuntador2 s_copy(_nodo *apuntador)
{
    _nodo *registroAuxiliar, _nodo *apuntador2 , *apuntadorAuxiliar , *apuntadorAuxiliar2;
    apuntador2*=crearlista(*apuntador2);


      if(apuntador==NULL)
            printf("la lista que copio estaba vacia");
            apuntador2=apuntador;

      else
        {
            apuntadorAuxiliar = apuntador;
            apuntadorAuxiliar2 = apuntador2;

            while(apuntadorAuxiliar->sig != NULL)
                {
                    *apuntadorAuxiliar2=*apuntadorAuxiliar;

                    apuntadorAuxiliar2=apuntadorAuxiliar2->sig;
                    apuntadorAuxiliar = apuntadorAuxiliar->sig;
                }
        }

        return apuntador2;
}


int main()
{
    _nodo *inicioLista;
    _nodo *inicioLista2;

    inicioLista=crearlista(inicioLista);
    inicioLista2=crearlista(inicioLista2);


    inicioLista = insertarEnLista(5, inicioLista);
    inicioLista = insertarEnLista(6, inicioLista);
    inicioLista = insertarEnLista(7, inicioLista);
    inicioLista = insertarEnLista(8, inicioLista);
    inicioLista = insertarEnLista(9, inicioLista);

    inicioLista2 = s_copy(inicioLista);

    imprimirLista(inicioLista2);



    return EXIT_SUCCESS;
}


BatchianoISpyxolo

_nodo *apuntador2 s_copy(_nodo *apuntador) {...}

Fíjate que tratas de devolver el tipo "_nodo * apuntador2" y eso no es ningún tipo. El tipo es _nodo *

De todas formas yo crearía el tipo tPosL (_nodo *) y el tipo tLista (tPosL) para que se lea mucho más claro.

Aquí te dejo el código corregidos los errores de sintaxis pero da segmentation fault, así que revisa la memoria:

#include <stdio.h>
#include <stdlib.h>

struct registro
{
    int valor;
    struct registro *sig;
};

typedef struct registro _nodo;

_nodo *crearlista(_nodo *apuntador)
{
    return (apuntador=NULL);
}

_nodo *insertarEnLista(int numero, _nodo *apuntador )
{
    _nodo *registroNuevo, *apuntadorAuxiliar;

    registroNuevo = (_nodo*)/*casteo*/ malloc(sizeof(_nodo));

    if(registroNuevo!=NULL)
    {/*lleno el nuevo nodo suelto*/
        registroNuevo->valor=numero;
        registroNuevo->sig=NULL;

        if(apuntador==NULL)
            apuntador=registroNuevo;
        else
        {
            apuntadorAuxiliar = apuntador;

            while(apuntadorAuxiliar->sig != NULL)
                apuntadorAuxiliar = apuntadorAuxiliar->sig;

            apuntadorAuxiliar->sig = registroNuevo;
        }
    }

    return apuntador;
}

void imprimirLista(_nodo *apuntador)
{
    _nodo *apuntadorAuxiliar;

    apuntadorAuxiliar=apuntador;

    printf("Contenido de la lista: inicioLista->");

    while(apuntadorAuxiliar != NULL)
    {
        printf("%d -> ", apuntadorAuxiliar->valor);
        apuntadorAuxiliar = apuntadorAuxiliar->sig;
    }
    printf("NULL\n");

    return;
}

_nodo * s_copy(_nodo *apuntador)
{
    _nodo *registroAuxiliar, *apuntador2 , *apuntadorAuxiliar , *apuntadorAuxiliar2;
    apuntador2=crearlista(apuntador2);


      if(apuntador==NULL) {
            printf("la lista que copio estaba vacia");
            apuntador2=apuntador;
      }

      else
        {
            apuntadorAuxiliar = apuntador;
            apuntadorAuxiliar2 = apuntador2;

            while(apuntadorAuxiliar->sig != NULL)
                {
                    *apuntadorAuxiliar2=*apuntadorAuxiliar;

                    apuntadorAuxiliar2=apuntadorAuxiliar2->sig;
                    apuntadorAuxiliar = apuntadorAuxiliar->sig;
                }
        }

        return apuntador2;
}


int main()
{
    _nodo *inicioLista;
    _nodo *inicioLista2;

    inicioLista=crearlista(inicioLista);
    inicioLista2=crearlista(inicioLista2);


    inicioLista = insertarEnLista(5, inicioLista);
    inicioLista = insertarEnLista(6, inicioLista);
    inicioLista = insertarEnLista(7, inicioLista);
    inicioLista = insertarEnLista(8, inicioLista);
    inicioLista = insertarEnLista(9, inicioLista);

    inicioLista2 = s_copy(inicioLista);

    imprimirLista(inicioLista2);



    return EXIT_SUCCESS;
}
Puede que desees aprender a programar desde 0: www.espascal.es

rodrigo_103

muchas gracias amigo, ya no me da mas ese problema, ahora solo obtengo la violacion de segmento de la que hablabas, en cuanto la solucione subo el codigo final, por si alguien lo precisa en el futuro. un saludo.

BatchianoISpyxolo

Debo decir que la inserción de un elemento de la lista debería devolver un tipo booleano (int), no un puntero a un nodo.

En pseudocódigo sería (depende del tipo de lista y la inserción):

función insertar(lista, elemento, [posición]) -> lista, boolean

[posición], entre corchetes porque es opcional.

Siendo lista el puntero que apunta al primer nodo de la lista (en una lista simplemente enlazada)

Siendo elemento el elemento albergado en cada nodo de la lista

La función devuelve la lista modificada (si fue posible) y un valor booleano(int) para saber si se pudo realizar la inserción

Nota*: No podemos insertar un nuevo elemento cuando no hay memoria disponible.

Si ( punteroANuevoNodo = NULO) entonces Error de memoria - No se puede insertar
Puede que desees aprender a programar desde 0: www.espascal.es

do-while

¡Buenas!


_nodo *insertarEnLista(int numero, _nodo *apuntador )


No puedes modificar un puntero exterior si no tienes un doble puntero. Si cuando llamas a la funcion el puntero que usas en la llamada tiene el valor NULL, copiaras dicho valor en el parametro que utiliza la funcion internamente, pero anque cambies la direccion a la que apunta el puntero interno de la funcion, no estaras cambiando el externo, por lo tanto seguira siendo NULL cuando salga de la funcion:


#include <stdio.h>

void puntero(int *ptr)
{
    int d;

    ptr = &d;
}

int main(int argc, char *argv[])
{
    int *ptr = NULL;

    puntero(ptr);

    printf("%p\n",ptr);

    return 0;
}


Si quieres cambiar el puntero tendras que mandar un puntero al puntero:


#include <stdio.h>

void puntero(int **ptr)
{
    int d;

    //accedemos al puntero exterior para poder modificarlo
    (*ptr) = &d;
}

int main(int argc, char *argv[])
{
    int *ptr = NULL;

    puntero(&ptr);

    printf("%p\n",ptr);

    return 0;
}


Por lo tanto el prototipo de tu nueva funcion es:

_nodo *insertarEnLista(int numero, _nodo **apuntador )

Y tendras que modificar el resto del codigo para que funcione de forma correcta.

Y con esta funcion no se que quieres hacer, pero realmente no esta haciendo nada efectivo.



_nodo * s_copy(_nodo *apuntador)
{
    _nodo *registroAuxiliar, *apuntador2 , *apuntadorAuxiliar , *apuntadorAuxiliar2;
    apuntador2=crearlista(apuntador2);


      if(apuntador==NULL) {
            printf("la lista que copio estaba vacia");
            apuntador2=apuntador;
      }

      else
        {
            apuntadorAuxiliar = apuntador;
            apuntadorAuxiliar2 = apuntador2;

            while(apuntadorAuxiliar->sig != NULL)
                {
                    *apuntadorAuxiliar2=*apuntadorAuxiliar;

                    apuntadorAuxiliar2=apuntadorAuxiliar2->sig;
                    apuntadorAuxiliar = apuntadorAuxiliar->sig;
                }
        }

        return apuntador2;
}


Si nos cuentas cual es tu intencion con esta funcion te podremos ayudar.

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!

rir3760

Cita de: do-while en  8 Noviembre 2012, 15:58 PM
_nodo *insertarEnLista(int numero, _nodo *apuntador )


No puedes modificar un puntero exterior si no tienes un doble puntero. Si cuando llamas a la funcion el puntero que usas en la llamada tiene el valor NULL, copiaras dicho valor en el parametro que utiliza la funcion internamente, pero anque cambies la direccion a la que apunta el puntero interno de la funcion, no estaras cambiando el externo, por lo tanto seguira siendo NULL cuando salga de la funcion
Correcto pero en esa función no es un error ya que el valor de retorno de la función es el puntero (actualizado) al primer nodo de la lista y mientras se realice la asignación:
inicioLista = insertarEnLista(5, inicioLista);
inicioLista = insertarEnLista(6, inicioLista);
inicioLista = insertarEnLista(7, inicioLista);
inicioLista = insertarEnLista(8, inicioLista);
inicioLista = insertarEnLista(9, inicioLista);

No habrá problemas.

El programa revienta debido a la cantidad de errores en la función "s_copy", para empezar no debe compilar (me refiero al programa original). Esa función es innecesariamente larga ya que se puede implementar utilizando su parámetro y la función "insertarEnLista", de esta forma:
_nodo *s_copy(_nodo *p)
{
   _nodo *copia = NULL;
   
   while (p != NULL){
      copia = insertarEnLista(p->valor, copia);
      p = p->sig;
   }
   
   return copia;
}


Un saludo
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

do-while

#6
Cita de: rir3760 en  8 Noviembre 2012, 17:17 PM
Correcto pero en esa función no es un error ya que el valor de retorno de la función es el puntero (actualizado) al primer nodo de la lista y mientras se realice la asignación:
inicioLista = insertarEnLista(5, inicioLista);
inicioLista = insertarEnLista(6, inicioLista);
inicioLista = insertarEnLista(7, inicioLista);
inicioLista = insertarEnLista(8, inicioLista);
inicioLista = insertarEnLista(9, inicioLista);


Cierto. Estaba con el chip de usar el propio puntero a la raiz como parametro de entrada/salida y usar el valor de retorno para informar de posibles errores... :silbar:
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!