Pasar puntero en recursion

Iniciado por LadyWin, 29 Agosto 2021, 06:46 AM

0 Miembros y 1 Visitante están viendo este tema.

LadyWin

Hola! como andan? Ya he hecho varios post respecto a los punteros y de a poco le estoy agarrando la mano gracias a sus consejos.  ;D
Ahora estoy creando una lista en donde voy agregando los elementos al final de modo recursivo, pero me sale ciertos errores, entiendo que es un problema en los punteros pero he visto varias funcionalidades de otras personas que lo escriben asi y al parecer no les sale el mismo inconveniente, o como seria la correcta forma de escribirlo? si me pueden ayudar seria de gran ayuda!
  ;-)

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

typedef struct rLista
{
int dato;
struct rNodo * sig;
} * tLista;

tLista * crear_nodo (int nuevo_dato)
{
tLista * nuevo_elemento = (tLista*) malloc (sizeof(tLista));
(*nuevo_elemento)->dato = nuevo_dato;
(*nuevo_elemento)->sig = NULL;
return nuevo_elemento;
}
tLista agregar_final (tLista * ppio, tLista * nuevo_elemento)
{
if (!ppio) ppio = nuevo_elemento;
else
ppio->sig = agregar_final(ppio->sig,nuevo_elemento); //error: '*ppio' is a pointer; did you mean to use '->'?

return *ppio;
}
int contar_elementos (tLista * ppio)
{
int contador;

if (!ppio) return 0;
else contador = contar_elementos(ppio->sig); // error: '*ppio' is a pointer; did you mean to use '->'?

return contador;
}


int main (void)
{
tLista ppio = NULL;

ppio = agregar_final(&ppio,crear_nodo(5));

return 0;
}

MAFUS

Te he modificado el programa para que funcione y te he escrito en los comentarios el por qué de cada cambio.

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

//
// Acuérdate de realizar uan función que libere todos los nodos que hayas creado.
//

// rNodo no existe, al menos en este código que nos has pasado
typedef struct rLista {
int dato;
struct rLista * sig;
} * tLista;

// tLista ya es un puntero. Esta función sólo genera un dato en en heap y lo devuelve,
// por tanto no hay que regresar un puntero a puntero.
tLista crear_nodo (int nuevo_dato) {
tLista nuevo_elemento = malloc (sizeof(struct rLista));
nuevo_elemento->dato = nuevo_dato;
nuevo_elemento->sig = NULL;
return nuevo_elemento;
}

// nuevo_elemento debe ser un puntero a la dirección del heap con el contenido
// relleno de la estructura y por tanto no un puntero a puntero,
tLista agregar_final (tLista * ppio, tLista nuevo_elemento) {
    // ppio es un puntero a puntero y eso es para que puedas modificar el puntero que
    // está en otra función. ppio debe ser dereferenciado
if (!*ppio) *ppio = nuevo_elemento;
// El parámetro que se debe pasar a agregar_final es el puntero al campo sig del dato apuntado por ppio
// por eso debe pasarse la referencia & a sig del puntero -> al que hace referencia * ppio
else (*ppio)->sig = agregar_final(&((*ppio)->sig), nuevo_elemento);

return *ppio;
}

//tLista ya es un puntero y solo hay que recorrerlo, no hay que pasarle un puntero a puntero
int contar_elementos (tLista ppio) {
if (!ppio) return 0;
// Usar una variable contandor haría que se reiniciara cada vez, por tanto lo que hay que hacer
// es añadir 1 a la siguiente llamada a la faunción. Así es como funciona la recursión:
// Cuando ppio sea NULL devolverá 0 y no hará más llamadas, la función anterior devolverá 1 + 0,
// la anterior devolverá 1 + 1 + 0... y así se recorrerá la lista de llamadas hasta la función inicial
// que devolverá la suma de todas las llamadas al llamante
else return 1+contar_elementos(ppio->sig);
}

int main (void) {
tLista ppio = NULL;

agregar_final(&ppio,crear_nodo(5));
agregar_final(&ppio,crear_nodo(6));
       
        // Muestra el uso de contar_elementos
printf("Elementos en la lista: %d", contar_elementos(ppio));
}

LadyWin

Cita de: MAFUS en 29 Agosto 2021, 12:48 PM
Te he modificado el programa para que funcione y te he escrito en los comentarios el por qué de cada cambio.



Muchisimas gracias, no solo me has ayudado con mi duda sino tambien con otros errores que tenia, mil gracias!   ;-) ;D ;-) ;D