Flexing C muscles

I’ve been sharpening my C programming skills because I’m now working on a team (i.e. EC2 Networking) within Amazon Web Services that requires skills in lower level software development. And I must say, I’m truly rusty. A noob. On top of that, my only experience with C in the past has been fairly superficial, me dabbling here and there in the K & R book, long before I had taken any computer science courses.  But since taking computer organization and data structures, I have a tight understanding of pointers and their practical uses.

But I digress.

I’m currently working through a book written by Zed Shaw, the book titled “Learn C the hard way.” I had picked up the book at the local library in Seattle, stumbling upon it while I was running my fingers along the spines of books in the computer science section. This book has mixed reviews. Some websites strongly dissuade readers from reading anything published by this particular author.  But others recommend it. So, I’m taking their advice with a grain of salt and forming my own opinion.

At the end of every chapter, the author recommends some extra credit exercises.  In one of these exercises, the author suggests implementing a stack data structure in C.  Now, there are two popular implementations when building a stack: using an array and using a linked list. So, I took this exercise as an opportunity to write a simple stack data structure using linked lists (you gotta love them C pointers).

Here’s the program output:

./stack_linked_list

Stack is empty. Pushing 10 to the top of stack
Stack is not empty. Pushing 20 to the top of the stack
Stack is not empty. Pushing 30 to the top of the stack
Popped item: 30
Peeking at next item: 20
Peeking at next item: 20
Peeking at next item: 20
Popped item: 20
Popped item: 10
Popped item: -1

And the corresponding code:

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

struct Node {
    int value;
    struct Node * next;
};

struct Stack {
    int count;
    struct Node * top;
};


bool isEmpty(struct Stack * stack)
{
    return stack->top == NULL;
}

void push(struct Stack * stack, int item)
{
    /*
     * Edge case: first item to push
     */

    struct Node * node = (struct Node *) malloc(sizeof(struct Node));
    node->value = item;

    if (stack->top == NULL){
        printf("Stack is empty. Pushing %i to the top of stack\n", item);
        stack->top = node;
    } else {
        printf("Stack is not empty. Pushing %i to the top of the stack\n", item);
        node->next = stack->top;
        stack->top = node;
    }

    stack->count++;
    return;

}
int pop(struct Stack * stack)
{
    if (isEmpty(stack)){
        return -1;
    }

    struct Node * node = stack->top;
    stack->top = node->next;

    return node->value;
}

int peek(struct Stack * stack)
{
    if (isEmpty(stack)){
        return -1;
    }

    return stack->top->value;
}


int main(int argc, char * argv[])
{
    struct Stack stack;
    push(&stack, 10);
    push(&stack, 20);
    push(&stack, 30);
    printf("Popped item: %i\n", pop(&stack));
    printf("Peeking at next item: %i\n", peek(&stack));
    printf("Peeking at next item: %i\n", peek(&stack));
    printf("Peeking at next item: %i\n", peek(&stack));
    printf("Popped item: %i\n", pop(&stack));
    printf("Popped item: %i\n", pop(&stack));
    printf("Popped item: %i\n", pop(&stack));
    return 0;
}