Operators
C++ inherits C's operators — arithmetic, comparison, logic, bitwise and assignment — and adds a few of its own, such as the three-way comparison <=>. Most behave just as you'd expect; a few details like integer division and short-circuiting are worth knowing well.
Arithmetic
#include <iostream> int main() { int a = 17, b = 5; std::cout << a + b << ' ' << a - b << ' ' << a * b << ' ' << a / b << ' ' << a % b << '\n'; std::cout << -17 / 5 << ' ' << -17 % 5 << '\n'; std::cout << 17.0 / 5 << '\n'; }
22 12 85 3 2 -3 -2 3.4
Integer division truncates toward zero; % gives the remainder and only works on integers. Dividing an integer by zero is undefined behaviour — check first.
Assignment, increment and decrement
#include <iostream> int main() { int score = 10; score += 5; // 15 score *= 2; // 30 score -= 4; // 26 score /= 2; // 13 ++score; // 14 int before = score++; // before = 14, score = 15 std::cout << score << ' ' << before << '\n'; }
15 14
Prefer the prefix form (++i) when you don't need the old value — for class types like iterators it can avoid a copy. Never modify a variable twice in one expression (i = i++).
Comparison and logic
#include <iostream> int main() { int age = 20; bool adult = age >= 18; bool teen = age >= 13 && age <= 19; std::cout << std::boolalpha; // print bools as words std::cout << adult << ' ' << teen << ' ' << !adult << ' ' << (age == 20 || age == 30) << '\n'; }
true false false true
&& and || short-circuit: the right side runs only if needed. That makes guards like count != 0 && total / count > 10 safe. C++ also accepts the words and, or and not as alternative spellings.
Three-way comparison
C++20's "spaceship" operator <=> compares two values once and tells you whether the first is less, equal or greater. It's mainly used to give your own classes all six comparisons at once (lesson 34):
#include <compare> #include <iostream> int main() { auto r = 3 <=> 7; std::cout << std::boolalpha << (r < 0) << ' ' << (r == 0) << ' ' << (r > 0) << '\n'; }
true false false
The conditional operator
#include <iostream> int main() { for (int n : {1, 3}) { std::cout << n << (n == 1 ? " item" : " items") << '\n'; } }
1 item 3 items
Bitwise operators
| Operator | Meaning |
|---|---|
& | ^ ~ | AND, OR, XOR, NOT on each bit |
<< >> | Shift bits left/right (the same symbols as stream insertion/extraction — context decides) |
#include <bitset> #include <iostream> int main() { unsigned flags = 0b0101; flags |= 0b1000; // set a bit flags &= ~0b0001u; // clear a bit std::cout << std::bitset<4>(flags) << ' ' << flags << '\n'; std::cout << (1u << 10) << '\n'; }
1100 12 1024
Use unsigned types for bit manipulation. std::bitset prints bits nicely, and C++20's <bit> header adds helpers such as std::popcount.
Precedence
Multiplication binds tighter than addition, comparisons tighter than &&, which binds tighter than ||. Two gotchas: bitwise & binds more loosely than ==, and << with cout binds tighter than comparisons — so std::cout << a < b; doesn't do what it looks like. When in doubt, parenthesise.
Try it yourself
Decide whether each year is a leap year: divisible by 4, except centuries, unless divisible by 400.
1900 is not a leap year 2000 is a leap year 2024 is a leap year 2026 is not a leap year