CS210 · Block 1 · Lesson 4

Conditionals

Logical operators · Short-circuit · Truthiness · if / else if / else · switch · Common bugs
At a glance: Today programs start making decisions. You'll meet C's logical operators (&&, ||, !), see how short-circuit evaluation lets you write safe guards, and learn how C treats truthiness differently from Python. Then you'll wire those expressions into if / else if / else and switch statements, and learn the four bugs that bite cadets writing their first real conditionals.
Contents
  1. Lesson Objectives
  2. Assigned Readings
  3. Pre-Class Work
  4. Lesson Materials and Overview
  5. In-Class Work
  6. After Class
1. Lesson Objectives

By the end of this lesson, cadets will be able to:

  1. Apply C's logical operators (&&, ||, !) and predict the effect of short-circuit evaluation. (Outcome 1)
  2. Implement conditional logic using if, else if, else, and switch statements. (Outcome 1)
  3. Distinguish how C evaluates truthiness compared to Python. (Outcome 1)
  4. Identify and avoid common conditional bugs such as assignment vs equality, dangling else, and switch fall-through. (Outcome 3)
2. Assigned Readings

Complete before class. These set the vocabulary we will use.

Source Sections Why
Beej-C Chapter 3 (sections on logical operators, if / else, and switch) Logical operators, conditional statements, truthiness rules
King, C Programming: A Modern Approach Chapter 5 (Selection Statements) Optional deeper dive on if, switch, and short-circuit evaluation
3. Pre-Class Work
Do this first
Plan on 30 to 45 minutes. The reading and skim below set you up to spend class time on the tracer and the lab instead of catching up.

Pre-Class Checklist

1
Read Beej-C Chapter 3 (logical operators, if, switch)
Read closely if any of these terms feel unfamiliar:
  • &&, ||, ! (logical AND, OR, NOT)
  • Short-circuit evaluation
  • if, else if, else
  • switch, case, break, default
2
Skim the In-Class section below
You will see an interactive logic tracer widget. No need to work it yet; just know it is there and what it looks like.
4. Lesson Materials and Overview

Today's content has two halves that come together. First half: logical operators and how C decides what counts as true. Second half: the statements (if, else if, else, switch) that act on those decisions. The reference material below covers what you'll see in lecture and use in the logic tracer.

Jump to
Slides Truthiness in C Logical Operators Short-Circuit if / else if / else Ternary switch Common Bugs

Slides

The Lesson 4 deck covers logical operators, truthiness, short-circuit evaluation, the conditional statements, and the four bugs to watch for. The slides are the spine of the in-class lecture; the logic tracer is where you practice predicting how expressions evaluate.

Open Lesson 4 slides → replace href with your deployed slide deck URL

Truthiness in C

C does not have a dedicated boolean type the way Python does. The native keyword _Bool exists (added in C99), and <stdbool.h> provides the friendlier bool, true, and false on top of it. You will see plain integers used for truth values all over real C code, though. The rule is exactly one sentence:

In C, zero is false. Every other value is true.

That includes negative numbers, positive numbers, floating-point values that are not exactly zero, and yes, even -1. All of these evaluate to true:

if (1) { ... }    // true
if (-7) { ... }   // true (nonzero)
if (0.001) { ... } // true
if (0) { ... }    // false

What is different from Python:

  • Python has rich truthiness rules: empty strings, empty lists, None, and zero are all false. C does not have those concepts here; it just checks "is this number zero?"
  • When comparison operators like == produce a result, they give you 1 for true and 0 for false. The logical operators (&&, ||, !) do the same.
  • There is no True or False keyword in C the way there is in Python. Write 1 and 0.

Logical operators and truth tables

Three logical operators. They combine truth values (which, remember, are just zero and nonzero in C) and produce 1 or 0 as their result.

Operator Name True when
a && b Logical AND Both a and b are nonzero
a || b Logical OR At least one of a or b is nonzero
!a Logical NOT (unary) a is zero (i.e. flips truth)

Truth tables:

a b a && b a || b
0000
0101
1001
1111
a !a
01
nonzero0

Remember: ! turns nonzero into 0, and 0 into 1. It always returns exactly 0 or 1.

Coming from Python: Python uses the words and, or, not. In C, those words mean nothing. Use the symbols: &&, ||, !. Also: && is two ampersands. A single & is the bitwise AND (Lesson 34) and means something completely different.

Short-circuit evaluation

C evaluates && and || left to right and stops as soon as the answer is known.

  • For a && b: if a is false, the whole thing is false. b is never evaluated.
  • For a || b: if a is true, the whole thing is true. b is never evaluated.

That is not just a performance optimization. It is a tool. You can rely on it to protect dangerous expressions:

// The "guard" pattern. The left side protects the right side.
if (denom != 0 && num / denom > 10) {
    // safe: we only divide when denom is nonzero
}

Swap the order and the program crashes on division by zero whenever denom is zero:

// BUG: division happens first, regardless of denom
if (num / denom > 10 && denom != 0) {
    // floating-point exception when denom == 0
}

Order matters. The cheaper or safer check goes on the left.

if / else if / else

The basic conditional in C is shaped like Python's, with three syntactic differences: parentheses around the test, curly braces (not indentation) define the body, and the keyword is else if (two words) instead of Python's elif.

int score = 85;

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

Style note: braces are technically optional for single-statement bodies, but always include them. It prevents the dangling-else bug (see below) and makes the code less ambiguous to humans and easier to extend later.

DFCS C Programming Standard: two style rules become teachable here. §6.2 sets indentation at four spaces and places the opening brace on the same line as the if / else / switch statement (the K&R style you see in every example on this page). §7.4 forbids single-line if statements; every branch body sits on its own line inside braces. See the DFCS C Programming Standard in the course Resources section for the full rules.

The else branch is optional. Exactly one branch executes: C tries each condition in order and stops at the first true one. If none are true and there is no else, nothing in the chain runs.

The ternary operator

C has a compact form of if/else that returns a value. It's called the ternary operator because it takes three operands. The syntax is condition ? value_if_true : value_if_false.

int score = 85;
char *result = (score >= 60) ? "pass" : "fail";
// equivalent to:
char *result;
if (score >= 60) {
    result = "pass";
} else {
    result = "fail";
}

Use it when both branches produce a value of the same type and the whole thing fits comfortably on one line. Common cases: picking between two strings, two numeric constants, or two simple expressions. The printf example below is a typical use:

printf("You have %d item%s.\n", n, (n == 1) ? "" : "s");

Reach for a full if/else when the branches are statements (not values), when either branch is more than a short expression, or when nesting ternaries would hurt readability. Most code in this course should use full conditional statements; the ternary appears here so you recognize it when you see it in Beej or in real C code.

switch statements

When you're branching on the integer value (or character value) of a single variable, switch is often cleaner than an if/else if chain.

char grade = 'B';

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

Rules to keep in mind:

  • The switch value must be an integer type. That includes char (which is just a small integer). You cannot switch on a double or a string.
  • Each case label must be a constant, not a variable or a range.
  • default is optional and runs when no case matches.
  • Without a break, execution falls through to the next case. See the bugs section below.

When in doubt, write if / else if. Reach for switch when you have three or more cases on a single integer value and the cases are exact matches (not ranges or comparisons).

Four bugs that bite first-time conditionals

Bug 1: = instead of ==
You saw this introduced in Lesson 3 with comparison operators. In an if, it bites hard:
if (x = 5) {  // BUG: assigns 5 to x, then tests 5 (true)
    printf("always runs\n");
}
The compiler will warn under -Wall. Read your warnings. Defensive trick: write the constant on the left (if (5 == x)) so an accidental single = becomes a compile error.
Bug 2: The dangling else
When you skip the braces, an else binds to the nearest unmatched if, not the one your indentation suggests:
if (x > 0)
    if (y > 0)
        printf("both positive\n");
else
    printf("x is not positive?\n");
    // actually runs when x > 0 and y <= 0
Fix: always use braces, even for single-statement bodies. The compiler will not catch this for you.
Bug 3: Missing break in switch
If you forget a break, execution falls through into the next case:
switch (n) {
    case 1: printf("one\n");
    case 2: printf("two\n");  // no break above!
    case 3: printf("three\n"); break;
}
// If n is 1, this prints: one, two, three
Fix: end every case with break. (Intentional fall-through is a real pattern, but until you have a reason, treat the missing break as a bug.)
Bug 4: Accidental semicolon after if
A stray semicolon turns an if into an empty statement:
if (x > 0);  // BUG: the if does nothing
{
    printf("always runs\n");
}
The block runs every time, regardless of x. The compiler accepts this; -Wall may warn. When your conditional “always runs”, look for a stray semicolon first.
5. In-Class Work

Two things to do in class.

  • Work through the logic tracer below. Eight prediction rounds. You read a code snippet with variable values, predict what prints, then see a step-by-step trace including which expressions got short-circuited. About 25 minutes.
  • Complete Lab 04: VFR Go/No-Go. Auto-graded through GitHub Classroom. Read ceiling, visibility, and crosswind; combine logical operators with conditionals to print a GO or NO-GO decision. Full instructions in the lab repo.

Logic Tracer

Eight rounds. Each one shows you a small snippet, the current values of the variables, and asks what prints. After you predict, the widget walks you through the evaluation step by step, including which conditions got short-circuited and which conditionals ran.

Before you begin

Enter your name. It will appear on the completion screen so you can include it in your screenshot for the Blackboard reflection quiz.

CS210 Lesson 4 · Logical Operators Tracer

Read the code, predict what prints, then check yourself. Watch what short-circuit evaluation does to the order things get evaluated in.
Round 1 of 8
How this works: Each round shows a snippet of C with the values of the variables on top. You predict what gets printed, then click Check. After you answer, the trace reveals the steps the compiler evaluates. A yellow-highlighted step means short-circuit evaluation skipped the right-hand operand because the result was already determined.
6. After Class
  • Finish Lab 04 if you did not complete it in class. Submit through GitHub Classroom before Lesson 5.
  • Open the Lesson 4 reflection quiz in Blackboard. Enter your tracer completion code, answer the reflection prompt, and attach your screenshot of the tracer completion screen.
  • Read Beej-C Chapter 3 (loop sections) for Lesson 5.
  • Replay the logic tracer. Try predicting before you read the values; harder, more useful.
  • Heads up: the next quiz covers conditionals, loops, and functions (Lessons 4 through 6).
Need help? Schedule EI with your instructor. Bring specific code or specific screenshots, and the exact error message or output you do not understand. Specific questions get unstuck quickly.