if, else & switch

C++ · Lesson 7 of 32 6 min read Updated

Programs become useful when they can make decisions: give a discount only to members, show "Fail" only below the pass mark, run a different action for each menu choice. In this lesson you will learn how C++ compares values, how to combine conditions, and how to choose between if chains and switch.

Comparison operators and bool

A condition is an expression that is either true or false, so its type is bool. You build conditions with comparison operators:

OperatorMeaningExample (with x = 7)Result
==equal tox == 7true
!=not equal tox != 7false
<less thanx < 5false
>greater thanx > 5true
<=less than or equalx <= 7true
>=greater than or equalx >= 10false

Note the double == for comparison. A single = is assignment, and mixing them up is one of the most common bugs in C and C++.

if, else if and else

An if statement runs a block of code only when its condition is true. Add else if for more choices and else for "everything else". C++ checks the conditions from top to bottom and runs only the first block whose condition is true.

C++
#include <print>

int main() {
    int marks = 76;

    if (marks >= 90) {
        std::println("Grade A+");
    } else if (marks >= 75) {
        std::println("Grade A");
    } else if (marks >= 60) {
        std::println("Grade B");
    } else if (marks >= 33) {
        std::println("Grade C");
    } else {
        std::println("Fail: please meet your teacher");
    }
}
Output
Grade A

With 76 marks, the first test (>= 90) is false, the second (>= 75) is true, so "Grade A" is printed and the rest of the chain is skipped. The order matters: if you tested >= 33 first, everyone who passed would get a C.

Always use braces, even for one-line blocks. Without braces only the next single statement belongs to the if, which leads to confusing bugs when someone adds a second line later.

Combining conditions: and, or, not

The logical operators join conditions:

  • && (and) is true only when both sides are true.
  • || (or) is true when at least one side is true.
  • ! (not) flips true to false and false to true.
C++
#include <print>

int main() {
    int age = 62;
    bool is_student = false;
    bool has_id = true;

    if ((age >= 60 || is_student) && has_id) {
        std::println("Concession fare applies");
    } else {
        std::println("Full fare");
    }

    if (!is_student) {
        std::println("No student pass needed");
    }

    auto label = (age >= 18) ? "adult" : "minor";
    std::println("Passenger type: {}", label);
}
Output
Concession fare applies
No student pass needed
Passenger type: adult

The brackets around age >= 60 || is_student make the meaning clear: senior citizens or students, and in both cases they must show an ID. && and || use short-circuit evaluation: if the left side already decides the answer, the right side is not evaluated at all. That is why if (count != 0 && total / count > 50) never divides by zero.

The last statement uses the conditional (ternary) operator condition ? a : b, which picks one of two values. Use it for short choices of a value; use if for actions.

if with an initializer

Since C++17 you can declare a variable inside the if itself, before a semicolon. The variable exists only inside the if and its else, which keeps it from leaking into the rest of the function.

C++
#include <print>
#include <string>

int main() {
    std::string email = "meera@example.in";

    if (auto at = email.find('@'); at != std::string::npos) {
        std::println("Username: {}", email.substr(0, at));
    } else {
        std::println("That is not an email address");
    }
    // 'at' does not exist here
}
Output
Username: meera

switch: choosing by value

When you compare one integer, character or enum against many fixed values, switch is often clearer than a long if chain.

C++
#include <print>

int main() {
    int day = 6;   // 1 = Monday ... 7 = Sunday

    switch (day) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        std::println("Weekday: college is open");
        break;
    case 6:
        std::println("Saturday: half day");
        [[fallthrough]];
    case 7:
        std::println("Weekend: cricket practice at 4 pm");
        break;
    default:
        std::println("Invalid day number");
    }
}
Output
Saturday: half day
Weekend: cricket practice at 4 pm

C++ jumps to the matching case and runs from there until it meets break. Without break, execution falls through into the next case. Stacking case 1: to case 5: uses this on purpose to share one action. For day 6, the code prints the Saturday line and then deliberately falls into case 7. The [[fallthrough]] attribute (C++17) tells the compiler and the reader that this is intentional, so -Wextra does not warn. default runs when no case matches.

A switch works with integers, characters and enums, but not with std::string or double. For text, use an if chain.

Comparing decimal numbers

Decimal numbers are stored in binary and often cannot be represented exactly, so 0.1 + 0.2 == 0.3 is false. Compare with a small tolerance instead:

C++
#include <cmath>
#include <print>

int main() {
    double a = 0.1 + 0.2;
    std::println("Exactly equal? {}", a == 0.3);
    std::println("Close enough? {}", std::abs(a - 0.3) < 1e-9);
}
Output
Exactly equal? false
Close enough? true

Common mistakes

  • Writing = instead of ==. if (marks = 100) assigns 100 and is always true. Compile with -Wall: GCC warns "suggest parentheses around assignment used as truth value".
  • Chaining comparisons like maths. if (0 < x < 10) does not do what you expect; it compares 0 < x (true or false, so 1 or 0) with 10. Write if (x > 0 && x < 10).
  • Forgetting break in a switch. The next case runs too. Add break or a deliberate [[fallthrough]];.
  • Putting a semicolon after the condition. if (x > 5); ends the if with an empty statement, so the block below always runs.

Key points

  • Conditions are bool expressions built with ==, !=, <, >, <= and >=.
  • if, else if and else run only the first block whose condition is true; always use braces.
  • &&, || and ! combine conditions and short-circuit from left to right.
  • if (init; condition) keeps a helper variable local to the if.
  • switch compares one integer, character or enum against fixed cases; use break and [[fallthrough]] deliberately.
  • Never compare decimals with ==; use a small tolerance.

Exercise

An electricity board in Pune charges Rs. 4 per unit for the first 100 units, Rs. 6 per unit for units 101 to 300, and Rs. 9 per unit above 300. Write a program that sets units to 340 and prints the bill. Then add a switch on a char category ('d' domestic, 'c' commercial) that adds a fixed charge of Rs. 50 or Rs. 150, printing "Unknown category" otherwise.

Show solution
C++
#include <print>

int main() {
    int units = 340;
    char category = 'd';
    int bill = 0;

    if (units <= 100) {
        bill = units * 4;
    } else if (units <= 300) {
        bill = 100 * 4 + (units - 100) * 6;
    } else {
        bill = 100 * 4 + 200 * 6 + (units - 300) * 9;
    }

    switch (category) {
    case 'd':
        bill += 50;
        break;
    case 'c':
        bill += 150;
        break;
    default:
        std::println("Unknown category");
    }

    std::println("Units: {}, bill: Rs. {}", units, bill);
}
Output
Units: 340, bill: Rs. 2010

For 340 units: 100 × 4 = 400, 200 × 6 = 1200 and 40 × 9 = 360, which is 1960, plus the domestic fixed charge of 50 gives 2010.

Quick Quiz

1. What does if (x = 0) do?

2. In if (count != 0 && total / count > 50), what happens when count is 0?

3. What happens in a switch when a case has no break?

4. Which type can NOT be used directly in a switch?

Learn C++ with a mentor

Free lessons get you started. Our Java, C & C++ Programming training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call