Unit 1 · Lesson 618 minAcademic review pending

What a stack is actually for

Checking whether brackets are balanced is the clearest demonstration of why LIFO order matters — the most recent open bracket must be the next one closed.

Choose explanation

After this lesson

You should be able to

  • Use a stack to check whether brackets in an expression are balanced.
  • Explain why a counter alone cannot detect mismatched bracket types.
  • Trace postfix expression evaluation using a stack.

Try it before you read

Try it live

stack.ctop = -1

Stack is empty — top = -1. pop() has nothing to remove.

01

Why a simple counter is not enough

A first instinct is to count opening and closing brackets and check the counts match. That misses ([)] — three opens, three closes, counts equal, yet clearly wrong, because the ] closes before the ( that is still open.

What actually matters is order, specifically nesting order — and nesting is exactly what a stack tracks. The most recently opened bracket must be the next one closed, which is LIFO order stated in different words.

02

Push on open, match on close

Scan the expression once. On an opening bracket, push it. On a closing bracket, pop and check that it matches the type just popped — a ) must match an opening ( that came off the top, not an opening [ or {.

Two failure conditions, checked in order: popping from an empty stack means a closing bracket had no opener — too many closes. A non-empty stack when the string ends means an opener was never closed — too many opens.

Reused push/pop from Lesson 5, applied to three bracket types
int is_balanced(const char *expr)
{
    char data[100];
    int  top = -1;

    for (int i = 0; expr[i] != '\0'; i++) {
        char c = expr[i];

        if (c == '(' || c == '[' || c == '{') {
            data[++top] = c;
        } else if (c == ')' || c == ']' || c == '}') {
            if (top == -1) return 0;              /* too many closes */

            char open = data[top--];
            if ((c == ')' && open != '(') ||
                (c == ']' && open != '[') ||
                (c == '}' && open != '{'))
                return 0;                          /* wrong type */
        }
    }

    return top == -1;   /* every opener must have been matched */
}
03

Postfix evaluation: the other classic use

In postfix notation, operators come after their operands: 3 4 + means 3 + 4. Evaluating it needs a stack too: push numbers as you meet them, and on an operator, pop twice, apply the operator, and push the result back.

Trace 3 4 + 5 * by hand: push 3, push 4, see +, pop 4 and 3, push 7, push 5, see *, pop 5 and 7, push 35. One value remains on the stack at the end — the answer.

Try it yourself

Extend the balance checker into a full program that reads an expression and reports exactly which character caused the failure, if any.

Need a hint?

Return the index of the failure instead of a plain 0 or 1, and use a sentinel like -1 for success.

Check the worked solution

Returning an index rather than a boolean means the two failure paths — too many closes and a mismatched type — must each report exactly where in the string they happened, which is more useful than the plain yes/no from the lesson's version. Every opener still needing a matching closer at the end is reported by whatever position the loop had reached, not a bracket position, since nothing in the string itself marked the failure.

#include <stdio.h>

int check_balance(const char *expr)
{
    char data[100];
    int  top = -1;

    for (int i = 0; expr[i] != '\0'; i++) {
        char c = expr[i];

        if (c == '(' || c == '[' || c == '{') {
            data[++top] = c;
        } else if (c == ')' || c == ']' || c == '}') {
            if (top == -1) return i;

            char open = data[top--];
            if ((c == ')' && open != '(') ||
                (c == ']' && open != '[') ||
                (c == '}' && open != '{'))
                return i;
        }
    }

    return top == -1 ? -1 : (int) top;
}

int main(void)
{
    char expr[100];
    printf("Enter an expression: ");
    scanf("%s", expr);

    int result = check_balance(expr);
    if (result == -1)
        printf("Balanced\n");
    else
        printf("Unbalanced near position %d\n", result);

    return 0;
}

Quick check

Why does a plain count of opening and closing brackets fail to validate "([)]"?

Select an answer to check your thinking.

Why this lesson exists

Syllabus mapping

Stack applications

Maps to course outcomes CO1, CO3, CO4.