AprenderC
← Todas las lecciones

Lo último que entra, lo primero que sale

A veces hay que recordar las cosas al revés de como llegaron.

1Por qué

Llevas veintitantas lecciones mirando una pila sin que se llamara así. Cada vez que ejecutabas paso a paso y entrabas en una función, aparecía una caja nueva encima; al terminar, desaparecía la de arriba. Eso es lo que hace el computador con las llamadas, y tiene nombre.

Una pila guarda cosas con una regla única: sale la última que entró. Nada más. Deshacer en un editor, volver atrás en el navegador, comprobar que los paréntesis cierran bien — todo eso es la misma estructura, y en todos los casos lo que hace falta es recordar al revés.

Lo bueno es que ya sabes construirla. Una pila es una lista enlazada donde solo se toca la cabeza: meter es lo que hacías en la lección 17 —poner por delante— y sacar es quitar el de delante. Lo único que se añade es la promesa de no tocar el resto.

Y por eso las dos operaciones cuestan lo mismo con tres elementos que con tres millones: nunca se recorre nada.

Al sacar hay una trampa que ya conoces de la 17: hay que mover la cima antes de devolver el nodo, o queda apuntando a un sitio que ya no es tuyo.

2Míralo andar

Este programa funciona. Léelo, y después ejecútalo sin cambiar nada.

#include <stdio.h>
#include <stdlib.h>
typedef struct Nodo {
int valor;
struct Nodo *sig;
} Nodo;
void apilar(Nodo **cima, int x)
{
Nodo *n = malloc(sizeof(Nodo));
n->valor = x;
n->sig = *cima;
*cima = n;
}
int desapilar(Nodo **cima)
{
Nodo *n = *cima;
int v = n->valor;
*cima = n->sig;
free(n);
return v;
}
int main(void)
{
Nodo *cima = NULL;
apilar(&cima, 1);
apilar(&cima, 2);
apilar(&cima, 3);
printf("%d %d\n", desapilar(&cima), desapilar(&cima));
while (cima != NULL)
{
Nodo *s = cima->sig;
free(cima);
cima = s;
}
return 0;
}

3Ahora tú

A desapilar le falta mover la cima, así que la pila se queda mirando lo que ya devolvió. Escribe esa línea, para que salga: 3 2

#include <stdio.h>
#include <stdlib.h>
typedef struct Nodo {
int valor;
struct Nodo *sig;
} Nodo;
void apilar(Nodo **cima, int x)
{
Nodo *n = malloc(sizeof(Nodo));
n->valor = x;
n->sig = *cima;
*cima = n;
}
int desapilar(Nodo **cima)
{
Nodo *n = *cima;
int v = n->valor;
free(n);
return v;
}
int main(void)
{
Nodo *cima = NULL;
apilar(&cima, 1);
apilar(&cima, 2);
apilar(&cima, 3);
printf("%d %d\n", desapilar(&cima), desapilar(&cima));
while (cima != NULL)
{
Nodo *s = cima->sig;
free(cima);
cima = s;
}
return 0;
}

↖︎ Tu línea va aquí, antes del free. Después ya sería tarde.

Ejecutar

Lo que dice tu programa

↖︎ Escribe tu parte y dale a Ejecutar

Qué pasó

Aquí te aviso si tu programa hace algo raro.

    4Qué guarda tu programa

    Memoria

    ↖︎ Ejecuta el programa para ver qué pasa por dentro