From understanding how compilation works and reading gcc warnings through variables and control flow, functions and arrays, pointers, malloc and free, structs and linked lists, files and make, and system calls. Across 50 lessons, you'll manage pointers and memory yourself and write a working simple shell. Every line of code, warning, and sanitizer report has been run live with gcc 16.2.0 (C23).
All 50 lessons are divided into 7 chapters. It's best to work through chapter 1 first, but you can also skip around to topics that interest you. Note: You can't run C in a browser, so use the gcc 16 Docker container we provide in lesson 2, or gcc on Linux/WSL. Chapter 7's system calls require Linux.
Start with the 4 stages of compilation and gcc warnings, then move through variables and types, operators, standard I/O, conditional branching, and loops. Build the habit here of running your code through gcc and letting warnings and sanitizers catch mistakes.
Split code into functions and understand scope and lifetime. Move through arrays, strings, and multidimensional arrays, and verify that sanitizers catch reading beyond array bounds.
Work through addresses and pointers, pointer arithmetic, how arrays and strings relate, const, function pointers, and pointers to pointers. Finally, see how null and dangling pointers break things with sanitizers.
Draw a map of stack and heap, borrow and return memory with malloc, calloc, realloc, and free. Catch leaks, use-after-free, double free, and buffer overflow with LeakSanitizer, valgrind, and AddressSanitizer.
Group data with structs, see memory layout with padding, unions, and enums. Finally, build linked lists, stacks, and queues in C, combining pointers and memory management.
Handle text and binary file I/O, separate compilation with headers, make, the preprocessor, and static and shared libraries. Finally, read command-line arguments with getopt and shape your program as a real tool.
Peek at system calls open, read, write with strace, then operate on processes with fork, exec, pipe, and signals. Finish by bringing together everything and building a simple shell that uses pipes and redirects.
After you finish all 50 lessons, take what you've built with manual memory management and move to languages that protect memory for you in the Rust Intro Course, or explore what lies beyond system calls and shells in the Linux Intro Course and Linux System Admin Intro Course. Membership unlocks all courses.