If-Else Statements
Decision-making is at the heart of every program. C++ if/else statements evaluate a condition and choose a branch of code to execute. Mastering conditionals — including edge cases like dangling else and short-circuit evaluation — is essential before moving to loops and functions.
Basic if Statement
#include <iostream>
using namespace std;
int main() {
int temperature = 35;
if (temperature > 30) {
cout << "It's hot outside.\n";
}
// Without braces — only the NEXT statement is in the if block
// Avoid this style: it's error-prone
if (temperature > 0)
cout << "Above freezing.\n";
return 0;
}
// Output:
// It's hot outside.
// Above freezing.Note: Always use curly braces {} even for single-statement if blocks. The "dangling else" bug and accidental multi-statement conditions are common pitfalls when braces are omitted.
if-else
#include <iostream>
using namespace std;
int main() {
int score = 72;
if (score >= 90) {
cout << "Excellent!\n";
} else {
cout << "Keep practising.\n";
}
// Output: Keep practising.
// Boolean expression
bool isLoggedIn = true;
if (isLoggedIn) {
cout << "Welcome back!\n";
} else {
cout << "Please log in.\n";
}
return 0;
}if-else if-else Chain
#include <iostream>
using namespace std;
string getGrade(int score) {
if (score >= 90) {
return "A";
} else if (score >= 80) {
return "B";
} else if (score >= 70) {
return "C";
} else if (score >= 60) {
return "D";
} else {
return "F";
}
}
int main() {
cout << getGrade(95) << "\n"; // A
cout << getGrade(83) << "\n"; // B
cout << getGrade(71) << "\n"; // C
cout << getGrade(55) << "\n"; // F
return 0;
}Only the first matching branch executes — once found, the rest of the chain is skipped.
Nested if Statements
#include <iostream>
using namespace std;
int main() {
int age = 20;
bool hasID = true;
bool isMember = false;
if (age >= 18) {
if (hasID) {
if (isMember) {
cout << "Member discount applied.\n";
} else {
cout << "Full price — consider membership!\n";
}
} else {
cout << "ID required for entry.\n";
}
} else {
cout << "Under 18 — access denied.\n";
}
// Output: Full price — consider membership!
return 0;
}Note: Deeply nested conditions are hard to read. Use logical operators (&&, ||) or early returns to flatten the nesting.
Combining Conditions with Logical Operators
#include <iostream>
using namespace std;
int main() {
int age = 20;
bool hasTicket = true;
// AND — both conditions must be true
if (age >= 18 && hasTicket) {
cout << "Entry granted.\n";
}
// OR — at least one condition must be true
bool isAdmin = false;
bool isOwner = true;
if (isAdmin || isOwner) {
cout << "Access to settings.\n";
}
// NOT — invert a condition
bool isWeekend = false;
if (!isWeekend) {
cout << "Working day.\n";
}
// Complex condition — use parentheses for clarity
int score = 85;
string role = "student";
if ((score >= 80 && role == "student") || role == "teacher") {
cout << "Eligible for award.\n";
}
return 0;
}if with Initialiser (C++17)
C++17 allows an initialisation statement inside the if condition — the variable is scoped to the if-else block:
#include <iostream>
#include <map>
using namespace std;
int main() {
map<string, int> scores = {{"Alice", 92}, {"Bob", 78}};
// C++17: initialise and test in one line
if (auto it = scores.find("Alice"); it != scores.end()) {
cout << "Alice's score: " << it->second << "\n"; // 92
}
// 'it' is not accessible here — scoped to the if block
if (int result = scores.count("Charlie"); result == 0) {
cout << "Charlie not found.\n";
}
return 0;
}constexpr if (C++17)
if constexpr is evaluated at compile time — the other branch is not compiled at all:
#include <iostream>
#include <type_traits>
using namespace std;
template <typename T>
void printType(T value) {
if constexpr (is_integral_v<T>) {
cout << "Integer: " << value << "\n";
} else if constexpr (is_floating_point_v<T>) {
cout << "Float: " << value << "\n";
} else {
cout << "Other type\n";
}
}
int main() {
printType(42); // Integer: 42
printType(3.14); // Float: 3.14
printType("hello"); // Other type
return 0;
}This is essential in template programming — it lets you write type-specific logic without specialisation.
Common Mistakes
// 1. Assignment instead of comparison (= vs ==)
int x = 5;
if (x = 10) { // Always true — assigns 10 to x!
cout << "This always runs!\n";
}
// Fix: if (x == 10)
// 2. Dangling else — which 'if' does the 'else' belong to?
if (x > 0)
if (x > 10)
cout << "Large positive\n";
else // This belongs to the INNER if!
cout << "Confusing!\n";
// Fix: Always use braces
// 3. Floating-point equality
double a = 0.1 + 0.2;
if (a == 0.3) { // May be false due to float precision!
cout << "Equal\n";
}
// Fix: compare with an epsilon
const double EPS = 1e-9;
if (abs(a - 0.3) < EPS) {
cout << "Equal (within epsilon)\n";
}Practical Example: Loan Eligibility Checker
#include <iostream>
#include <string>
using namespace std;
struct Applicant {
string name;
int age;
double annualIncome;
int creditScore;
bool hasExistingDebt;
};
string checkLoanEligibility(const Applicant& a) {
// Age requirement
if (a.age < 21 || a.age > 70) {
return "REJECTED: Age must be between 21 and 70.";
}
// Income requirement
if (a.annualIncome < 300000) {
return "REJECTED: Minimum annual income is ₹3,00,000.";
}
// Credit score
if (a.creditScore < 600) {
return "REJECTED: Credit score below minimum (600).";
}
// Existing debt check
if (a.hasExistingDebt && a.creditScore < 750) {
return "REJECTED: Existing debt requires credit score ≥ 750.";
}
// Determine loan tier
if (a.creditScore >= 800 && a.annualIncome >= 1000000) {
return "APPROVED: Premium tier — up to ₹50,00,000 at 8.5%";
} else if (a.creditScore >= 700) {
return "APPROVED: Standard tier — up to ₹20,00,000 at 10.5%";
} else {
return "APPROVED: Basic tier — up to ₹5,00,000 at 13%";
}
}
int main() {
Applicant applicants[] = {
{"Alice", 28, 1500000, 810, false},
{"Bob", 22, 250000, 700, false},
{"Charlie", 45, 800000, 680, true},
{"Diana", 35, 600000, 750, true},
};
for (const auto& a : applicants) {
cout << a.name << ": " << checkLoanEligibility(a) << "\n";
}
// Alice: APPROVED: Premium tier — up to ₹50,00,000 at 8.5%
// Bob: REJECTED: Minimum annual income is ₹3,00,000.
// Charlie: REJECTED: Existing debt requires credit score ≥ 750.
// Diana: APPROVED: Standard tier — up to ₹20,00,000 at 10.5%
return 0;
}Summary
if/else if/else— evaluates conditions top to bottom, executes the first matching branch- Always use curly braces — they prevent the dangling-else bug and accidental scope errors
- Combine conditions with
&&(AND),||(OR),!(NOT) — short-circuit evaluation stops early - Never use
=when you mean==in conditions — the compiler may warn but it compiles - Never compare floats with
==— use an epsilon comparison instead - C++17 if with initialiser scopes a variable to the if-else block — cleaner than declaring it before
if constexprevaluates at compile time — the dead branch is eliminated, enabling efficient template code
Next, we'll look at the switch statement — a cleaner way to branch on discrete integer or enum values.