Sign up to track your progress
Create an account to save your progress, complete exercises, and earn achievements.
C Fundamentals
Learn C from your very first program with memory as your map: see where variables live, follow the call stack, and master pointers and dynamic memory early instead of last. Arrays, strings, structs, and error handling all build on that same picture, with undefined behaviour called by its name and AddressSanitizer checking every program you run.
This course is in beta. You get early access while we're still writing and refining it, so lessons may change, and new content is added regularly. Spotted a problem? Feedback is welcome.
Support Free C++ Education
Help us keep this platform free for everyone! Your support enables us to create more high-quality lessons, exercises, and interactive content.
Course Curriculum
Programs, Variables, and Memory (5 lessons)
What a C program is, how it is compiled and run, how variables occupy bytes of memory, what an address is, and how to read input with the memory model established from lesson one.
Your First C Program
What a program is, how gcc turns hello.c into something the machine can run, the anatomy of main, printing your first lines with printf, and reading your first compiler warning as the bug report it is.
25 minutes
Variables Are Bytes in Memory
A declaration reserves bytes of memory: int and double, assignment, sizeof, and why an uninitialized variable holds undefined behaviour rather than zero.
30 minutes
Addresses and the Stack
Every byte of memory has an address: reveal where your variables live with the & operator and %p, and build the picture of the stack the rest of the course sits on.
25 minutes
Reading Input with scanf
Read numbers from standard input with scanf, see why it needs &x (a real address to write into), and meet its return value, the conversion count you will learn to act on in chapter 2.
30 minutes
Chapter 1 Summary and Quiz
Review the compile-and-run pipeline, variables as named memory, addresses and the stack, and reading input with scanf.
20 minutes
Data, Operators, and Control Flow (6 lessons)
How C's types interpret the bytes underneath them, conversions and casts, the operators that combine values, bit manipulation, and the branches and loops that steer a program.
Integers, Conversions, and stdint.h
C's integer types as interpretations of bytes: signed and unsigned, char as a small integer, what happens when int meets double, casts, the fixed-width types in stdint.h, and why signed overflow is undefined behaviour.
35 minutes
Operators, Expressions, and Constants
Arithmetic operators, integer division and remainder, precedence and when to reach for parentheses, increment and decrement, the evaluation-order traps, and naming fixed values with const instead of magic numbers.
30 minutes
Bits and Bitwise Operators
Look one level below the types: binary representation, AND, OR, XOR, NOT, and the shift operators, and why bit manipulation belongs on unsigned types.
30 minutes
Branching with if and switch
Comparison and logical operators, if and else chains, the = versus == slip the compiler warns about, switch with deliberate break placement, and your first real use of scanf's return value to reject bad input.
30 minutes
Repeating with Loops
while, for, and do-while, break and continue, the off-by-one mistakes loop conditions invite, and reading input until scanf stops converting.
30 minutes
Chapter 2 Summary and Quiz
Review the integer types and conversions, operators and named constants, bitwise operations, and the branching and looping constructs.
20 minutes
Functions and the Call Stack (5 lessons)
Break programs into functions, watch the stack grow and shrink beneath every call, then take your first pointers: pass addresses so a function can reach memory that is not its own.
Writing Functions
Declare, define, and call your own functions: prototypes, parameters, return values, void, and the fact that every argument arrives as a copy.
30 minutes
The Call Stack and Recursion
Every call pushes a frame holding its own copies of parameters and locals, and returning pops it: the picture that makes pass-by-value obvious and recursion unmysterious.
30 minutes
Pointers: Passing Addresses Around
Declare pointers, take addresses with &, dereference with *, respect NULL, and hand a function a pointer so it can modify the caller's variable, the pattern scanf has used all along.
35 minutes
Lifetime and Dangling Pointers
Scope versus lifetime, automatic storage, static locals that persist between calls, and why returning the address of a local leaves a dangling pointer whose use is undefined behaviour.
25 minutes
Chapter 3 Summary and Quiz
Review function declarations and pass-by-value, the stack-frame model of calls and recursion, pointer syntax and out-parameters, and the lifetime rules.
20 minutes
Arrays and Dynamic Memory (6 lessons)
Contiguous memory in both of its homes: fixed-size arrays on the stack, pointer arithmetic and decay, then the heap with malloc, free, ownership, and the AddressSanitizer reports that pinpoint every slip.
Arrays: Contiguous Memory
Declare and loop over arrays, keep the length alongside the data, and see why reading or writing past the end is undefined behaviour that AddressSanitizer catches at run time.
30 minutes
Pointer Arithmetic and Array Decay
An array name decays to a pointer to its first element and ptr + i steps by whole elements, so you can walk arrays with pointers and pass them to functions alongside an explicit length.
30 minutes
The Heap: malloc and free
Allocate memory whose size is only known at run time: malloc with sizeof, checking for NULL before use, working with the block, and giving it back with free exactly once.
35 minutes
Ownership and Leaks
Every allocation needs exactly one owner and exactly one free: leaks, double free, and use-after-free named as the undefined behaviour they are, and the discipline that prevents all three.
25 minutes
Reading AddressSanitizer Reports
Decode the reports the sandbox prints for heap-buffer-overflow, use-after-free, and leaks (which line failed, where the memory was allocated and freed), then fix a broken program using only its report.
30 minutes
Chapter 4 Summary and Quiz
Review arrays and bounds, decay and pointer arithmetic, the malloc and free contract, the single-owner rule, and how to read an AddressSanitizer report.
20 minutes
Strings (6 lessons)
C strings are arrays of char ending in a null terminator, which is why they had to wait for pointers and arrays: read, compare, copy, and parse them on the stack and the heap, then grow buffers with realloc as input arrives.
C Strings and the Null Terminator
A string is a char array ending in a null byte: string literals, iterating to the terminator, and what becomes undefined when the terminator is missing.
30 minutes
The String Library
strlen, strcmp, and copying with the destination size in hand: why plain strcpy overflows buffers, and the safe copying patterns built on snprintf.
30 minutes
Reading Lines with fgets
Read whole lines safely with fgets, strip the trailing newline, and parse fields out with sscanf: the input pattern that replaces unbounded scanf string reads.
30 minutes
Strings on the Heap
Allocate string buffers with malloc when the length is only known at run time, remember the extra byte for the terminator, copy into them safely, and free them under chapter 4's ownership rules.
30 minutes
Growing Buffers with realloc
Grow an allocation as input arrives with realloc, handle its failure without leaking the original buffer, and build a program that reads input whose length nothing announced in advance.
30 minutes
Chapter 5 Summary and Quiz
Review the null-terminator contract, the string library and its pitfalls, line-based input with fgets, and heap-allocated strings grown with realloc.
20 minutes
Structs, Enums, and Program Organization (5 lessons)
Group related bytes into structs and see their real memory layout, name your program's states with enums, meet unions, and learn how real C programs split into headers and source files.
Structs: Grouping Related Data
Define struct types, initialize them with designated initializers, access members, and inspect the real memory layout of a struct, padding included.
35 minutes
Structs, Pointers, and the Heap
Pass structs to functions by pointer with the arrow operator, build arrays of structs, and allocate structs with malloc: everything from chapters 3 and 4 applied to aggregate data.
30 minutes
Enums and Unions
Name your program's states with enum and switch over them exhaustively, then meet union as members sharing the same bytes and the obligation to track which member is live.
25 minutes
Headers and Multi-File Programs
How real projects split into header and source files (include guards, declarations versus definitions, extern and static linkage), taught as a mental model, since exercises on this platform stay single-file.
25 minutes
Chapter 6 Summary and Quiz
Review struct definition and layout, pointer access and heap-allocated structs, enums and unions, and how multi-file programs are organized.
20 minutes
Floating Point, Errors, and Undefined Behaviour (6 lessons)
The details that separate working C from robust C: floating-point behaviour and tolerant comparison, failure reporting with return codes and errno, assert and diagnostics, the full undefined behaviour catalogue, and a capstone program that puts the whole course together.
Floating Point in Depth
Why 0.1 + 0.2 is not 0.3: how floating point actually represents numbers, comparing with a tolerance instead of ==, and choosing between float and double.
25 minutes
Handling Failure
Report failure with return codes, understand errno and perror, check every malloc and I/O call, and keep a single cleanup path that releases everything acquired.
30 minutes
assert and Reading Diagnostics
State invariants with assert, treat compiler warnings as errors in spirit, and practice reading gcc and AddressSanitizer output as diagnostics rather than noise.
25 minutes
The Undefined Behaviour Catalogue
The full list in one place, from uninitialized reads and signed overflow to out-of-bounds access, null and dangling dereference, double free, and unsequenced modification: why the standard promises nothing, and which of these the sanitizer can and cannot catch.
35 minutes
Capstone: A Complete Program
Bring it all together in one program with structs, heap allocation, string parsing, and error handling, memory-clean under AddressSanitizer from the first run.
35 minutes
Chapter 7 Summary and Quiz
Review floating-point comparison, failure reporting and cleanup paths, assert and diagnostics, and the undefined behaviour catalogue that closes out the course.
20 minutes