← thecodex.expert · The Codex Family of Knowledge

Free · No account · Official sources only

C — Cradle to Mastery

A complete, structured path through C — from Dennis Ritchie's 1972 original to pointers, manual memory management, and the tooling that keeps a C project buildable and debuggable fifty years later. Every lesson points at reference pages already written and verified on this site. Free, no account, no sign-up.

29 lessons 6 stages ~21 hours of reading 10 projects C23 (ISO/IEC 9899:2024) · curriculum current as of 2026
Start Lesson 1 → Browse the reference instead

How this course works

1
Follow the stages in orderEach stage assumes the one before it. Stage 3 in particular assumes Stage 2 cold.
2
Read the tab the lesson namesReference pages have Beginner, Intermediate and Expert tabs. Read only what the lesson asks for on a first pass.
3
Run every exampleKeep the playground open in a second tab. Reading code you have not run is how misunderstandings survive.
4
Build after each stageDo not save all ten projects for the end. Pick one up as soon as a stage gives you enough to attempt it.
Casual pace: ~10 weeks at 4 hours a week
Steady pace: ~5 weeks at 8 hours a week
Intensive: ~2 weeks full-time
STAGE 0

Before You Start

Fifty years old and still underneath nearly every operating system, database engine, and language runtime you will ever use. These two lessons explain why, and get a compiler installed.

LESSON 1

What is C?

Dennis Ritchie built C at Bell Labs to rewrite UNIX — most OSes still run on it

C was created at Bell Labs in the early 1970s so UNIX could be rewritten in something more portable than assembly. That single decision is why C's fingerprints — and often its actual compiled code — sit underneath Linux, Windows, every major database, and the runtime of nearly every higher-level language you have used.

📚 🟩 Read the Beginner tab only.
Key focus: Why C's design as a thin, portable layer over assembly made it the substrate for everything after it.
⏱ 30 min
Required Reading
→
What is C? — The Codex

C's origin at Bell Labs rewriting UNIX, its influence on nearly every later systems language, and where C23 sits today.

LESSON 2

Setup and Compiler

GCC and Clang are the two dominant compilers — both free, both production-grade

There is no single official C toolchain the way there is with some newer languages: GCC and Clang are both free, both mature, and both genuinely used in production, with mostly-compatible command-line flags. Getting one installed and a first file compiled is the entire goal of this lesson.

📚 🟩 Read the Beginner tab only.
Key focus: Installing GCC or Clang, and compiling and running your first C program from the command line.
⏱ 30 min
Required Reading
→
Setup and Compiler — The Codex

Installing GCC/Clang, the compile-then-run two-step C requires, basic flags, and editor/IDE setup.

STAGE 1

Language Fundamentals

The syntax and habits that show up in every C file you will ever write: types, control flow, functions, arrays and strings, recursion, and the manual error-checking C requires of you. Six lessons before pointers properly begin.

LESSON 3

Variables and Types

sizeof(int) isn't guaranteed to be 4 — C only guarantees minimums

C's standard guarantees only *minimum* sizes for its integer types, not exact ones — <code>int</code> is at least 16 bits, in practice almost always 32, but the standard never promises that. This portability-over-precision tradeoff runs through the whole type system and is worth internalizing early.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Why C guarantees minimum type sizes rather than exact ones, and what that means for portable code.
⏱ 45 min
Required Reading
→
Variables and Types — The Codex

Integer and floating-point types, sizeof, signed vs unsigned, type conversion rules, and literal suffixes.

LESSON 4

Control Flow

No real boolean type until C99 — 0 is false, everything else is true

C had no dedicated boolean type until C99's <code>_Bool</code> (later renamed <code>bool</code> via a header). Before and often still after that, <code>0</code> means false and anything nonzero means true — a convention that shows up constantly in real C code and is worth being fully comfortable with.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: The zero-is-false convention that predates a real boolean type, and how it still shapes idiomatic C.
⏱ 45 min
Required Reading
→
Control Flow — The Codex

if/else, for/while/do-while, switch, the zero-is-false convention, and _Bool/bool in modern C.

LESSON 5

Functions

Every argument passes by value — to modify a caller's variable, pass its address

C has no pass-by-reference parameters: every argument is copied by value into the function, full stop. The only way for a function to modify a caller's variable is for the caller to explicitly pass that variable's address, which the function receives as a pointer — the idea the rest of the course builds on.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Why pass-by-value is universal in C, and how passing an address is the only workaround.
⏱ 45 min
Required Reading
→
Functions — The Codex

Function declarations vs definitions, parameters and return types, pass-by-value, and function prototypes.

LESSON 6

Arrays and Strings

A C string is just a char array ending in a zero byte

There is no separate string type in C at all: a string is a <code>char</code> array that happens to end with a zero byte, and every standard string function relies on that convention being upheld. Forgetting the terminator, or writing past the array's bounds, is one of the most common real C bugs.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Why the null terminator is the entire mechanism behind C strings, and what goes wrong when it's missing.
⏱ 1 hours
Required Reading
→
Arrays and Strings — The Codex

Array declarations and indexing, the null-terminated string convention, common string.h functions, and buffer-size bugs.

LESSON 7

Recursion

No tail-call optimization guarantee — deep recursion genuinely risks overflow

Unlike some languages, the C standard makes no guarantee that a compiler will optimize tail-recursive calls into a loop. A recursive function that looks clean on paper can genuinely overflow the call stack in C where an equivalent function in another language would not, which is worth knowing before you rely on it.

📚 ⚡ Intermediate.
Key focus: Why deep recursion is a real, practical risk in C rather than a theoretical one.
⏱ 30 min
Required Reading
→
Recursion — The Codex

Recursive function structure, base cases, the call stack's role, and when to prefer an explicit loop instead.

LESSON 8

Error Handling

No exceptions — checking a return value is entirely on the programmer

C has no exception mechanism: every function that can fail signals it through a return value, an out-parameter, or the global <code>errno</code>, and checking that signal after every single call is entirely the programmer's responsibility. Skipping a check is how real C bugs are born.

📚 ⚡ Intermediate.
Key focus: The discipline C error handling requires, since nothing forces you to check a return value.
⏱ 30 min
Required Reading
→
Error Handling — The Codex

Return-value error conventions, errno, perror, and why every fallible call needs an explicit check.

STAGE 2

Pointers and Memory — C's Defining Discipline

This is the stage that makes C, C: manual memory management, the pointer arithmetic underneath every array, the tools that catch what the compiler won't, and the undefined behaviour that punishes getting it wrong. Seven lessons, the heart of the course.

LESSON 9

Pointers and Memory

Declaration, dereferencing, pointer arithmetic, stack vs heap

A pointer is just a variable holding a memory address, but that simplicity is deceptive: dereferencing, pointer arithmetic, and the stack/heap distinction combine into the single idea that separates C from almost every language you'll learn afterward. This lesson is the foundation the rest of the stage builds on.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: The address-holds-a-value model underneath every pointer operation you'll use from here on.
⏱ 1.25 hours
Required Reading
→
Pointers and Memory — The Codex

Pointer declaration and dereferencing, the & and * operators, pointer arithmetic, and the stack-vs-heap distinction.

LESSON 10

Dynamic Memory Allocation

malloc gives you heap memory; forgetting free() leaks it forever

<code>malloc</code> and <code>free</code> hand memory-management responsibility entirely to you — there is no garbage collector watching for memory you forgot to release. A leak in a long-running C program accumulates silently until it genuinely exhausts available memory.

📚 ⚡ Intermediate.
Key focus: Why every malloc needs a matching free, and what actually happens when that discipline slips.
⏱ 1 hours
Required Reading
→
Dynamic Memory Allocation — The Codex

malloc/calloc/realloc/free, common allocation patterns, and the manual bookkeeping heap memory requires.

LESSON 11

Const and Volatile

const *p and const p* mean genuinely different things

Where the <code>const</code> keyword sits in a pointer declaration changes what it actually protects — a pointer to constant data reads completely differently from a constant pointer to mutable data, and mixing them up is a classic beginner mistake. <code>volatile</code> solves an entirely separate problem.

📚 ⚡ Intermediate.
Key focus: Reading const-pointer declarations correctly, and what volatile actually tells the compiler not to assume.
⏱ 30 min
Required Reading
→
Const and Volatile — The Codex

const placement and what each position protects, top-level vs low-level const, and volatile's role with hardware/signals.

LESSON 12

Function Pointers

A function's code lives at an address too — store it, call through it

A compiled function's code sits at a memory address just like any other data, and C lets you store that address in a variable and call through it later. This is the mechanism behind callbacks, dispatch tables, and every plugin-style API C code has ever offered.

📚 ⚡ Intermediate.
Key focus: Storing and calling through a function's address, and where that pattern shows up in real APIs.
⏱ 45 min
Required Reading
→
Function Pointers — The Codex

Function pointer syntax, typedefs for readability, callback patterns, and dispatch tables.

LESSON 13

Memory Safety Tools

Valgrind and AddressSanitizer catch bugs the compiler never notices

The C compiler will happily accept code that reads freed memory or writes past an array's end — it has no obligation to catch either. Valgrind and AddressSanitizer are separate, genuinely different tools that instrument a running program to catch exactly these bugs at runtime instead.

📚 ⚡ Intermediate.
Key focus: What Valgrind and ASan each actually catch, and why you need both in a real C workflow.
⏱ 45 min
Required Reading
→
Memory Safety Tools — The Codex

Running Valgrind's memcheck, compiling with -fsanitize=address, and reading each tool's output.

LESSON 14

Debugging with GDB

A segfault tells you nothing on its own — GDB finds the line and the pointer

A raw segmentation fault gives you almost no information by itself: which line, which pointer, which call led there. GDB is how you actually answer those questions — breakpoints, stepping, and inspecting a crashed program's stack and variables directly.

📚 ⚡ Intermediate.
Key focus: Turning an opaque segfault into a specific line and a specific bad pointer using GDB.
⏱ 45 min
Required Reading
→
Debugging with GDB — The Codex

Breakpoints, stepping, inspecting variables and the call stack, and examining a core dump after a crash.

LESSON 15

Undefined Behaviour, Tied Together

Buffer overflows, use-after-free, signed overflow — and the tools that catch them

This lesson is the synthesis for the stage: the specific ways C code can invoke undefined behaviour &mdash; buffer overflows, use-after-free, signed integer overflow, unsequenced expressions &mdash; and how the pointer, memory-allocation, and tooling lessons above combine into one coherent defensive practice. Read it once each piece is familiar on its own.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: Seeing pointers, dynamic allocation, and the safety tools above work together against real UB categories.
⏱ 1 hours
Required Reading
→
Undefined Behaviour, Tied Together — The Codex

Common UB categories, why the compiler is allowed to assume UB never happens, and ASan/Valgrind as the practical defense.

STAGE 3

Data Structures

The building blocks C hands you instead of a standard library full of collections: enums, unions, self-referential structs, and the array/struct/function-pointer combination that underlies nearly everything above. Four lessons.

LESSON 16

Enums

A C enum is just named integers — no type safety at all

Unlike some languages' enums, a C <code>enum</code> is nothing more than a set of named integer constants — any <code>int</code> value, including ones with no matching name, can be assigned to an enum variable without complaint from the compiler. Knowing this prevents a false sense of type safety.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Why a C enum provides naming convenience but no actual type-safety guarantee.
⏱ 30 min
Required Reading
→
Enums — The Codex

Enum declarations, implicit integer values, explicit value assignment, and the type-safety gap versus other languages.

LESSON 17

Unions

Every member shares the exact same memory — write one, read another

A <code>union</code>'s members all overlap the same block of memory, so writing through one member and reading through another is a real, sometimes genuinely useful technique — and also a common source of subtle bugs when the active member isn't tracked carefully.

📚 ⚡ Intermediate.
Key focus: The shared-memory model behind a union, and how to track which member is actually active.
⏱ 30 min
Required Reading
→
Unions — The Codex

Union declarations, memory overlap between members, tagged unions for tracking the active member, and common uses.

LESSON 18

Linked Lists

A struct holding a pointer to another instance of itself

A linked list is the classic proof that structs and pointers combine into something bigger than either alone: a struct holding a pointer to another instance of its own type, chained together one allocation at a time. Building one by hand is the single most common way this idea gets internalized.

📚 ⚡ Intermediate.
Key focus: Building and traversing a self-referential struct chain, and managing its memory correctly.
⏱ 1 hours
Required Reading
→
Linked Lists — The Codex

Node struct design, insertion and traversal, freeing every node without leaking, and singly vs doubly linked lists.

LESSON 19

Structs and Arrays, Tied Together

Definition, typedef, nested structs, array decay, and function pointers together

This lesson is the synthesis for the stage: struct definition and member access, <code>typedef</code> for readability, nested structs, how arrays decay to pointers when passed to a function, <code>sizeof</code>'s behavior on each, strings as char arrays, and function pointers as struct members &mdash; all of it combined into the kind of data-modeling code real C projects actually contain.

📚 ⚡ Intermediate.
Key focus: Seeing structs, arrays, string handling, and function pointers work together in realistic data models.
⏱ 1.25 hours
Required Reading
→
Structs and Arrays, Tied Together — The Codex

Struct definitions and typedef, nested structs, array-to-pointer decay, sizeof on structs vs arrays, and function pointers as struct fields.

STAGE 4

Systems and Tooling

What surrounds a C source file before it becomes a running program: the preprocessor, headers, multi-file builds, Makefiles, and the lower-level operators and library functions that round out the language. Seven lessons.

LESSON 20

Header Files

#include literally copy-pastes a header's text — no real module system

There is no module system underneath C's <code>#include</code>: it is a literal, unconditional text-substitution that pastes the named file's contents into yours before real compilation even starts. Understanding this explains include guards, forward declarations, and a surprising number of build errors.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Why #include's copy-paste model makes include guards and forward declarations necessary, not optional.
⏱ 30 min
Required Reading
→
Header Files — The Codex

Header file structure, include guards vs #pragma once, declarations vs definitions, and standard vs local headers.

LESSON 21

Multi-File Projects

Each .c file compiles independently; the linker combines them afterward

A real C project splits code across multiple <code>.c</code> files, each compiled independently into its own object file, with the linker combining those object files into one executable only at the very end. This two-stage model is why a forward declaration in a header is enough to compile against code defined elsewhere.

📚 ⚡ Intermediate.
Key focus: The compile-then-link two-stage model, and how it lets separately compiled files reference each other.
⏱ 45 min
Required Reading
→
Multi-File Projects — The Codex

Translation units, object files, the linker's job, extern declarations, and organizing a multi-file project.

LESSON 22

Makefiles

A tab instead of spaces is the single most common frustration make causes

Make automates rebuilding only what actually changed, based on file timestamps and the dependency rules you write — but its syntax is unforgiving about one specific thing: recipe lines must be indented with a literal tab character, and a stray space there produces a notoriously confusing error.

📚 ⚡ Intermediate.
Key focus: Writing basic Make rules and targets, and avoiding the tab-versus-spaces trap that catches everyone once.
⏱ 30 min
Required Reading
→
Makefiles — The Codex

Targets, dependencies, and recipes, variables in a Makefile, phony targets, and the tab-indentation requirement.

LESSON 23

The Preprocessor

A text-substitution pass that runs before real compilation even starts

The preprocessor handles <code>#include</code>, <code>#define</code>, and conditional compilation directives as a pure text-substitution pass, entirely before the compiler proper ever sees your code. A macro missing parentheses around its parameters is a classic, genuinely real bug this lesson explains how to avoid.

📚 ⚡ Intermediate.
Key focus: Why macros are text substitution, not function calls, and the parenthesization bugs that follow from that.
⏱ 45 min
Required Reading
→
The Preprocessor — The Codex

#define object-like and function-like macros, conditional compilation (#ifdef/#ifndef), and common macro pitfalls.

LESSON 24

Bitwise Operations

Six operators behind flags, masks, and embedded register access

C's six bitwise operators — AND, OR, XOR, NOT, and the two shifts — manipulate individual bits directly, which is exactly what flag combinations, bitmasks, and direct hardware register access all require. This is a genuinely low-level tool most higher-level languages hide from you entirely.

📚 ⚡ Intermediate.
Key focus: Reading and writing bitmask and flag-combination code using C's six bitwise operators.
⏱ 30 min
Required Reading
→
Bitwise Operations — The Codex

&, |, ^, ~, <<, >>, bitmasking and flag combinations, and setting/clearing/toggling individual bits.

LESSON 25

Variadic Functions

printf accepts any number of arguments — stdarg.h makes that possible

<code>printf</code>'s ability to accept any number of arguments of varying types is not a compiler special case: it is built on <code>stdarg.h</code>'s macros, which any C function can use to accept its own variable-length argument list the same way.

📚 ⚡ Intermediate.
Key focus: How stdarg.h's macros let an ordinary C function accept a variable number of arguments.
⏱ 30 min
Required Reading
→
Variadic Functions — The Codex

va_list, va_start/va_arg/va_end, writing your own variadic function, and why the caller must communicate the count.

LESSON 26

The Standard Library

A deliberately small set of headers covering only what's truly universal

C's standard library is intentionally minimal compared to most modern languages — stdlib.h, ctype.h, math.h and a handful of others cover only what the standard considers genuinely universal, leaving everything else to third-party libraries or the operating system directly.

📚 ⚡ Intermediate.
Key focus: Which standard headers cover which universally-needed functionality, and what's deliberately left out.
⏱ 45 min
Required Reading
→
The Standard Library — The Codex

stdlib.h (allocation, conversion, sorting), ctype.h, math.h, string.h recap, and the library's deliberately narrow scope.

STAGE 5

Files, Concurrency and Standards

Reading and writing real files, running work across real threads, and the fifty-year history of standards that got C here. Three lessons to close out the course.

LESSON 27

File I/O

fopen, fread, fwrite, fclose — four functions older than most languages

C's file I/O functions — <code>fopen</code>, <code>fread</code>, <code>fwrite</code>, <code>fclose</code> — predate nearly every other language's own file APIs, and most of those later APIs are themselves thin wrappers around similar underlying system calls. Learning these four functions well pays off widely.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: The four-function core of C file I/O, and the buffering behavior underneath them.
⏱ 45 min
Required Reading
→
File I/O — The Codex

fopen modes, fread/fwrite for binary data, fprintf/fscanf for text, and always checking for a NULL FILE*.

LESSON 28

Concurrency

C11 added a standard threading library — but pthreads is what people actually use

C11 technically standardized <code>&lt;threads.h&gt;</code>, but in practice almost every real C codebase reaches for POSIX threads (pthreads) instead, since it predates the standard, is more widely supported, and is what existing code and tutorials already use.

📚 ⚡ Intermediate.
Key focus: Why pthreads remains the practical default even though C11 standardized its own threading API.
⏱ 45 min
Required Reading
→
Concurrency — The Codex

pthread_create/join, mutexes for shared-state protection, and why <threads.h> hasn't displaced pthreads in practice.

LESSON 29

C Standards History

From an unofficial 1978 book to a formal 2024 ISO standard

C's standards history runs from K&R's original 1978 book — never itself a formal standard — through ANSI C89/C90, C99, C11, C17, and now C23, each a genuinely different, ratified version with its own feature set. Knowing which era a piece of code targets explains a lot about why it looks the way it does.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: The seven real, distinct versions of C, and what each one specifically added or changed.
⏱ 30 min
Required Reading
→
C Standards History — The Codex

K&R C, ANSI C89/C90, C99's major additions, C11, C17, and C23's most recent changes.

STAGE 6

Concepts That Cross Languages

These pages explain ideas that are not specific to C — they apply to every language you will ever learn. Read them once and the next language costs you far less effort. They pair well with the lessons above rather than replacing them.

STAGE 7

Build Real Things — 10 Projects

Reading is not enough. These 10 projects — five basic, five medium — are chosen because each one exercises something specific you learned above, and because they are genuinely idiomatic C rather than generic exercises. Each link below opens the project brief; the C implementation walkthrough is in progress.

BASIC — 5 PROJECTS
→
Number Guessing Game

scanf input parsing, a manual guess loop, and rand()/srand() for the secret number.

→
Temperature Converter

A small switch statement for the conversion direction, and printf format specifiers.

→
Word Counter

Reading a file byte-by-byte with fopen/fgetc, and a hand-rolled hash table for word frequency.

→
To-Do List (CLI)

A struct array for tasks, and manual line-based persistence with fread/fwrite.

→
Password Generator

A flag-based character-set selection, and a review of why rand() is unsuitable for real security.

MEDIUM — 5 PROJECTS
→
Web Scraper

A raw TCP socket and hand-written HTTP request, since C ships no HTTP client at all.

→
REST API

A minimal HTTP server over raw sockets, with hand-parsed request lines and manual response formatting.

→
CLI Task Manager

A tagged union for subcommands, and a switch over the tag the compiler can't check for exhaustiveness.

→
URL Shortener

A fixed-size open-addressing hash table for the code-to-URL mapping, with pthread mutexes for thread safety.

→
Log Analyser

Line-by-line parsing with sscanf, and a simple linked-list-based counter for top-N aggregation.

STAGE 8

Practice & Experimentation

Ongoing, not a final step. Use these throughout the course — try every snippet you read, and run anything you are unsure about rather than assuming.

Resources
→
C Playground

Run C code without installing anything, via the official C Playground.

→
C Snippets

Copy-ready idiomatic patterns to keep beside you while you build.

→
C Reference Hub

All 29 topic pages in one index, for looking things up later.