Operators and Expressions

Comparison and Logical Operators

Comparison and logical operators help a program make comparisons of values in order to make choices about what to do.

Comparison operators allow the program to ask a question about the relationship between two values. The result will be true or false depending on the values being compared.

Logical operators are used with Boolean results or with other values to produce one or more Boolean results, which can then be combined to test various situations.

The six comparison operators are:

  • == equal to

  • != not equal to

  • < less than

  • > greater than

  • <= less than or equal to

  • >= greater than or equal to

Each of these operators takes two operands, performs the comparison between them, and returns true or false.

int left{10};
int right{20};

bool same{left == right};
bool different{left != right};
bool smaller{left < right};

Parentheses are not always necessary around a comparison, but they are a good idea to make your intention more visible within the overall expression. Arithmetic operands of different types will go through the usual arithmetic conversions first, in which case both sides will become a common type and will then be compared.

Be careful not to use the single =, which is the assignment operator, rather than == when you want to compare.

An assignment can also produce a result equal to the value being assigned. If used inside an if expression, for example, it may often be a logic error and quite hard to spot.

Floating point comparisons require some additional consideration. Since many decimal numbers can't be precisely represented in binary, they may end up differing by only a very small amount even though they appear to be equal to each other mathematically.

Using == to compare two floating point numbers may therefore result in false.

The three logical operators are:

  • && logical and

  • || logical or

  • ! logical not

The logical and operator && will return true only if the two operands are true.

The logical or operator || will return true if at least one of the operands is true.

The logical not operator ! reverses the value of a Boolean variable.

bool has_permission{true};
bool is_active{false};

bool allowed{has_permission && is_active};
bool either{has_permission || is_active};
bool flipped{!has_permission};

Arithmetic variables may also be used with logical operators. These will be converted to bool before the operation takes place. A value of zero is treated as false, while all nonzero values are true.

The && and || operators evaluate their operands from left to right and stop executing as soon as the result is certain. This behavior is known as short circuit evaluation.

If the left operand of an && operation is false, there is no point evaluating the right hand side because the result can never be true.

Similarly, if the left operand of a || operation is true, there is no point evaluating the right hand side because the result can never be false.

int value{0};

if (value != 0 && 100 / value > 5)
{
    // The division is not performed when value is zero.
}

This behavior can be very useful. It means that part of an expression will not execute when it is unnecessary. It is, however, inadvisable for conditions to only write required results to variables on the right hand side of a logical operator.

It is common to use more than one comparison linked with logical operators in the condition of an if statement.

Comparison operators take precedence over logical operators, so comparisons are evaluated first. Parentheses, however, can make your intent clearer when many comparisons have been chained together using logical operators.

int age{25};
int score{80};

bool eligible{(age >= 18) && (score >= 70)};

Comparison operators enable a program to test if one value is equal to, greater than, less than, or equal to some other value. They allow a test to determine whether one or several conditions are true before executing another command or set of commands.

The logical operators can be used in many comparisons, with some operands of a logical expression potentially not being evaluated due to short circuit evaluation.

#include <iostream>

int main()
{
    int x{7};
    int y{12};

    std::cout << "x == y: " << (x == y) << '\n';
    std::cout << "x != y: " << (x != y) << '\n';
    std::cout << "x < y:  " << (x < y) << '\n';
    std::cout << "x > y:  " << (x > y) << '\n';
    std::cout << "x <= y: " << (x <= y) << '\n';
    std::cout << "x >= y: " << (x >= y) << '\n';
    std::cout << '\n';

    bool ready{true};
    bool enabled{false};

    std::cout << "ready && enabled: "
              << (ready && enabled)
              << '\n';

    std::cout << "ready || enabled: "
              << (ready || enabled)
              << '\n';

    std::cout << "!ready: "
              << (!ready)
              << '\n';

    std::cout << '\n';

    int divisor{0};

    if (divisor != 0 && 100 / divisor > 10)
    {
        std::cout << "Division performed\n";
    }
    else
    {
        std::cout << "Division skipped because divisor is zero\n";
    }

    int age{22};
    int score{85};

    if ((age >= 18) && (score >= 60))
    {
        std::cout << "Candidate meets both requirements\n";
    }
}
Exercise: Comparison and Logical OperatorsStarter code, hints and solutionOpenClose
Guided practiceBeginner · 10–15 min

Practice: Comparison and Logical Operators

Work through the mission, reveal hints only when needed, and compare your result with the model solution.

Your challenge

Change enabled to true while leaving ready true. Predict which AND and OR results change, and keep the division-by-zero guard intact.

Mission checklist

  1. Run the starter as a baseline, then predict the change requested in Your challenge.
  2. Make that change in your editor; use the lesson-specific hints if you need help.
  3. Compile and run your answer, then compare with the worked solution and explain the result.

Starter program

This is the working baseline, not the completed answer. Compile as C++20, then make the change described above.

#include <iostream>

int main()
{
    int x{7};
    int y{12};

    std::cout << "x == y: " << (x == y) << '\n';
    std::cout << "x != y: " << (x != y) << '\n';
    std::cout << "x < y:  " << (x < y) << '\n';
    std::cout << "x > y:  " << (x > y) << '\n';
    std::cout << "x <= y: " << (x <= y) << '\n';
    std::cout << "x >= y: " << (x >= y) << '\n';
    std::cout << '\n';

    bool ready{true};
    bool enabled{false};

    std::cout << "ready && enabled: "
              << (ready && enabled)
              << '\n';

    std::cout << "ready || enabled: "
              << (ready || enabled)
              << '\n';

    std::cout << "!ready: "
              << (!ready)
              << '\n';

    std::cout << '\n';

    int divisor{0};

    if (divisor != 0 && 100 / divisor > 10)
    {
        std::cout << "Division performed\n";
    }
    else
    {
        std::cout << "Division skipped because divisor is zero\n";
    }

    int age{22};
    int score{85};

    if ((age >= 18) && (score >= 60))
    {
        std::cout << "Candidate meets both requirements\n";
    }
}

Hints

Hint 1

For ready && enabled, both Boolean operands must be true; for ready || enabled, one true operand is enough. Here && is logical AND, not a reference declaration.

Hint 2

Flip enabled to true and predict which Boolean outputs change. In the separate divisor test, keep divisor != 0 on the left so zero cannot reach the division.

Worked solution

enabled is changed from false to true. ready && enabled therefore changes from false to true because both operands are true; the OR result remains true. The division guard is preserved so zero cannot reach the division.

#include <iostream>

int main()
{
    int x{7};
    int y{12};

    std::cout << "x == y: " << (x == y) << '\n';
    std::cout << "x != y: " << (x != y) << '\n';
    std::cout << "x < y:  " << (x < y) << '\n';
    std::cout << "x > y:  " << (x > y) << '\n';
    std::cout << "x <= y: " << (x <= y) << '\n';
    std::cout << "x >= y: " << (x >= y) << '\n';
    std::cout << '\n';

    bool ready{true};
    bool enabled{true};

    std::cout << "ready && enabled: "
              << (ready && enabled)
              << '\n';

    std::cout << "ready || enabled: "
              << (ready || enabled)
              << '\n';

    std::cout << "!ready: "
              << (!ready)
              << '\n';

    std::cout << '\n';

    int divisor{0};

    if (divisor != 0 && 100 / divisor > 10)
    {
        std::cout << "Division performed\n";
    }
    else
    {
        std::cout << "Division skipped because divisor is zero\n";
    }

    int age{22};
    int score{85};

    if ((age >= 18) && (score >= 60))
    {
        std::cout << "Candidate meets both requirements\n";
    }
}

Example output

x == y: 0
x != y: 1
x < y:  1
x > y:  0
x <= y: 1
x >= y: 0

ready && enabled: 1
ready || enabled: 1
!ready: 0

Division skipped because divisor is zero
Candidate meets both requirements

0 comments

No comments yet. Be the first.

Add a comment

About CppLearn

CppLearn is an interactive, free reference for modern C++. In each lesson, you'll find out how the language works, rather than just lines of code that you can copy and paste. We cover concepts starting from beginner lessons on fundamentals and proceed to templates, move semantics, smart pointers, and areas that usually trap or scare C++ learners.