Control flow determines which statements a C program executes and which statements it skips. Up to this point, the course has focused on building programs, declaring values, and forming expressions. In this lesson, those expressions begin controlling program behavior through if, else if, else, switch, and the conditional operator ?:.
This lesson builds directly on OSC.003 on C operators and expressions, because comparisons such as temperature > 80 and logical expressions such as ready && connected become the conditions that choose a branch.
How C Decides True or False
In C, zero is false and any nonzero value is true. A condition does not need to produce a special Boolean object. The expression simply evaluates to an integer-like truth value. That means if (5) takes the branch, while if (0) does not.
#include <stdio.h>
int main(void) {
int temperature = 87;
if (temperature > 80) {
printf("High temperature\n");
}
return 0;
}
The comparison temperature > 80 is evaluated first. Because the result is nonzero, the body of the if statement runs. This depends on the comparison and logical operators introduced after the variables and data types covered in OSC.002.
if and else
An if statement handles one condition. Adding else gives the program a second path when the condition is false.
int power_ok = 1;
if (power_ok) {
printf("Start system\n");
} else {
printf("Keep system offline\n");
}
The two bodies are mutually exclusive. Exactly one runs. Braces are technically optional around a single statement, but using them consistently reduces ambiguity and prevents maintenance bugs when another statement is added later.
else if Chains
Use else if when several conditions must be checked in order. C stops at the first condition that evaluates true.
int load_percent = 73;
if (load_percent >= 90) {
printf("Critical load\n");
} else if (load_percent >= 70) {
printf("High load\n");
} else if (load_percent >= 40) {
printf("Normal load\n");
} else {
printf("Low load\n");
}
Order matters. If the test for >= 40 appeared before the test for >= 90, a value of 95 would match the earlier condition and the later branch would never be reached.
switch, case, break, and default
A switch statement is useful when one integral expression must be compared against several constant values. Common switch expressions include char, int, enumerations, and other integer types. Standard C does not use switch to compare arbitrary strings.
char command = 's';
switch (command) {
case 's':
printf("Start\n");
break;
case 'p':
printf("Pause\n");
break;
case 'q':
printf("Quit\n");
break;
default:
printf("Unknown command\n");
break;
}
Each case is a labeled entry point. The break statement exits the switch. Without break, execution continues into the next case. That behavior is called fallthrough. Fallthrough can be intentional, but accidental fallthrough is a common source of bugs.
Intentional Fallthrough
int month = 1;
switch (month) {
case 12:
case 1:
case 2:
printf("Winter\n");
break;
case 3:
case 4:
case 5:
printf("Spring\n");
break;
}
Here, several cases deliberately share one body. This is a legitimate use of fallthrough because months 12, 1, and 2 all produce the same result.
The Conditional Operator ?:
The conditional operator chooses between two expressions. It is often called the ternary operator because it has three operands: a condition, the expression used when true, and the expression used when false.
int temperature = 85;
const char *state = temperature > 80 ? "hot" : "normal";
printf("%s\n", state);
The expression before ? is the condition. The expression between ? and : is selected when the condition is true. The expression after : is selected when it is false. Use this operator when both alternatives are simple values or expressions. Long nested conditional expressions usually reduce readability and are better written as ordinary if statements.
A Common Bug: = Versus ==
int mode = 0;
if (mode = 1) {
printf("This branch runs\n");
}
This code assigns 1 to mode. The assignment expression itself evaluates to 1, which is true, so the branch runs. The likely intention was mode == 1. Compiler warnings help catch this class of error, which is one reason the toolchain flags introduced in OSC.001 matter.
Compile and Run
gcc -std=c17 -Wall -Wextra -Wpedantic control_flow.c -o control_flow
./control_flow
The warning flags are especially useful in control-flow code because they can expose suspicious assignments, unreachable branches, missing switch cases, and other logic problems before runtime testing begins.
Exercise
Create power_state.c. Declare an integer named load and print LOW, NORMAL, HIGH, or CRITICAL with an if/else if chain. Then declare a character command with values 's', 'p', or 'q' and handle it with switch. Finally, use the conditional operator to set a string pointer to "online" or "offline" from an integer status flag.
Knowledge Check
- What integer value does C treat as false?
- When does an
elsebody execute? - Why does order matter in an
else ifchain? - What does
breakdo inside a switch? - What is switch fallthrough?
- What three operands make up the
?:operator? - Why is
if (x = 1)often a bug?
Answers
- Zero.
- When the associated
ifor precedingelse ifconditions are false. - C executes the first true branch and skips the remaining alternatives.
- It exits the switch statement.
- Execution continues from one case into the next because no break or other control transfer ended the first case.
- A condition, the expression selected when true, and the expression selected when false.
- Because
=assigns a value, while==compares two values.
BitcoinVersus.Tech Editor’s Note:
We volunteer daily to ensure the credibility of the information on this platform is Verifiably True. If you would like to support to help further secure the integrity of our research initiatives, please donate using the QR code provided

For best QR-code scanning results, please scan this donation code from a desktop or larger screen. Mobile screens may prevent camera recognition.

Leave a Reply