Writing a push and pop in c

Learn writing a push and pop in c with practical examples, diagrams, and best practices. Covers c development techniques with visual explanations.

Implementing Push and Pop Operations for a Stack in C

Hero image for Writing a push and pop in c

Learn how to implement fundamental stack operations, push and pop, using arrays and linked lists in C. This guide covers both static and dynamic stack implementations.

Stacks are a fundamental Last-In, First-Out (LIFO) data structure in computer science. They are used in various applications, from managing function calls on the call stack to parsing expressions and implementing undo/redo functionalities. The two primary operations associated with a stack are push (adding an element to the top) and pop (removing an element from the top). This article will guide you through implementing these operations in C using both arrays and linked lists.

Understanding Stack Operations: Push and Pop

Before diving into the code, it's crucial to understand what push and pop entail:

  • Push: This operation adds a new element to the top of the stack. If the stack is full (in the case of an array-based stack), an 'overflow' condition occurs.
  • Pop: This operation removes the element from the top of the stack and returns its value. If the stack is empty, an 'underflow' condition occurs.

Both operations typically involve a 'top' pointer or index that keeps track of the current top element of the stack.

flowchart TD
    subgraph Stack Operations
        A[Start] --> B{Is Stack Full?}
        B -- No --> C[Increment Top]
        C --> D[Add Element at Top]
        D --> E[End Push]
        B -- Yes --> F[Stack Overflow]
        F --> E

        G[Start] --> H{Is Stack Empty?}
        H -- No --> I[Retrieve Element from Top]
        I --> J[Decrement Top]
        J --> K[Return Element]
        K --> L[End Pop]
        H -- Yes --> M[Stack Underflow]
        M --> L
    end

Flowchart illustrating the logic for Push and Pop operations on a stack.

Implementing a Stack using an Array (Static Allocation)

An array-based stack is straightforward to implement. We define a fixed-size array and an integer variable, top, to keep track of the index of the topmost element. Initially, top is set to -1 to indicate an empty stack.

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

#define MAX_SIZE 10

int stack[MAX_SIZE];
int top = -1;

// Function to check if the stack is full
int isFull() {
    return top == MAX_SIZE - 1;
}

// Function to check if the stack is empty
int isEmpty() {
    return top == -1;
}

// Function to push an element onto the stack
void push(int data) {
    if (isFull()) {
        printf("Stack Overflow! Cannot push %d\n", data);
    } else {
        stack[++top] = data;
        printf("Pushed %d to stack.\n", data);
    }
}

// Function to pop an element from the stack
int pop() {
    if (isEmpty()) {
        printf("Stack Underflow! Cannot pop from empty stack.\n");
        return -1; // Indicate error or return a special value
    } else {
        int data = stack[top--];
        printf("Popped %d from stack.\n", data);
        return data;
    }
}

// Function to peek at the top element without removing it
int peek() {
    if (isEmpty()) {
        printf("Stack is empty.\n");
        return -1;
    } else {
        return stack[top];
    }
}

int main() {
    push(10);
    push(20);
    push(30);

    printf("Top element is: %d\n", peek());

    pop();
    pop();
    pop();
    pop(); // Attempt to pop from an empty stack

    push(40);
    printf("Top element is: %d\n", peek());

    return 0;
}

C implementation of a stack using a fixed-size array.

Implementing a Stack using a Linked List (Dynamic Allocation)

A linked list-based stack offers dynamic sizing, meaning it can grow or shrink as needed, limited only by available memory. Each node in the linked list represents an element, and the 'top' of the stack is typically the head of the linked list.

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

// Define a structure for a stack node
struct Node {
    int data;
    struct Node* next;
};

struct Node* top = NULL; // Initialize top pointer to NULL for an empty stack

// Function to check if the stack is empty
int isEmpty() {
    return top == NULL;
}

// Function to push an element onto the stack
void push(int data) {
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    if (newNode == NULL) {
        printf("Memory allocation failed! Stack Overflow.\n");
        return;
    }
    newNode->data = data;
    newNode->next = top; // New node points to the current top
    top = newNode;       // New node becomes the new top
    printf("Pushed %d to stack.\n", data);
}

// Function to pop an element from the stack
int pop() {
    if (isEmpty()) {
        printf("Stack Underflow! Cannot pop from empty stack.\n");
        return -1; // Indicate error
    }
    struct Node* temp = top;
    int poppedData = temp->data;
    top = top->next; // Move top to the next node
    free(temp);      // Free the memory of the popped node
    printf("Popped %d from stack.\n", poppedData);
    return poppedData;
}

// Function to peek at the top element without removing it
int peek() {
    if (isEmpty()) {
        printf("Stack is empty.\n");
        return -1;
    }
    return top->data;
}

int main() {
    push(100);
    push(200);
    push(300);

    printf("Top element is: %d\n", peek());

    pop();
    pop();
    pop();
    pop(); // Attempt to pop from an empty stack

    push(400);
    printf("Top element is: %d\n", peek());

    return 0;
}

C implementation of a stack using a dynamically allocated linked list.