Part of C in 100s

C in 100 Seconds: If/Else | Episode 5

Celest KimCelest Kim

Video: C in 100 Seconds: If Else — Grade Calculator in 14 Lines | Episode 5 by Taught by Celeste AI - AI Coding Coach

Take the quiz on the full lesson page
Test what you've read · interactive walkthrough

C If / Else: Grade Calculator

if, else if, else — chained conditionals. Ternary ?: for one-line branches. A 14-line grade calculator that maps a score to a letter grade.

C's if-else is the same as in any C-family language. Today's puzzle: build a small grade calculator that demos every form.

The grade calculator

#include <stdio.h>

int main() {
  int score = 85;

  if (score >= 90) {
    printf("Grade: A\n");
  } else if (score >= 80) {
    printf("Grade: B\n");
  } else if (score >= 70) {
    printf("Grade: C\n");
  } else {
    printf("Grade: F\n");
  }

  int age = 20;
  printf(age >= 18 ? "Adult\n" : "Minor\n");

  return 0;
}

Two forms — the multi-branch chain (with else if) and the inline ternary ?:.

The basic shape

if (condition) {
  // runs when condition is true
}

The condition is any expression. If it evaluates to non-zero, the branch runs. If zero, it doesn't.

if (1) printf("Always\n");
if (0) printf("Never\n");
if (-5) printf("Yes — non-zero is truthy\n");
if (NULL) printf("Never — NULL is 0\n");

C doesn't have a bool type natively (until C99 added _Bool / <stdbool.h>). Truthy = non-zero, falsy = zero.

Comparison operators

if (a == b)    // equal
if (a != b)    // not equal
if (a < b)     // less than
if (a > b)     // greater than
if (a <= b)    // less than or equal
if (a >= b)    // greater than or equal

Each returns 1 (true) or 0 (false).

The classic mistake:

if (x = 5)     // assigns 5 to x, then evaluates non-zero (true)
if (x == 5)    // checks if x equals 5

Single = is assignment; double == is comparison. Compiler usually warns (with -Wall) but still compiles.

Logical operators

if (a > 0 && a < 10)    // AND — both true
if (x == 0 || y == 0)   // OR — at least one true
if (!ready)             // NOT — flips truthiness

&& and || short-circuit:

  • a && b — if a is false, b isn't evaluated.
  • a || b — if a is true, b isn't evaluated.

Useful for null checks: if (ptr != NULL && ptr->value > 0). The dereference is safe because if ptr is NULL, the second part doesn't run.

else and else if

if (score >= 90) {
  // ...
} else if (score >= 80) {
  // ...
} else if (score >= 70) {
  // ...
} else {
  // fallback
}

else is the fallback. else if chains alternatives. Each branch is checked in order; the first match runs.

Order matters:

if (score >= 60) printf("D\n");
else if (score >= 90) printf("A\n");   // never runs!

The 60 branch matches everything ≥ 60, leaving nothing for the 90 branch. Order high-to-low.

Braces are optional (but use them)

if (x > 0)
  printf("positive\n");

Single statement after if doesn't need braces. But...

if (x > 0)
  printf("positive\n");
  printf("good\n");      // ALWAYS runs — not part of the if!

The second printf has the indentation but isn't part of the if. This is the Apple goto fail bug class — silently broken security. Always use braces, even for one-liners.

Ternary operator

int age = 20;
printf(age >= 18 ? "Adult\n" : "Minor\n");

condition ? value_if_true : value_if_false. An expression (returns a value), not a statement. Useful for:

  • One-line decisions: int max = a > b ? a : b;
  • Inside printf: printf("%s\n", success ? "ok" : "fail");
  • Function arguments: f(x > 0 ? x : -x);

For multi-line decisions, use if/else. Don't nest ternaries beyond one level — it gets unreadable.

The infamous "x = 5 vs x == 5"

if (x = 5) { ... }   // BUG: assigns then checks (always true)
if (x == 5) { ... }  // CORRECT

The "Yoda" style avoids it by putting the constant on the left:

if (5 == x) { ... }   // typo to "5 = x" doesn't compile — can't assign to literal

Some codebases love it; others find it backwards. Either way, modern compilers warn.

Switch as an alternative

For many cases on a single value, switch is often clearer:

switch (grade) {
  case 'A': printf("Excellent\n"); break;
  case 'B': printf("Good\n"); break;
  default: printf("Other\n");
}

Episode 6 covers switch properly.

Nested ifs

if (age >= 18) {
  if (has_id) {
    printf("Welcome\n");
  } else {
    printf("Need ID\n");
  }
} else {
  printf("Too young\n");
}

Often cleaner with &&:

if (age >= 18 && has_id) {
  printf("Welcome\n");
} else if (age >= 18) {
  printf("Need ID\n");
} else {
  printf("Too young\n");
}

Common mistakes

= instead of ==. Silent assign-and-check. Use -Wall to catch.

No braces, multiple statements. Only the first runs. Always use braces.

Wrong order in else if chain. First match wins; high-to-low for descending ranges.

Comparing strings with ==. if (str == "hello") compares pointer addresses, not contents. Use strcmp(str, "hello") == 0 (episode 11).

Comparing floats with ==. Floating-point precision means 0.1 + 0.2 != 0.3. Use fabs(a - b) < epsilon (episode 39 covers errno; floating point quirks need their own care).

What's next

Episode 6: switch / case. The cleaner alternative to long if-else chains when you're branching on a single value.

Recap

if (cond) { ... } else if (cond) { ... } else { ... }. Non-zero is truthy. == for compare, = is assignment (a classic typo). Logical: &&, ||, ! — short-circuit evaluation. Ternary: cond ? a : b — expression form. Always use braces even for one-line bodies. Order if-else from most-specific (highest range) to most-general.

Next episode: switch and case.

Ready? Take the quiz on the full lesson page →
Test what you've learned. Watch the lesson and try the interactive quiz on the same page.