C Mastery / Enums and Typedef
Part 1 — The Core Language

Enums and Typedef

This chapter covers enum (named integer constants) and typedef (type aliases). Typedef is the tool for reading and writing complex declarations, especially function pointers.

Why This Matters

Enums give meaning to integer values and are the backbone of state machines and flags. Typedefs make complex types readable and maintainable — and, used well, are the difference between code you can read and code you cannot.

Prerequisites

Core Concept

Enums

An enum declares a set of named integer constants:

enum Color { RED, GREEN, BLUE };

RED, GREEN, and BLUE are constants of type int with values 0, 1, 2 by default. You can assign explicit values:

enum Color { RED = 1, GREEN = 5, BLUE = 9 };

If a value is omitted, it continues from the previous value + 1.

The enum *type* (enum Color) is compatible with some implementation-defined integer type (usually int if all values fit). The constants themselves are int.

Flags with enums

Use power-of-two values for bit flags:

enum Perm {
    PERM_READ  = 1 << 0,
    PERM_WRITE = 1 << 1,
    PERM_EXEC  = 1 << 2,
};

Combine with |, test with &.

Typedef

typedef creates an alias for a type:

typedef unsigned long size_t;
typedef struct Node Node;
typedef int (*cmp_fn)(const void *, const void *);

After typedef, the alias can be used anywhere the original type could.

Syntax

enum Name { CONST1, CONST2 = value, CONST3 };
typedef existing_type alias_name;

Examples

Basic enum

#include <stdio.h>

enum Status { STATUS_OK, STATUS_ERROR, STATUS_PENDING };

int main(void)
{
    enum Status s = STATUS_OK;
    printf("%d\n", s);
    return 0;
}

Expected output: 0.

Function-pointer typedef

typedef int (*binary_op)(int, int);

int add(int a, int b) { return a + b; }

int apply(binary_op op, int x, int y)
{
    return op(x, y);
}

int main(void)
{
    return apply(add, 2, 3);   /* returns 5 */
}

Without the typedef, binary_op would be written inline as int (*)(int, int), which is hard to read and easy to get wrong.

Struct typedef

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

Node *head;   /* clearer than struct Node *head */

How It Works

Enums are a compile-time mapping from names to integer constants. Typedefs are compile-time aliases; they produce no code and reserve no storage. Both are resolved entirely by the compiler.

Variations

Typedef vs. #define

typedef is handled by the compiler and understands types; #define is a textual replacement done by the preprocessor. Prefer typedef for types and enum/const for constants over macros.

Pointer typedefs and const

typedef int *int_ptr;
const int_ptr p;    /* p is a const pointer to int (int *const), NOT int const * */

This is a common trap: const applies to the whole typedef'd type, so const int_ptr is int *const, not const int *.

Common Mistakes

(in C, they are int constants; C++ differs).

Undefined Behavior

implementation-defined (the enum type is an integer type; the set of values it can represent is implementation-defined).

when used in arithmetic.

Portability

implementation-defined but must be able to represent all enumerators.

char`), but this is C23-only.

Under the Hood

Enums are just integers in generated code; the names exist only at compile time. Typedefs are erased before code generation; they exist only in the compiler's type system.

Practical Usage

Exercises

1. Define an enum for HTTP-like status codes with explicit values and print them. 2. Define a bit-flag enum and write set/clear/test functions. 3. Write a function-pointer typedef for a comparator and use it with a simple sort. 4. Demonstrate the const int_ptr vs const int * distinction.

Deep Challenge

Build a small table-driven state machine using an enum for states and a function-pointer typedef for transitions. Explain why enums + function pointers together form a clean, extensible design.

References

Verification

verified.`

Progress

Concept checkboxes

Mastery levels

ConceptCurrent level (0–8)Target level
c.enum.decl05
c.typedef.basic05
c.typedef.ptr05
c.typedef.fnptr05