Conditionals
if, else, else-if, switch — how to make programs choose
A program that always does the same thing isn't very interesting. Conditionals let a program look at a value and decide what to do next. They are the second pillar of computation, after sequence.
The if statement
The basic form is:
if (condition) {
// run this if condition is true (non-zero)
}The condition is any expression. C treats 0 as false and any
non-zero value as true.
Change age to 15 and rerun. The line should disappear from the
output.
if ... else
To do one or the other:
else if chains
For more than two branches, chain them:
The branches are checked top to bottom. The first one whose condition is true runs, and the rest are skipped.
Comparison operators
| Operator | Meaning |
|---|---|
== | equal to |
!= | not equal to |
< | less than |
<= | less than or equal |
> | greater than |
>= | greater than or equal |
`=` is assignment, `==` is comparison
This is the most famous typo in C history:
if (x = 5) { /* ALWAYS true; also sets x to 5! */ }
if (x == 5) { /* what you meant */ }The first version assigns 5 to x, then uses 5 as the condition
(non-zero, therefore true). Most modern compilers will warn you, but
the bug has burned countless programmers. Turn on warnings
(-Wall).
Logical operators
Combine conditions with logical operators:
| Operator | Meaning |
|---|---|
&& | AND (both true) |
|| | OR (at least one) |
! | NOT (inverts) |
&& and || are short-circuiting: if the result is already
determined after evaluating the left side, the right side is not
evaluated. This lets you write safe checks like
if (p != NULL && p->value == 0) — the dereference on the right
never runs when p is null.
Truth values: what counts as true?
In C, anything non-zero is true. 0 is false. There is no separate
boolean unless you #include <stdbool.h>.
if (count) { ... } // true if count != 0
if (!count) { ... } // true if count == 0
if (str) { ... } // true if str is not the NULL pointerThis is concise, but explicit comparisons are easier to read:
if (count != 0) { ... }
if (str != NULL) { ... }Prefer clarity over cleverness, especially while learning.
Nested conditionals
You can put if inside if:
Deep nesting is hard to read. When it grows past two levels, it's
usually a sign to refactor — split a chunk into a separate function,
or rewrite with && and ||.
The dangling-else pitfall
if (a)
if (b)
printf("both\n");
else
printf("not a\n"); // BUG: this else binds to the inner if, not the outerIndentation lies. The else always binds to the nearest unmatched
if. Always use braces, even for single statements:
if (a) {
if (b) {
printf("both\n");
}
} else {
printf("not a\n");
}This rule is so important that many style guides make braces mandatory. Make it your default.
The switch statement
When you have many branches on a single integer value, switch is
sometimes clearer than a long if/else if chain.
Three things to remember:
- The
casevalue must be a compile-time integer constant. - Execution falls through to the next case unless you
break. This is sometimes useful (notice cases 6 and 7 both runWeekend) and sometimes a bug. Always writebreakunless you want fall-through. defaultruns if none of the cases matched. It is optional but good practice to include one.
Decision tree, visualized
A diagram like this makes it obvious why order matters when the
ranges overlap. If you wrote if (score >= 60) first, everyone with
a score of 95 would get a D!
Challenge: leap year
A year is a leap year if it is divisible by 4, except that years divisible by 100 are not leap years, unless they are also divisible by 400.
A variable year is set to 2000. Print exactly one line: leap if the year is a leap year, otherwise not leap.
Test cases the grader uses internally (you don't need to handle multiple inputs — year is fixed at 2000):
- 2000 → leap (divisible by 400)
- 1900 → not leap (divisible by 100 but not 400)
- 2024 → leap (divisible by 4, not 100)
- 2023 → not leap
What does this print?
#include <stdio.h>
int main(void) {
int x = 5;
if (x = 10) {
printf("hello\n");
}
printf("x = %d\n", x);
return 0;
}
Hint: a single = is assignment, not comparison. An assignment expression evaluates to the value that was assigned.
Nothing, because if (x = 10) is a compile error.
x = 5, because the assignment doesn't take effect.
hello followed by x = 10.
hello followed by x = 5.
A switch is missing a break between two cases:
switch (n) {
case 1: printf("one ");
case 2: printf("two "); break;
default: printf("other "); break;
}
What does the program print when n is 1?
one only.
one other
one two
A compile-time error.