Intuition The one core idea
A program is a stack of instructions the computer normally reads straight down, one per line . Control flow is the collection of tricks that let you bend that straight line — to choose a path, repeat a block, or jump elsewhere — and every one of those tricks is built on a single question the machine keeps asking: "is this value zero or not?"
Before you can read a single if or for, you must own the tiny alphabet they are built from. This page defines every symbol, word, and shape the parent note leaned on — starting from absolutely nothing.
Imagine your program as a vertical ladder of steps. The computer stands on step 1, does it, steps down to step 2, does it, and so on. That downward walk is called sequence — the default, and the thing every other tool modifies .
Definition Statement and block
A statement is one instruction, usually ended with a semicolon ; — like x = 5;. A block is a group of statements wrapped in curly braces { ... }, treated as one unit. Look at the picture: each rung of the ladder is a statement; the box drawn around several rungs is a block.
Why the topic needs it: every if, loop, and switch runs a block when its rule is met. Without knowing "block = one bundle", you can't tell what a loop repeats.
; — end of statement
The semicolon is a full-stop for the computer: "this instruction is complete." The picture: it's the line between two rungs of the ladder. Miss one and the computer reads two steps as a jumbled single one (a compile error).
( ) — the grouping brackets
Round brackets ( ) bundle things together so the computer treats them as one unit to evaluate first . In control flow they wrap the condition : if (n > 0), while (i < 3), for (...). The picture: a hug around the question — "evaluate everything inside me, THEN hand the single answer back."
They also force order in arithmetic: (2 + 3) * 4 computes 5 first. Why the topic needs it: every if, while, for, and switch header requires its condition to sit inside ( ). Without the brackets the computer can't tell where the question ends and the body begins.
This is the single most important idea on the page. C has no special true/false switch built into its oldest core. Instead:
Definition Truthiness = "is it zero?"
A value is treated as ==false when it is exactly 0, and true when it is anything else== (1, -7, 42, all count as true). That's it. The computer, when it reaches a condition, computes a number and asks one question: "is this number zero?"
Look at the figure: the number line is split into just two zones — the single point 0 (false, coral) and everything else (true, mint). This is why the parent could say if (n) with no comparison at all: it just checks "is n non-zero?"
Intuition Why the topic needs this
Every if, while, for, and do-while decides "keep going or stop?" by running the zero test on their condition. If you don't know that 0 is the only false value, if (x = 5) (assignment!) will confuse you forever — because 5 is non-zero, so it's always "true". See the parent's = vs == warning; it only makes sense once you own this rule.
Related idea: full Boolean Logic (AND, OR, NOT) sits on top of this zero test.
You rarely write raw numbers as conditions. You write questions , and the questions produce 1 (true) or 0 (false).
Definition Relational operators
a > b — is a greater than b?
a < b — is a less than b?
a >= b — greater or equal?
a <= b — less or equal?
a == b — equal? (two equals signs!)
a != b — not equal?
Each of these evaluates to 1 if the answer is yes, 0 if no. The picture: a scale weighing a against b, and a lamp that lights (1) or stays dark (0).
Intuition Why the topic needs these six
Control flow is a chain of decisions , and a decision needs a yes/no question. These six operators are the only way to turn two ordinary numbers into the 1/0 that the zero test can then judge. Without them your if and loop conditions could only ever ask "is this raw value non-zero?" — you could never compare age >= 18 or loop while (i < n). Learn these first, because every condition in the parent note is built from them.
= is not ==
= means "store the right side into the left" (assignment). == means "are these equal?" (a question). The parent note's classic bug if (x = 5) stores 5 and then tests 5 → always true. The relational family here is your defence. See C Operators for the full table.
Recall What does
3 != 3 evaluate to?
0 (false) — because 3 is equal to 3, so "not equal" is false.
One question is rarely enough. Real decisions say "if the user is logged in and the cart is not empty." C gives you three logical operators to glue and flip questions.
Definition Logical operators
A && B — AND : true only when both A and B are true (non-zero). Picture: two switches in a row — current flows only if both are on.
A || B — OR : true when at least one of A, B is true. Picture: two switches side by side — current flows if either is on.
!A — NOT : flips the answer. !0 is 1 (true), !5 is 0 (false). Picture: an inverter that swaps the lamp's state.
Each still yields 1 or 0, so the zero test judges the combined result.
Intuition Short-circuit — why
&& and || stop early
&& checks left first: if the left side is already false, the whole thing must be false, so C doesn't even look at the right side . Likewise || stops the moment the left side is true. This is why you can safely write if (p != 0 && p->age > 18) — the right half only runs when p is valid. Why the topic needs it: the parent's conditions like n > 0 are single questions, but any realistic branch combines several with &&/||. See Boolean Logic for full truth tables.
Recall What is
!(3 > 5)?
3 > 5 is 0 (false); ! flips it to 1 (true).
Definition The conditional operator
?:
Written condition ? valueIfTrue : valueIfFalse. It runs the zero test on condition; if true it becomes the first value, otherwise the second. Picture: a fork in a pipe — the flag (condition) decides which branch's water comes out the far end.
Example: int big = (a > b) ? a : b; stores the larger of a and b.
Why the topic needs it: it is a compact selection tool — a whole if/else squeezed into a single expression you can use inside a bigger line (like inside printf). The parent note leans on it as the "expression form" of choosing.
Recall What does
(2 > 9) ? 100 : 7 evaluate to?
7 — because 2 > 9 is false, so the after-colon value is chosen.
Now we assemble the pieces from sections 1–4 into the first real control-flow tool.
if / else
The if keyword runs a block only when its condition passes the zero test (is non-zero). The optional else runs a block only when the condition failed (was zero). The syntax:
if (condition) {
// runs when condition is true (non-zero)
} else {
// runs when condition is false (zero)
}
You can chain them with else if to test several questions in order — the first true one wins and the rest are skipped:
if (n > 0 ) { /* positive */ }
else if (n == 0 ) { /* zero */ }
else { /* negative */ }
Picture: a fork in the road with a signpost — the condition reads the sign and sends the walker down exactly one path.
Why the topic needs it: if/else is selection itself — the way a program chooses . Every branch in the parent note is one of these. The condition inside ( ) is built from the comparison and logical operators of sections 3–4, then judged by the zero test of section 2.
Recall If
n = 0, which branch of the if / else if / else chain above runs?
The else if (n == 0) branch — the first true condition wins.
i++
i++ means "add 1 to i". It is the update step that pushes a loop toward its finish line. Picture: a car odometer clicking up by one.
Why the topic needs it: without a step that changes the loop's counter, the condition never turns false → an infinite loop . Every for and counting while in the parent relies on i++.
Now we assemble the pieces into the shape that powers all repetition.
Trace the arrows in the figure: init runs once (lavender), then the loop circles through condition → body → update → back to condition. The green exit arrow fires the moment the condition's zero-test says "false". This exact diagram is the skeleton of while, for, and do-while — they only differ in when the condition is tested. Deeper timing analysis lives in Loops and Time Complexity .
while — test before each pass
The while keyword checks its condition first ; if it passes the zero test, the body runs, then it checks again. If the condition is false at the very start, the body runs zero times.
while (condition) {
// body — repeated while condition is true
}
Picture: the "keep going?" question sits at the top of the loop cycle (section 8's figure), so you might walk straight past the body.
do-while — test after each pass
The do-while loop runs the body once first , then checks the condition. It guarantees the body runs at least once . Note the mandatory semicolon ; after the closing while(...):
do {
// body — runs at least once
} while (condition);
Picture: the "keep going?" question moves to the bottom of the cycle, so you always do one lap before asking.
Common mistake The lonely
while semicolon
A semicolon belongs after do { } while (condition);. But writing a semicolon right after a plain while (i < 3); header is a disaster — it makes the loop body empty, so the loop does nothing (or spins forever). Rule of thumb: a ; follows while only when it closes a do-while.
for — the compact counting loop
The for keyword packs three of the four loop parts into one header, separated by two semicolons:
for (init; condition; update) {
body;
}
So for (int i = 0; i < 3; i++) reads: start i at 0, keep going while i < 3, and after each pass do i++. Why the topic needs it: it is the parent note's compact loop; recognising the three-part header — and that the two semicolons are mandatory even if a part is left blank — lets you read any for at a glance.
Recall Which loop always runs its body at least once?
do-while — it tests the condition after the first pass.
break
The break keyword immediately leaves the innermost enclosing loop OR switch. Picture: an emergency exit door — you stop mid-body and jump straight past the loop's closing brace. In a switch it is what stops the fall-through from spilling into the next case.
continue
The continue keyword skips the rest of the current pass and jumps to the loop's update/condition to start the next round. Picture: hitting "next track" — the current song stops but the playlist keeps going. Note: continue has no meaning in a switch, only in loops.
Intuition Why the topic needs both
A loop that can only run its whole body every time is rigid. break lets you stop early when you've found what you wanted; continue lets you skip the awkward cases without leaving. And break doubles as the essential wall between switch cases — without it, execution falls through to the next case's code (the parent's classic bug).
Recall In
switch, what happens if you forget break?
Execution falls through and runs the next case's code too, until a break or the block ends.
Definition Integral types
An integer (int) is a whole number: -2, 0, 41. A char is a single character like 'A', but under the hood it is also just a small integer (its character code — 'A' is 65). Both are called integral types.
Why the topic needs it: switch can only branch on integral values compared to fixed case labels. The picture: numbered pigeon-holes; switch throws your value into the matching hole. You cannot switch on a fraction or a piece of text — only these whole-number pigeon-holes.
A label is a named signpost in the code, written as a word (or case + a constant) followed by a colon :. It marks a spot you can jump to .
case 1: — a signpost inside a switch for when the expression equals 1.
default: — the catch-all label inside a switch; execution lands here when no case matched. It's the switch version of else.
found: — a plain target for goto (see section 13).
Picture: flags planted on rungs of the ladder; default: is the flag labelled "if none of the others fit, come here."
switch statement
switch takes an integral expression (section 11), then jumps to the matching case label and runs downward from there until a break or the end of the block. The syntax:
switch (expression) {
case 1 : /* runs if expression == 1 */ break ;
case 2 : /* runs if expression == 2 */ break ;
default : /* runs if nothing matched */
}
Picture: a computed jump into a labelled block — you land on your case and keep walking down until a break door stops you. Why the topic needs it: switch is a fast, readable form of selection when you are checking one value against many fixed options.
Recall Which switch label runs when no case matches?
default: — the catch-all, playing the role else plays in an if-chain.
goto
The goto keyword jumps unconditionally to a label in the same function — no condition, no loop, just teleport. The syntax is goto label; paired with a label: signpost somewhere in the function:
for ( int i = 0 ; i < N; i ++ )
for ( int j = 0 ; j < M; j ++ )
if (found)
goto done; // escapes BOTH loops at once
done:
printf ( "finished" );
Picture: a magic trapdoor that drops you straight onto a marked flag, ignoring the normal ladder.
Why the topic needs it: a single break only exits the innermost loop; goto can escape several nested loops in one leap, and is also used for centralized error-cleanup. It is powerful but easy to abuse ("spaghetti code"), so reserve it for those two jobs.
Recall Why use
goto instead of break to leave two nested loops?
break only exits the innermost loop; goto jumps clean out of both at once.
Zero test - true is non zero
Labels case default colon
Everything on the left feeds the parent topic (Control Flow ) on the right. Notice the zero test is the hub: both selection and iteration route through it.
Cover the right side and test yourself — you are ready for the parent note only if you can answer all of these.
In C, which single value counts as false? Exactly 0; every other value is true.
What is the difference between = and ==? = stores a value (assignment); == asks whether two values are equal.
What do parentheses ( ) do in a condition? Group the condition into one unit that is evaluated first, before its result is tested.
When is A && B true? Only when both A and B are true (non-zero).
When is A || B true? When at least one of A or B is true.
What does !A do? Flips the truth: !0 is 1, and any non-zero becomes 0.
What does cond ? x : y give you? x if cond is true, otherwise y — a one-expression if/else.
What does an if (condition) statement do, and what does else add? if runs its block only when the condition is non-zero; else runs its block only when the condition was zero.
What does i++ do and why does a loop need it? Adds 1 to i; without an update the condition never turns false → infinite loop.
Name the four parts of every loop. Init, condition, body, update.
What is the syntax difference between while and do-while? while (cond) { } tests before the body; do { } while (cond); tests after and needs the trailing semicolon.
What are the three parts of a for header, and how are they separated? Init; condition; update — separated by two semicolons.
What does break do? Immediately exits the innermost loop or switch.
What does continue do? Skips the rest of the current pass and jumps to the loop's update/condition.
What is a "block" in C? A group of statements inside { }, treated as one unit.
Which types can a switch branch on? Integral types — int or char (chars are small integers).
Write the skeleton of a switch statement. switch (expr) { case A: ... break; default: ... } — jumps to the matching case, falls through until a break.
Which switch label runs when no case matches? default: — the catch-all.
What does the goto statement do? Jumps unconditionally to a label: in the same function — used mainly to escape nested loops or for error cleanup.
What punctuation marks a label like found: or case 1:? A colon : (a signpost, not an action).
What does 3 != 4 evaluate to? 1 (true) — they are not equal.
Why must you write if (n) carefully — what is being tested? Whether n is non-zero (the zero test), not whether n equals some other value.