Lecture 4 — Expressions
Source: sc++/ch04.md Duration: 75 minutes
Learning Objectives
By the end of this lecture, students should be able to:
- Use the arithmetic operators
+ - * / %and explain the integer-vs-floating-point division trap - Build boolean expressions with comparison operators and the logical operators
&& || ! - Take advantage of short-circuit evaluation to write safe guard conditions
- Distinguish prefix (
++n) and postfix (n++) increment, and choose the right one - Use compound assignment (
+=,-=, etc.) and recognize the common bitwise operators - Read the ternary operator
?:and decide when to prefer it overif/else - Apply operator precedence rules and defend themselves with parentheses when in doubt
Materials
- Live coding terminal with
g++(-std=c++23 -Wall -Wextra -pedantic) - A text editor projected for the class
- Copies of
sc++/ch04.mdfor reference
0. Welcome and Review (5 min)
Review multiple choice (from lecture 3): What is the bug in
std::string greeting = "Hello, " + "world!";?- A. Missing
#include <string> - B.
std::stringdoes not allow+ - C. Both operands are string literals; at least one side must be a
std::string - D.
+should be+= - E. Ben got this wrong
Answer: C
- A. Missing
Today we leave behind pure storage and learn to compute with the values we have stored
1. Assignment (3 min)
int jumps = 0;
jumps = 42;
jumps = jumps + 1; // 43=evaluates the right-hand side first, then stores the result in the left- You can (and often do) use the variable itself on the right
Trap: if (x = 5) assigns 5 to x and then tests truthiness. Use == to compare. Enable -Wall to catch this.
2. Arithmetic Operators (8 min)
7 + 3 // 10
7 - 3 // 4
7 * 3 // 21
7 / 3 // 2 <-- integer division!
7 % 3 // 1 <-- modulo, integers onlyInteger Division
int wrong = 7 / 3; // 2
double right = 7.0 / 3; // 2.333...
double also = 7 / 3.0; // 2.333...- Two integer operands –> fractional part is truncated, not rounded
- At least one operand must be floating-point to keep the decimals
Trap: Integer division by zero is undefined behavior (typically a crash). Always check your divisor.
Modulo for Even/Odd
if (number % 2 == 0) {
std::cout << "even\n";
} else {
std::cout << "odd\n";
}%only works on integers — no%ondouble
3. Comparison Operators (4 min)
==, !=, <, >, <=, >= — all produce a bool.
| expression | result |
|---|---|
5 == 5 | true |
5 != 3 | true |
3 < 5 | true |
3 >= 5 | false |
- Remember from chapter 3: these also work on strings, character by character
4. Logical Operators and Short Circuit (10 min)
| operator | name | example |
|---|---|---|
&& | AND | a && b is true only if both are true |
\|\| | OR | a \|\| b is true if either is true |
! | NOT | !a inverts a bool |
Real example:
int pencils = 2;
int pens = 1;
bool has_calculator = true;
bool can_take_test = (pencils == 2 || pens == 1) && !has_calculator;Short Circuit
int x = 0;
if (x != 0 && 10 / x > 2) {
// safe --- the divide never runs when x is 0
}&&stops at the first false;||stops at the first true- This is guaranteed, not an optimization — you can rely on it for guard conditions
Tip: When in doubt about how logical operators group, use parentheses. ! binds tighter than && and ||.
5. Increment and Decrement (6 min)
int a = 5;
int b = ++a; // prefix: a is 6, b is 6
int c = a++; // postfix: c is 6 (old a), then a becomes 7- Prefix (
++a): increment, then yield the new value - Postfix (
a++): yield the current value, then increment - Stand-alone
n++;and++n;behave identically
Tip: Prefer prefix ++n as a habit. For complex types (like iterators in chapter 8) prefix can be measurably faster because it avoids copying the old value.
6. Compound Assignment (3 min)
int score = 100;
score += 50; // 150
score -= 25; // 125
score *= 2; // 250+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=- Pure shorthand — no behavior difference from
x = x + y
7. Bitwise Operators (Preview) (6 min)
0b1100 & 0b1010 // 0b1000 AND
0b1100 | 0b1010 // 0b1110 OR
0b1100 ^ 0b1010 // 0b0110 XOR
~0b1100 // flips all bits
0b0001 << 2 // 0b0100
0b1000 >> 2 // 0b00100bprefix lets you write binary literals directly- Bit-level work is coming in detail in chapter 7 — today is just a preview
Trap: && is not &, and || is not |. Do not confuse logical and bitwise operators.
Trap: ^ is not exponentiation! 2^2 is 0, not 4. (XOR of 10 and 10 is 00.)
8. The Ternary Operator (5 min)
int temperature = 30;
std::string weather = (temperature > 25) ? "hot" : "cool";condition ? value_if_true : value_if_false- Equivalent to a simple
if/else, but as a single expression - Best for short, obvious choices — fall back to
if/elsewhen logic gets hairy
9. Operator Precedence (8 min)
Show the chapter’s precedence table on the board. Call out the common gotchas:
- Multiplicative (
* / %) binds tighter than additive (+ -) - Comparison (
== !=) binds tighter than bitwise (& | ^) - Assignment is lower than almost everything else
The classic trap:
// BUG: parses as flags & (0x02 == 0x02)
if (flags & 0x02 == 0x02) { ... }
// CORRECT
if ((flags & 0x02) == 0x02) { ... }Tip: When in doubt, add parentheses. You do not get bonus points for memorizing the precedence table.
10. Try It — Live Demo (4 min)
#include <iostream>
#include <string>
int main()
{
int x = 10, y = 3;
std::cout << "x + y = " << x + y << "\n";
std::cout << "x / y = " << x / y << "\n";
std::cout << "x % y = " << x % y << "\n";
x += 5;
std::cout << "x += 5 => " << x << "\n";
int a = 5;
int b = ++a;
int c = a++;
std::cout << "a=" << a << " b=" << b << " c=" << c << "\n";
std::string result = (x > y) ? "Jump around!" : "U can't touch this";
std::cout << result << "\n";
}Have the class predict the values of a, b, and c before you run it.
11. Wrap-up Quiz Questions (3 min)
Q1. What does this print?
int a = 10;
int b = a++;
int c = ++a;
std::cout << a << " " << b << " " << c << "\n";A. 10 10 11 B. 11 10 11 C. 12 10 12 D. 12 11 12 E. Ben got this wrong
Answer: C — after b = a++, a=11, b=10. Then c = ++a makes a=12, c=12.
Q2. Why does this not crash?
int x = 0;
bool ok = (x != 0) && (100 / x > 5);A. The compiler optimizes away the divide B. Division by zero is actually fine C. Short-circuit evaluation — && stops after the first false D. ok is just a declaration, nothing runs E. Ben got this wrong
Answer: C
Q3. What does this print?
int score = 85;
std::string grade = (score >= 90) ? "A"
: (score >= 80) ? "B"
: (score >= 70) ? "C"
: "F";
std::cout << grade << "\n";A. A B. B C. C D. F E. Ben got this wrong
Answer: B
12. Assignment / Reading (1 min)
- Read: chapter 5 of Gorgo Starting C++, sections on
ifandwhileonly (we coverdo-while/for/switchnext week) - Do: chapter 5 exercises 1, 5, 7 (decision-making and while loops)
- Bring: a program that reads a number and classifies it even/odd and positive/negative/zero
Key Points to Reinforce
=stores,==compares — do not confuse them- Integer
/truncates; use adoubleoperand for real division %is integer only&&and||short-circuit — lean on that for guard conditions- Prefix vs postfix matters inside an expression
- Comparison binds tighter than bitwise — parenthesize bitwise checks
- When in doubt, parenthesize