Conditional statements branch the flow of a program. In this section
Learn if/else if/else, the ternary operator, and branching tool sets up to switch.
Learning Objectives
- Create a multi-level branch with
if/else if/else. - Use the ternary operator
?:for short condition expressions. - Know exactly the operation of
switch/case/break/default. - Understand the Boolean result of a condition (not 0/0).
Why do you need conditional statements? — "Traffic light at the crossroads"
The program so far has flowed all at once from top to bottom. But in reality, problems almost always look like “sometimes A, other times B”.
┌──────────┐
│ score≥90 │── Yes ──► A
└──────────┘
│ No
▼
┌──────────┐
│ score≥80 │── Yes ──► B
└──────────┘
│ No
▼
C or lower
Conditional sentences are the traffic light at this crossroads.
Key concepts
1) if / else if / else
if (score >= 90) printf("A\n");
else if (score >= 80) printf("B\n");
else if (score >= 70) printf("C\n");
else printf("D or lower\n");
- It checks from top to bottom and executes only the first branch that is true.
- So,
score >= 80automatically means "more than 80 but less than 90".
2) Ternary operator ?:
int max = (a > b) ? a : b;
if-else Suitable for simple one-line branching. If it's too long, go for regular if.
3) switch / case
switch (op) {
case '+': result = a + b; break;
case '-': result = a - b; break;
default: printf("Unknown operator\n");
}
Flow:
┌─────► case '+': ─► break ─► (exit switch)
op? ───┼─────► case '-': ─► break ─► (switch exit)
└─────► default ─► (Switch exit)
If there is no break, it will fall-through to the next case. If you don't mean to, don't forget break.
4) Truth value of conditional expression
In C, 0 is false, and any value other than 0 is true.
if (count) { ... } //Same as count != 0
if (ptr) { ... } //Equivalent to ptr != NULL (idiom expression)
See as example
Example 1 — ex01_if.c : Score → Grade
if (score >= 90) printf("Grade: A\n");
else if (score >= 80) printf("Grade: B\n");
else if (score >= 70) printf("Grade: C\n");
else if (score >= 60) printf("Grade: D\n");
else printf("Grade: F\n");
Input: 85
Enter score (0~100): Grade: B
Input: 59
Enter score (0~100): Grade: F
Bottom line: Branches are evaluated from above, so order matters.
If you move if (score >= 60) to the top, 90 points also become D.
Example 2 — ex02_ternary.c: Ternary operator
int max = (a > b) ? a : b;
int min = (a < b) ? a : b;
const char *parity = (a % 2 == 0) ? "even number" : "odd number";
Input: 7 3
Enter two integers: Maximum value: 7
Minimum: 3
a is odd
Bottom line: Because ternaries create values, they can be used directly to initialize variables.
Example 3 — ex03_switch.c: Four arithmetic calculator
switch (op) {
case '+': result = a + b; break;
case '-': result = a - b; break;
case '*': result = a * b; break;
case '/': /*0 After inspection a/b*/ break;
default: /*error*/
}
Input: 12 + 5
Enter an expression (e.g. 3 + 4): Result: 17.000
Input: 10 / 0
Enter an expression (e.g. 3 + 4): cannot be divided by 0.
Key: The label case must be an integer constant (characters are also integers). Strings cannot be used.
Example 4 — ex04_nested_if.c: Nested if (leap year determination)
Leap year rule: Multiples of 4, but excluding multiples of 100, again including multiples of 400.
Input: 2024
Enter the year: 2024 is a leap year.
Input: 2100
Enter the year: 2100 is not a leap year.
Bottom line: As nesting deepens, readability decreases dramatically. One floor at a time is recommended.
A different perspective — if-else if is actually a nested if
if (score >= 90)
/* A */
else if (score >= 80)
/* B */
else
/*C or lower*/
is actually the same as:
if (score >= 90) {
/* A */
} else {
if (score >= 80) {
/* B */
} else {
/*C or lower*/
}
}
else if is just an idiom notation for readability and is not a separate keyword.
Common Mistakes
- Confusion between
==and=:if (x = 0)is always false + side effect. - Semicolon alone: If the semicolon is entered incorrectly, such as
if (x > 0);, an empty branch is created. - Missing
break: Unintentional fall-through inswitch. - Floating point equality comparison:
if (a == 0.1)is almost always false. Comparison with error allowed (fabs(a - 0.1) < 1e-9). elseis tied to the nearbyif: When nested, if written without braces, it may be attached toif, which is different from what was intended. Always recommend braces.
Cleanup
if/else if/elseare evaluated from top to bottom, so the order of conditions is important.- Ternary
?:is useful for initializing variables in single-line branches. switch/caseis used only for integer type (including character) branches. Don't forgetbreak.- In a conditional expression, 0 is false, and all values other than 0 are true.
- If the overlap becomes deep, separate it into a function or flatten the branches.
Try it yourself
cd src
gcc -std=c11 -Wall -o ex01 ex01_if.c && echo 85 | ./ex01
gcc -std=c11 -Wall -o ex02 ex02_ternary.c && echo "7 3" | ./ex02
gcc -std=c11 -Wall -o ex03 ex03_switch.c && echo "12 + 5" | ./ex03
gcc -std=c11 -Wall -o ex04 ex04_nested_if.c && echo 2000 | ./ex04
Application:
- Try deleting
'+': result = a + b;andbreakfromex03_switch.c. Observe how the output changes. - Write the grade branching condition of
ex01_if.cbackwards as<= 89to get the same result.