C++ · Beginner
Conditions in C++: if, else and switch
In short: A condition in C++ is an expression tested for true or false. if runs a block only when its condition holds, else if and else provide alternatives that are tried in order, switch selects a case by an integer or character value, and the ?: operator chooses between two values inside a single expression.
Choosing a path
Without conditions a program runs the same statements every time. if makes execution depend on data: the condition in parentheses is evaluated, and the block that follows runs only when it is true. A condition is usually a comparison such as grams <= 100 or a combination of comparisons joined with && and ||. Any numeric value is also accepted and counts as true when it is not zero, but writing the comparison out, count != 0 rather than count, tells the reader what is being asked.
else gives the other branch, and else if lets you test a series of alternatives. The chain is evaluated from the top; the first condition that is true wins and the rest are skipped, even if they would also have been true. That ordering is what lets the postage example test grams <= 100 first and grams <= 500 second: by the time the second test runs, anything 100 or below has already been handled. The final else catches everything the earlier tests did not.
Braces around each branch are optional when the branch is a single statement, but leaving them out is a well-known source of bugs, because a second statement added later sits outside the if and runs unconditionally. Use braces always; they cost two characters.
switch is a specialised form for comparing one value against several constants. The value must be an integer type, a char or an enumeration; a std::string cannot be switched on. Each case label names a constant, and execution jumps to the matching label and then keeps going downwards until it meets break. That fall-through behaviour is deliberate, and it is used on purpose when several labels share one body, such as case 'r': immediately followed by case 'R':. Every other case needs its break. default handles values no label matched.
The conditional operator condition ? a : b is an expression, not a statement: it produces a when the condition is true and b otherwise. It is the right tool when the only difference between two branches is a value being assigned or printed. Nesting it makes code hard to read, so keep it to one level.
C++17 added an initialiser to if: if (int shortfall = ordered - stock; shortfall > 0) declares shortfall, then tests it. The variable exists in both the if and the else branch and vanishes afterwards, which keeps names from leaking into the rest of the function.
Syntax
if (condition) {
// runs when condition is true
} else if (otherCondition) {
// tried only when the first condition was false
} else {
// runs when nothing above matched
}
switch (integerOrChar) {
case 1:
// ...
break; // without break, execution falls into the next case
case 2:
case 3: // two labels sharing one body
// ...
break;
default:
// ...
}
result = condition ? valueIfTrue : valueIfFalse;
if (auto value = compute(); value > limit) { // C++17: declare, then test
// value is visible here and in the else branch
}The condition is any expression convertible to bool. Comparison and logical operators are covered in the operators lesson.
An if / else if / else chain
A parcel's weight in grams is mapped to a postage band; only the first matching band applies.
#include <iostream>
int main() {
int grams;
std::cin >> grams;
int pence;
if (grams <= 100) {
pence = 95;
} else if (grams <= 500) {
pence = 160;
} else if (grams <= 2000) {
pence = 320;
} else {
pence = 650;
}
std::cout << "Weight: " << grams << " g\n";
std::cout << "Postage: " << pence << " p\n";
if (grams > 2000) {
std::cout << "Take it to the counter\n";
}
return 0;
}Input given to the program: 750
Output
Weight: 750 g Postage: 320 p
With 750 the first two tests fail and the third succeeds, so pence becomes 320 and the else is skipped. Because every branch assigns pence, the variable is guaranteed a value before it is printed; the compiler can check that for you, which is a good reason to make chains exhaustive with a final else. The separate if at the end has no else, so nothing prints for 750.
switch on a menu character
A library kiosk reads one character; two labels share a body, and default catches the rest.
#include <iostream>
int main() {
char choice;
std::cin >> choice;
switch (choice) {
case 'r':
case 'R':
std::cout << "Renew a loan\n";
break;
case 'b':
std::cout << "Borrow a book\n";
break;
case 'q':
std::cout << "Quit\n";
break;
default:
std::cout << "Unknown option: " << choice << "\n";
}
std::cout << "Menu closed\n";
return 0;
}Input given to the program: R
Output
Renew a loan Menu closed
'R' jumps to its label, which has no statements of its own, so execution falls into the body under 'r' and prints the renewal message. The break then leaves the switch entirely, skipping the other cases and landing on the line after the closing brace. Remove that break and the program would also print "Borrow a book", because the next case would run as well.
The ?: operator, an if with an initialiser and nesting
A stock check uses three forms of decision, each where it reads best.
#include <iostream>
#include <string>
int main() {
int stock;
int ordered;
std::cin >> stock >> ordered;
std::string status = (ordered <= stock) ? "in stock" : "back order";
std::cout << "Status: " << status << "\n";
if (int shortfall = ordered - stock; shortfall > 0) {
std::cout << "Short by " << shortfall << "\n";
} else {
std::cout << "Surplus of " << -shortfall << "\n";
}
if (ordered > 0) {
if (ordered > 100) {
std::cout << "Bulk discount applies\n";
} else {
std::cout << "Standard pricing\n";
}
}
return 0;
}Input given to the program: 40 150
Output
Status: back order Short by 110 Bulk discount applies
The ?: line picks one of two strings and assigns it, which would take five lines as an if/else. The C++17 form declares shortfall for exactly the two branches that need it; after the closing brace of the else the name is gone. The nested if shows that an inner else pairs with the nearest if, which the braces make unambiguous. With 150 ordered against 40 in stock, all three decisions take their second path or the bulk branch.
Which form to use
| Form | Best for | Not suitable for |
|---|---|---|
| if / else if / else | ranges, combined conditions, anything involving < or > | nothing; it is the general tool |
| switch | one int or char value against several fixed constants | std::string, doubles, ranges |
| condition ? a : b | choosing one of two values inside an expression | branches that do several things |
| if (init; condition) | a value needed only inside the branches (C++17) | code that must compile as C++14 or older |
Common mistakes
A semicolon straight after the condition
Why it goes wrong:
if (grams > 2000);is a complete if statement with an empty body. The block on the next line is no longer part of the if, so it always runs.Fix: Never put a semicolon after the closing parenthesis of an if, while or for header.
C++ · fixif (grams > 2000) { std::cout << "counter service\n"; }Forgetting break inside switch
Why it goes wrong: Execution continues into the following case, so choosing 'b' would print both the borrow message and the quit message.
Fix: End every case body with
breakunless the fall-through is intended, and add a comment when it is.Assigning inside the condition
Why it goes wrong:
if (stock = 0)sets stock to zero and tests zero, which is false, so the branch never runs and the data is destroyed in passing.Fix: Compare with
==. Compile with -Wall so the compiler flags an assignment used as a condition.Dropping the braces and adding a second statement later
Why it goes wrong: Only the first statement after
if (...)belongs to it. An indented second line looks like part of the branch but runs unconditionally.Fix: Use braces on every branch, even the one-line ones.
C++ · fixif (late) { fine += 50; std::cout << "Fine added\n"; // inside the if only because of the braces }
Where you use this
Validating input is the first job of almost every program, and it is pure conditions. A booking tool reads a number of seats; before doing anything with it, it checks that the number is at least 1 and no larger than the room, and reports which rule was broken. A menu-driven tool reads one command character and dispatches with a switch. Range checks, membership rules and tiered pricing all come down to the same shapes: an if/else chain when the tests involve ranges, a switch when a single value selects among fixed options, and ?: when two branches differ only in a value.
if (seats < 1) {
std::cout << "At least one seat is needed\n";
} else if (seats > capacity) {
std::cout << "Only " << capacity << " seats available\n";
} else {
book(seats);
}Key points
if (condition) { }runs its block only when the condition is true;elsesupplies the alternative.- In an
else ifchain the first true condition wins and the remaining tests are skipped. - Always use braces; a branch without them is exactly one statement long.
switchworks on integers and chars, not strings; each case needsbreakunless fall-through is intended.a ? b : cis an expression that picks one of two values.- C++17
if (init; condition)scopes a helper variable to the if and else branches. =inside a condition assigns; use==and compile with -Wall.
Try it yourself
The program labels a temperature as cold below 10 degrees and mild otherwise. Add a third band so that 25 degrees and above prints hot, keeping cold and mild as they are.
#include <iostream>
int main() {
int degrees;
std::cin >> degrees;
if (degrees < 10) {
std::cout << "cold\n";
} else {
std::cout << "mild\n";
}
return 0;
}
27hot#include <iostream>
int main() {
int degrees;
std::cin >> degrees;
if (degrees < 10) {
std::cout << "cold\n";
} else if (degrees < 25) {
std::cout << "mild\n";
} else {
std::cout << "hot\n";
}
return 0;
}
Practise this
Exercises for this lesson are in the C++ practice set.
Related lessons
- Operators in C++C++ arithmetic, comparison, logical and assignment operators: integer division and modulo, prefix versus postfix ++, short-circuit evaluation and precedence.9 min
- Loops in C++: for, while and do-whileC++ loops explained: the three parts of a for loop, while and do-while, reading input until it ends, nested loops, and when to reach for break or continue.9 min
Frequently asked questions
Can I use switch with a std::string in C++?
No. The value in a switch must be an integer type, a char or an enumeration, because the compiler builds the jump from constant case labels. For strings write an if / else if chain using ==, which std::string supports: if (command == "renew") { ... } else if (command == "quit") { ... }.
Are braces required after if in C++?
Not by the language: without braces, exactly one statement belongs to the if. They are required by good practice, because a second statement added later, however it is indented, runs unconditionally. The only safe habit is to brace every branch.
What does if with an initialiser add in C++17?
It lets you declare a variable, then test it, in the header: if (int n = read(); n > 0). The variable is visible in the if branch and the else branch and nowhere else. Before C++17 the same effect needed a declaration on the line above, which left the name alive for the rest of the enclosing block.
How this page was checked. Every program on it was run with GCC 13 (C++17) at build time by the publishing checks, and the output shown is what it printed. Running C++ inside the browser is not available yet, so the Run button is absent rather than pretending; copy the code and run it with GCC 13 (C++17) locally.