C
Control Flow
Every program so far in this domain has run top to bottom, one statement after another, with no decisions. Control flow is how a program chooses which statements to run based on a condition — the difference between a script and something that actually reacts to its input.
- What it is
- The
if/elseandswitchstatements C uses to run different code depending on a condition. - Mental model
- A fork in the road — the program evaluates a condition to a true/false answer and takes exactly one branch based on it.
- Key numbers
- Any nonzero value is "true"; only
0is "false" — there's no separate boolean type in original C. - Reach for it when
if/elsefor a handful of conditions or ranges;switchspecifically when testing one variable against many exact, known values.
What "true" means in C
Before if makes sense, you need to know what counts as true. C has no dedicated boolean
type in its original design — every condition is really just a number, and the rule is simple:
0 is false, and literally every other value is true, including negative
numbers.
if / else if / else
int temperature = 85;
if (temperature > 90) {
printf("Too hot\n");
} else if (temperature < 60) {
printf("Too cold\n");
} else {
printf("Comfortable\n");
}
// Comfortable
else if/else is skipped entirely — only one branch of the whole chain ever executes.switch
switch tests one value against a list of exact matches — cleaner than a long
else if chain when you're comparing a single variable to several specific values:
int day = 3;
switch (day) {
case 1:
printf("Monday\n");
break;
case 2:
printf("Tuesday\n");
break;
case 3:
printf("Wednesday\n");
break;
default:
printf("Some other day\n");
}
// Wednesday
The break at the end of each case is not optional decoration — without it, execution
falls through into the next case regardless of whether it matches, which is real,
intentional C behavior, not a bug in the language.
switch (day) {
case 1:
case 2:
case 3:
case 4:
case 5:
printf("Weekday\n"); // falls through cases 1-5 into this ONE printf
break;
case 6:
case 7:
printf("Weekend\n");
break;
}
Real-world applications
- Sensor threshold checks — comparing a reading against safe/warning/critical bands, exactly like the temperature example above.
- Command/opcode dispatch — a
switchon a received byte value is the standard pattern for parsing a simple command protocol. - State machines — a
switchon the "current state" variable, with each case handling one state's behavior, is one of the most common structures in embedded firmware.
Gotchas
- Forgetting
breakin aswitchis one of the most common real bugs in C — it compiles fine and often "mostly works," failing only on inputs that hit the specific case that was supposed to stop there. switchonly works on integer types (andchar) — it cannot switch on afloat,double, or string.- A dangling
ifwith no braces only controls the single next statement — adding a second statement "inside" it without braces silently moves that statement outside the condition entirely. Using braces even for one-line bodies avoids this class of bug completely. - Comparing floating-point values with
==inside anifis unreliable — tiny rounding errors from floating-point representation mean two values that are mathematically equal can differ by a fraction of a bit. Comparing within a small tolerance (fabs(a - b) < 0.0001) is the standard fix.