Procedural Programming with C · Course Plan

Course Plan

A complete course in C: fifty-six weekly topics taking a reader from no prior programming experience to competent, independent, professional C development. This page sets out what the course covers, what it assumes, what it needs, and how it is built.

At a glance
  • 56 weekly topics in four levels of fourteen.
  • Basic — the language core, ending with pointers and strings.
  • Intermediate — memory, aggregate data, files, errors, modular design.
  • Advanced — libraries and tooling, data structures, performance, portability, systems, networking, concurrency.
  • Professional — codebases, collaboration, distribution, interoperability, security, embedded, maintenance.

1Aim

C is used in operating systems, embedded software, compilers, databases, and every performance-sensitive layer beneath higher-level languages. It gives direct control over memory representation and execution, and it gives no protection against getting that control wrong.

The aim of this course is therefore not only to teach the language — that is the first fourteen weeks — but the discipline that makes writing C in production tractable: warnings treated as defects, sanitizers run by default, every return value checked, ownership stated in every interface, and the difference between what happens to work and what is actually guaranteed.

Each topic assumes only what earlier topics have established. Nothing is used before it is explained, and the chain of dependencies is deliberate: pointers arrive before strings, memory layout before recursion, structures before the standard library that uses them.

2Prerequisites

No prior programming experience is assumed. What is assumed:

  • Comfort creating, saving, and organizing files, and basic terminal navigation.
  • Arithmetic, and the ability to break a task into ordered steps.
  • A computer running Linux, macOS, or Windows with WSL.

Two preparatory documents are available: prerequisites for preparation and key figures who shaped the field.

3Learning outcomes

AfterYou can
Basic (1–14)Write, build, format, debug and version a C program; explain how values are represented; use every control structure; work with pointers, arrays and strings.
Intermediate (15–28)Manage heap memory without leaking; design aggregate types; read and write files; define an error contract; split a program into modules with a hidden implementation.
Advanced (29–42)Build and ship libraries; write generic code; implement the standard data structures; profile and optimize with evidence; avoid undefined behavior; write portable, networked and concurrent programs.
Professional (43–56)Work in an unfamiliar codebase; review C for memory safety; distribute a library with a stable ABI; call it from other languages; fuzz it; write bare-metal firmware; maintain code that outlives its authors.

4Tooling

Everything used in the course is free and cross-platform. Nothing requires physical hardware.

From weekToolPurpose
1GCC or Clang, a text editorCompiling
3Git, clang-formatVersion control, formatting
12AddressSanitizer, UBSanMemory and undefined-behavior detection
20ValgrindLeaks, uninitialized reads
29Make, CMake, nm, objdumpBuilding, inspecting binaries
34perf, Compiler ExplorerProfiling, reading generated code
35GDB, gcov, -fanalyzerDebugging, coverage, static analysis
48libFuzzer, AFL++Fuzzing
49arm-none-eabi-gcc, QEMU, gdb-multiarchCross-compiling and running bare-metal firmware

The embedded block needs no hardware. Weeks 49 to 55 target an ARM Cortex-M image running under QEMU, so every example — including the interrupt timing, the linker layout, and the debugger sessions — can be built and run on any laptop. The same code and the same GDB commands work unchanged against a real board with a debug probe.

A single command line is used throughout and introduced in week 2:

gcc -std=c17 -Wall -Wextra -g -fsanitize=address,undefined -o prog prog.c

5How each week is structured

Every week's notes follow the same shape, so the material can be navigated without re-reading:

  1. What you can do by the end — five concrete capabilities.
  2. The concepts — several numbered sections, with diagrams where a picture carries the idea.
  3. A worked example — a complete, compilable program with the commands to build and run it, and experiments that break it deliberately to show the failure mode.
  4. Common mistakes — a table of what goes wrong, what the symptom looks like, and the fix.
  5. Check yourself — five questions with answers hidden until you have tried them.
  6. Where this leads — the connection to the following week.

The worked examples are the spine of the course. They are not exercises to be submitted; they are the artifact the notes build, and they are meant to be typed, compiled, and broken.

6The chain of examples

The examples are deliberately connected, so that each week extends something already understood rather than starting over:

week 11  a swap function that cannot work
week 13  the same function, fixed with pointers

week 19  a growable array on the heap
week 20  the same array, seeded with five memory defects
week 28  the same array as a module with a hidden implementation
week 29  the same module as a static and a shared library
week 30  the same container, made generic over any type
week 45  the same library, versioned and installable
week 46  the same library, called from Python, Rust and C++

week 23  a validating input parser
week 48  the same parser, attacked by a fuzzer

week 40  a TCP server, one forked process per connection
week 47  the same server, rewritten as a single-threaded event loop

week 49  a bare-metal image printing over a UART
week 50  the same UART, as a driver written against the register map
week 51  the same driver, interrupt-driven
week 55  the same driver, behind a HAL and unit-tested on the host

7Outline

Basic — the language core

WeekTopic
1Computers, Programs, and the C Toolchain
2History, Standards, and the Compilation Model
3Program Structure, Style, and Basic Output
4Data Representation
5Variables, Types, and Constants
6Operators and Expressions
7Type Conversions
8Formatted Input and Output
9Conditional Statements
10Loops and Flow Control
11Functions
12One- and Multi-Dimensional Arrays
13Introduction to Pointers
14Strings and Character Handling

Intermediate — memory, data, and structure

WeekTopic
15Pointer Arithmetic and Arrays
16Pointers as Function Parameters
17Scope, Lifetime, and Program Memory Layout
18Recursion
19Dynamic Memory Allocation
20Memory Errors and Their Diagnosis
21Structures
22Unions, Enumerations, and Type Aliases
23Program Arguments and Input
24The Standard Library Toolbox
25Bit-Level Operations
26Files and Streams
27Error Handling Strategies
28The Preprocessor and Modular Programming

Advanced — tooling, systems, and scale

WeekTopic
29Building Programs and Libraries
30Function Pointers, Callbacks, and Generic Programming
31Command-Line Interfaces and the Environment
32Linked Data Structures
33Trees, Hash Tables, and Abstract Data Types
34Performance and Memory Layout
35Debugging, Testing, and Analysis
36Undefined Behavior and Secure Coding
37Portability and the Machine Model
38Type Qualifiers, Inlining, and Modern C
39Processes, Signals, and Low-Level I/O
40Network Programming with Sockets
41Concurrency and the C Memory Model
42Reading Excellent C

Professional — practice, distribution, and embedded

WeekTopic
43Working in an Existing Codebase
44Collaborative Development and Code Review
45Packaging and Distributing C Libraries
46ABI and Interfacing with Other Languages
47Event-Driven and Scalable I/O
48Fuzzing and Security Testing
49Embedded C and Cross-Compilation
50Memory-Mapped I/O and Hardware Registers
51Interrupts and Real-Time Behavior
52Linker Scripts and Firmware Memory Layout
53Constrained-Resource Programming
54Real-Time Operating Systems
55Embedded Debugging and Testing
56Maintaining Long-Lived C Codebases

8Scope

Two boundaries are worth stating explicitly.

The course targets C17 by default, with C23 features identified where they differ. C89 and C99 are covered historically in week 2 because a great deal of existing code is written in them.

The hosted material assumes a POSIX environment — Linux, macOS, or WSL. Weeks 39, 40, 41 and 47 use POSIX interfaces that are not part of standard C; this is stated wherever it applies. Weeks 49 to 55 are freestanding and assume no operating system at all.

Not covered: C++ (a different language with different idioms), graphical interfaces, and language-specific build ecosystems beyond Make and CMake.

9References

KindSource
Referencecppreference — C; version-specific and accurate
TutorialBeej's Guide to C Programming
Questionscomp.lang.c FAQ
StandardWG14 — the working drafts are freely available
ToolsGCC, GDB, Valgrind, Compiler Explorer
PracticeLearn-C.org, Exercism C track
Code to readmusl libc, SQLite, Lua, Redis, git — week 42

Week 24 covers how to read a manual page and the text of the standard, which is the skill these references exist to support.