How to read this book — reading paths by level
The standard this book was written to is reading it front to back. The order of the chapters is the order of the explanation, and a later chapter stands on the vocabulary and the pictures an earlier one put up. That is the one order the book assumes of itself.
Readers, though, arrive in different circumstances — different levels, different needs right now, different places to put the language to work. So take from it what suits your level and your purpose. Learning from scratch, the written order is the comfortable one; already writing C, picking the chapters and parts you need is perfectly fine. Between those lie several levels — someone fluent in another language, someone rebuilding what they learned long ago, someone heading for embedded work.
The four paths below are shortcuts set down for such readers to choose from. They are not instructions to follow; pick whichever sits nearest your own position.
★ Whichever path you pick, though, there is one stretch not to trim: Parts I and II.
Those two parts are the most important content in this book. How the machine handles memory, how numbers and letters are represented, what translation and optimisation actually do — all the rest of C stands on what those two parts cover. Why a pointer is not just a number, why integers wrap, why the compiler does not do what you wrote: the answers to the questions you will meet later are already here. The difference between knowing those two parts whole and not knowing them widens over the eleven parts that follow.
An experienced reader will already know much of what is in them. Even so, please make sure nothing is missing before moving on. Skim, but check each chapter’s goals and recap; where something is new, or is something you “knew but never knew why”, read that chapter properly. When you get stuck later, the root is usually one empty slot left behind in these two parts.
★★ And one more thing to remember, whatever you pick — a chapter you skipped is not “gone” but “a place to come back to when you need it”. The #chref links in the text keep pointing at those places. Go round once by a shortcut and then read again in the written order: it goes much faster then, and the things you passed over fall into place.
Path ① — programming is new to you#
This path is the written order itself — the book’s own. There is nothing to pick out, so what follows are a few words about pace instead.
Parts I and II are fifteen chapters with almost no code, and exhausting yourself there costs you the rest of the book. The aim in those two parts is not mastery but familiarity — memory has addresses, integers wrap, reals are approximations. Those three are enough; the rest returns later with code beside it.
| Stretch | What to mind |
|---|---|
| chapters 1–15 (Parts I–II) | familiarity is the goal; do not memorise |
| chapters 16–26 (Parts III–V) | ★ type it out from here. Enter each example, then change one line |
| chapters 27–35 (Part VI) | integers and conversions — the book’s first field of traps |
| chapters 36–46 (Part VII) | the steepest stretch. If pressed, rest once here |
| chapters 47–54 (Parts VIII–IX) | structs and contracts. “why was it settled this way” starts to be audible |
| chapters 55–66 (Part X) | the program’s outside — linking, names, the preprocessor |
| chapters 67–89 (Part XI) | look things up rather than read through. No need to finish it |
| chapters 90–100 (Part XII) | the earlier discipline seen again in a real library |
| chapters 101–105 (Part XIII) | the working world, and the next step |
Table 0.1 — The beginner’s pace
Path ② — you know another language, C is new#
The path for someone who has used a language that hides memory — Python, JavaScript, Java. The syntax reads quickly, but what this book really offers is not syntax; it is memory and contracts.
- All of Parts I and II — do not skip them. chapters 3–5, addresses and the kinds of memory, are this language’s world-view, and in chapters 6–7, wrap-around and approximation, is where accidents you never met in the other language begin. Move fast through what you know, but go through it checking that nothing is missing.
- chapters 16–26 — skim the syntax quickly.
- chapters 36–46 — ★ slowly. Pointers, lifetime and ownership are the heart of this path.
- chapters 53–54 — contracts and undefined behaviour. Here you learn precisely what “no runtime is going to stop you” means.
- From chapter 66 on — look things up as needed.
Safe to skip: the control-flow syntax of chapters 32–33. Do look at switch fall-through (chapter 32) though — it differs from other languages.
Path ③ — you have written C, and want to do it properly#
The most common reader. This path fills in “I write code that works but I do not know why it does”.
★ So this path begins by going through Parts I and II first, because most of the “why” lives there. Much of it will be familiar, so move fast — but check each chapter’s goals and recap and make sure nothing is missing. If the questions in the table below feel hazy, their root is usually in those two parts as well.
| Probably hazy | Where to go |
|---|---|
| integer promotion and the usual arithmetic conversions | chapter 30 and appendix C |
| why an array is not a pointer | chapters 40–41 |
lifetime, storage duration, the two meanings of static | chapters 45 and 58 |
what const, volatile and restrict actually promise | chapters 27 and 53 |
| struct padding and alignment | chapters 47–48 |
| why undefined behaviour is not “just a crash” | chapter 54 |
| what the linker really does | chapters 17, 56 and 57 |
| the inside of a function call | chapter 62 |
| what C23 changed | appendix G |
Table 0.2 — Where the returning reader should look first
Then read Part XII — the place where the earlier discipline is seen standing together inside one library, and the closest this book comes to working code.
Path ④ — you are heading for embedded and systems work#
The path for someone going close to the machine. Do not skip Parts I and II — what is background on the other paths is the subject on this one.
- chapters 2–5 — addresses, alignment, kinds of memory.
- chapters 6–11 — representation and interrupts.
- chapters 12–15 — caches, optimisation, the abstract machine.
- chapters 28–30 — widths and conversions. Where accidents happen on small machines.
- chapters 48 and 51 — bit idioms, layout and alignment. This is the syntax of handling registers.
- chapters 49 and 57 — re-reading a representation, and calling conventions.
- chapters 81 and 85 — asynchrony and atomicity. The real use of
volatilelives here. - chapters 88–89 — memory layout and allocators, including places with no heap at all.
- chapter 104 — tools and practice.
What you need not read#
On every path, here is what may be skipped on a first reading — not places that block you, but places to visit when the need arrives.
- Reading Part XI through — the library chapters are closer to a lookup table. Come to the chapter when you need it.
- chapters 73–77 — locales, wide characters, Unicode. Until you meet internationalisation, knowing “these layers exist” is enough.
- chapters 82–83 — the annex K argument and non-local jumps. Both chapters explain why something is not recommended.
- The full grammar in appendix E — it is for looking things up, not reading.
Conversely, if one chapter must not be skipped on any path, it is chapter 54. The most expensive mistakes in this language are all gathered there.