Dataslope logoDataslope

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.

Code Block
C 17 (201710L)

Change age to 15 and rerun. The line should disappear from the output.

if ... else

To do one or the other:

Code Block
C 17 (201710L)

else if chains

For more than two branches, chain them:

Code Block
C 17 (201710L)

The branches are checked top to bottom. The first one whose condition is true runs, and the rest are skipped.

Comparison operators

OperatorMeaning
==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:

OperatorMeaning
&&AND (both true)
||OR (at least one)
!NOT (inverts)
Code Block
C 17 (201710L)

&& 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 pointer

This 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:

Code Block
C 17 (201710L)

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 outer

Indentation 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.

Code Block
C 17 (201710L)

Three things to remember:

  • The case value 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 run Weekend) and sometimes a bug. Always write break unless you want fall-through.
  • default runs 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.

Challenge
C 17 (201710L)
Is it a leap year?

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
QuestionSelect one

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.

QuestionSelect one

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.

On this page