How to read this book — reading paths by level
This book was written to be read 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. If you are learning from scratch, the written order is the comfortable one; if you already write 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 to the letter; 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 twelve 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 chapter references in the text keep pointing at those chapters. 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–58 (Parts VIII–IX) | structs and contracts. the answer to “why was it settled this way” starts to come through |
| chapters 59–69 (Part X) | the program’s outside — linking, names, the preprocessor |
| chapters 70–75 (Part XI) | objects built in C — function-pointer tables, tables built at run time, the cost of an indirect call, cases, limits |
| chapters 76–99 (Part XII) | look things up rather than read through. No need to finish it |
| chapters 100–110 (Part XIII) | the discipline of the earlier parts seen again in a real library, proven |
| chapters 111–115 (Part XIV) | 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 55–56 — contracts and undefined behaviour. Here you learn precisely what “no runtime is going to stop you” means.
- From chapter 76 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 — without break, control runs on into the next case.
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 62 |
what const, volatile and restrict actually promise | chapters 27 and 55 |
| struct padding and alignment | chapters 47–48 |
| why undefined behaviour is not “just a crash” | chapter 56 |
| what the linker really does | chapters 17, 60 and 61 |
| the inside of a function call | chapter 66 |
| what C23 changed | appendix F |
Table 0.2 — Where the returning reader should look first
Then read Part XIII — the place where the discipline of the earlier parts is seen standing together inside one library, proven, and the closest this book comes to everyday practice.
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 53 — bit idioms, layout and alignment. This is the syntax of handling registers.
- chapters 49 and 61 — re-reading a representation, and calling conventions.
- chapters 91 and 95 — asynchrony and atomicity. The real use of
volatilelives here. - chapters 98–99 — memory layout and allocators, including places with no heap at all.
- chapter 114 — tools and practice.
What you need not read#
On every path, here is what may be skipped on a first reading — not places you will be stuck without, but places to visit when the need arrives.
- Reading Part XII through — the library chapters are closer to a lookup table. Come to the chapter when you need it.
- chapters 83–87 — locales, wide characters, Unicode. Until you meet internationalisation, knowing “these layers exist” is enough.
- chapters 92–93 — 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 56. The most expensive mistakes in this language are all gathered there.