Una pila basada en arrays debe exponer operaciones compactas y deterministas. Las siguientes subsecciones describen la implementación usual con un Stack que almacena enteros, pero la lógica se adapta fácilmente a otros tipos.
#include <stdio.h>
#define STACK_MAX 64
typedef struct {
int datos[STACK_MAX];
int top;
} Stack;
void stack_init(Stack *s) {
s->top = 0;
}
Inserta un elemento en el tope, siempre que exista capacidad disponible. Devuelve un valor booleano (1 ó 0) para indicar éxito.
int stack_push(Stack *s, int valor) {
if (s->top == STACK_MAX) {
return 0; /* overflow */
}
s->datos[s->top++] = valor;
return 1;
}
Remueve el elemento superior. Es aconsejable devolver el valor mediante un parámetro de salida para distinguir entre error y datos reales.
int stack_pop(Stack *s, int *out) {
if (s->top == 0) {
return 0; /* underflow */
}
*out = s->datos[--s->top];
return 1;
}
Permite inspeccionar el elemento actual sin modificar el estado de la pila, ideal para validaciones o algoritmos que necesitan comparar el próximo valor.
int stack_peek(const Stack *s, int *out) {
if (s->top == 0) {
return 0;
}
*out = s->datos[s->top - 1];
return 1;
}
Función auxiliar para consultar si la pila está vacía. Facilita la lectura del código y evita repetir comparaciones.
int stack_is_empty(const Stack *s) {
return s->top == 0;
}
Complemento del anterior para detectar si la pila alcanzó la capacidad máxima. Resulta útil para interfaces que desean mostrar un mensaje al usuario antes de intentar un push.
int stack_is_full(const Stack *s) {
return s->top == STACK_MAX;
}
Recorrer el array desde el tope hacia abajo ayuda a depurar o mostrar el contenido actual. El siguiente ejemplo muestra el formato [top: valor].
void stack_print(const Stack *s) {
printf("Pila (%d elementos):\n", s->top);
for (int i = s->top - 1; i >= 0; --i) {
if (i == s->top - 1) {
printf(" [top] %d\n", s->datos[i]);
} else {
printf(" %d\n", s->datos[i]);
}
}
}
Los arrays comienzan en cero; por lo tanto, el incremento/decremento de top debe ser cuidadoso. Las reglas básicas:
push: s->datos[s->top++] = valor;pop: *out = s->datos[--s->top];isFull e isEmpty para prevenir desbordes.Pequeños errores en el orden de incremento/decremento pueden provocar lecturas fuera de rango y resultados erráticos. Añadir pruebas unitarias o asserts ayuda a detectar estos fallos temprano.
El siguiente snippet combina todas las operaciones en un programa ejecutable:
#include <stdio.h>
#define STACK_MAX 6
typedef struct {
int datos[STACK_MAX];
int top;
} Stack;
void stack_init(Stack *s) { s->top = 0; }
int stack_is_empty(const Stack *s) { return s->top == 0; }
int stack_is_full(const Stack *s) { return s->top == STACK_MAX; }
int stack_push(Stack *s, int valor) {
if (stack_is_full(s)) return 0;
s->datos[s->top++] = valor;
return 1;
}
int stack_pop(Stack *s, int *out) {
if (stack_is_empty(s)) return 0;
*out = s->datos[--s->top];
return 1;
}
int stack_peek(const Stack *s, int *out) {
if (stack_is_empty(s)) return 0;
*out = s->datos[s->top - 1];
return 1;
}
void stack_print(const Stack *s) {
printf("Contenido actual:\n");
for (int i = s->top - 1; i >= 0; --i) {
printf(" %d%s\n", s->datos[i], i == s->top - 1 ? " <- top" : "");
}
}
int main(void) {
Stack pila;
stack_init(&pila);
for (int i = 1; i <= 4; ++i) {
stack_push(&pila, i * 10);
}
stack_print(&pila);
int peek;
if (stack_peek(&pila, &peek)) {
printf("Peek: %d\n", peek);
}
int valor;
while (stack_pop(&pila, &valor)) {
printf("Pop: %d\n", valor);
}
return 0;
}
Al compilarlo en CLion se observará la impresión del estado completo, el resultado de peek y cada pop sucesivo, validando el manejo de índices.