Skip to content
Theory · Operators and Expressions · lesson 3 of 8

Comparisons, logic, ++ and --

A program constantly needs yes-or-no answers: is the user an adult, does a number fall within a range. A comparison gives such an answer, and its result has type bool:

C++
#include <iostream>

int main() {
    int age = 20;
    bool adult = age >= 18;
    bool teen = age >= 13 && age <= 19;
    std::cout << adult << ' ' << teen << '\n';  // 1 0
}

std::cout prints true as 1 and false as 0. The variable teen is false: 20 <= 19 does not hold, and && requires both sides to hold.

Comparisons

There are six basic comparison operators:

  • == — equal;
  • != — not equal;
  • < — less than;
  • <= — less than or equal;
  • > — greater than;
  • >= — greater than or equal.

Equality is tested with the double sign ==, while a single = assigns a value. Numbers of different types can be compared too: 2 < 2.5 gives true, because 2 is first converted to double.

Logical operators

There are three logical operators:

  • && (AND) gives true when both operands hold;
  • || (OR) gives true when at least one holds;
  • ! (NOT) turns true into false and back: !(age >= 18) holds for a minor.

As an operand of &&, || or !, a number turns into a bool: 0 gives false, and any other number, true.

&& and || evaluate the left operand first. If it already decides the answer, the right one is not evaluated at all. For && that is a false on the left, for || a true. Skipping the right operand like this is called short-circuit evaluation:

C++
#include <iostream>

bool is_even(int n) {
    std::cout << "is_even(" << n << ")\n";
    return n % 2 == 0;
}

int main() {
    bool a = is_even(3) && is_even(4);  // is_even(3)
    bool b = is_even(4) || is_even(3);  // is_even(4)
    std::cout << a << ' ' << b << '\n';  // 0 1
}

The calls is_even(4) in the first line and is_even(3) in the second never happened: the left side had already given the answer. So the right operand can count on the left one already holding: d != 0 && n / d > 2 never divides by zero.

The ++ and -- operators

++a increases a variable by one, and --a decreases it. Each of these operators has two forms. The prefix form ++a increases a first and returns the new value. The postfix form a++ increases a too, but returns the old value:

C++
int a = 5;
int b = a++;
int c = ++a;
std::cout << a << ' ' << b << ' ' << c << '\n';  // 7 5 7

b got 5, the value of a before the first increment. When the result is not used, as in a standalone statement ++a;, the two forms do the same thing. Other operations have a similar shorthand: a += 5 means a = a + 5, and -=, *=, /= and %= work the same way.

Common mistake

Beginners write a check that a number falls within a range the same way as in math:

C++
#include <iostream>

int main() {
    int x = 15;
    bool in_range = 0 < x < 10;  // ✗
    std::cout << in_range << '\n';  // 1
}
TEXT
warning: result of comparison of constant 10 with expression of type 'bool' is always true [-Wtautological-constant-out-of-range-compare]

The compiler only warns. The expression reads as (0 < x) < 10: 0 < x gives true or false, that is 1 or 0, and both 1 < 10 and 0 < 10 hold. So the result is true for any x. A range is checked with two comparisons: 0 < x && x < 10.

Key points

  • A comparison gives a bool, and equality is tested with ==, not =.
  • && and || skip the right operand when the left one already decides the answer.
  • a++ returns the old value, and ++a the new one.
  • A range is checked with two comparisons: 0 < x && x < 10.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way