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.

Beta

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.

39 lessons 19 hours

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.

Become a Patron

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.

1
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

2
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

3
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

4
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

5
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.

1
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

2
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

3
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

4
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

5
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

6
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.

1
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

2
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

3
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

4
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

5
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.

1
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

2
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

3
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

4
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

5
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

6
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.

1
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

2
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

3
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

4
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

5
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

6
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.

1
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

2
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

3
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

4
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

5
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.

1
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

2
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

3
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

4
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

5
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

6
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