if, else & switch
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:
| Operator | Meaning | Example (with x = 7) | Result |
|---|---|---|---|
== | equal to | x == 7 | true |
!= | not equal to | x != 7 | false |
< | less than | x < 5 | false |
> | greater than | x > 5 | true |
<= | less than or equal | x <= 7 | true |
>= | greater than or equal | x >= 10 | false |
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.
#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");
}
}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.
#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);
}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.
#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
}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.
#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");
}
}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:
#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);
}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 compares0 < x(true or false, so 1 or 0) with 10. Writeif (x > 0 && x < 10). - Forgetting
breakin a switch. The next case runs too. Addbreakor a deliberate[[fallthrough]];. - Putting a semicolon after the condition.
if (x > 5);ends theifwith an empty statement, so the block below always runs.
Key points
- Conditions are
boolexpressions built with==,!=,<,>,<=and>=. if,else ifandelserun 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 theif.switchcompares one integer, character or enum against fixed cases; usebreakand[[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
#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);
}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?
A single = assigns; the value 0 converts to false. Use == to compare.
2. In if (count != 0 && total / count > 50), what happens when count is 0?
&& short-circuits: once the left side is false, the result is false and the right side is not evaluated.
3. What happens in a switch when a case has no break?
Without break, control falls through to the following case.
4. Which type can NOT be used directly in a switch?
switch works with integers, characters and enums only; use an if chain for strings.
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
