Module 2.2

Conditionals in C++

Learn how to make decisions in your programs using conditional statements. Master if-else chains, switch statements, and nested conditions to control program flow based on different scenarios.

35 min read
Beginner
Hands-on Examples
What You'll Learn
  • if and if-else statements
  • else if chains
  • switch-case statements
  • Nested conditionals
  • Best practices
Contents
01

Introduction to Conditionals

Conditional statements allow your program to make decisions based on conditions. They are the foundation of program logic, enabling different code paths to execute depending on whether conditions are true or false.

Concept

Conditional Statement

A conditional statement evaluates a boolean expression and executes different blocks of code based on whether the condition is true or false.

Flow: if (condition) { /* true path */ } else { /* false path */ }

Types of Conditional Statements

if

Execute code only if condition is true

if-else

Two-way decision: true or false path

else if

Multiple conditions in sequence

switch

Multi-way branch based on value

02

The if Statement

The if statement is the simplest form of conditional. It executes a block of code only when the specified condition evaluates to true.

Basic Syntax

#include <iostream>
using namespace std;

int main() {
    int age = 18;
    
    // Simple if statement
    if (age >= 18) {
        cout << "You are an adult." << endl;
    }
    
    // Single-line if (no braces needed for one statement)
    if (age >= 18) cout << "Can vote!" << endl;
    
    // Multiple conditions with logical operators
    int score = 85;
    if (score >= 60 && score <= 100) {
        cout << "Valid passing score!" << endl;
    }
    
    return 0;
}

Condition Evaluation

#include <iostream>
using namespace std;

int main() {
    // In C++, any non-zero value is considered true
    int x = 5;
    
    if (x) {  // 5 is non-zero, so true
        cout << "x is truthy (non-zero)" << endl;
    }
    
    int y = 0;
    if (y) {  // 0 is false, this won't execute
        cout << "This won't print" << endl;
    }
    
    // Pointer check
    int* ptr = nullptr;
    if (ptr) {
        cout << "Pointer is valid" << endl;
    } else {
        cout << "Pointer is null" << endl;
    }
    
    // Common mistake: assignment vs comparison
    int a = 5;
    // if (a = 10) { }  // WRONG! This assigns 10 to a
    if (a == 10) { }    // CORRECT! This compares a to 10
    
    return 0;
}
Common Mistake: Using = (assignment) instead of == (comparison) in conditions. if (x = 5) assigns 5 to x and always evaluates to true!
03

The if-else Statement

The if-else statement provides two paths: one for when the condition is true, and another for when it's false.

#include <iostream>
using namespace std;

int main() {
    int number;
    cout << "Enter a number: ";
    cin >> number;
    
    // Basic if-else
    if (number % 2 == 0) {
        cout << number << " is even." << endl;
    } else {
        cout << number << " is odd." << endl;
    }
    
    // Checking positive/negative
    if (number > 0) {
        cout << "Positive number" << endl;
    } else if (number < 0) {
        cout << "Negative number" << endl;
    } else {
        cout << "Zero" << endl;
    }
    
    return 0;
}

Practical Example: Login Validation

#include <iostream>
#include <string>
using namespace std;

int main() {
    string username, password;
    const string correctUser = "admin";
    const string correctPass = "secret123";
    
    cout << "Username: ";
    cin >> username;
    cout << "Password: ";
    cin >> password;
    
    if (username == correctUser && password == correctPass) {
        cout << "Login successful! Welcome, " << username << endl;
    } else {
        cout << "Invalid credentials. Access denied." << endl;
    }
    
    return 0;
}
04

The else if Ladder

When you need to check multiple conditions in sequence, use the else if ladder. Only the first matching condition's block will execute.

#include <iostream>
using namespace std;

int main() {
    int score;
    cout << "Enter your score (0-100): ";
    cin >> score;
    
    char grade;
    
    // Grade calculation using else if ladder
    if (score >= 90) {
        grade = 'A';
    } else if (score >= 80) {
        grade = 'B';
    } else if (score >= 70) {
        grade = 'C';
    } else if (score >= 60) {
        grade = 'D';
    } else {
        grade = 'F';
    }
    
    cout << "Your grade: " << grade << endl;
    
    // Additional feedback
    if (grade == 'A' || grade == 'B') {
        cout << "Excellent work!" << endl;
    } else if (grade == 'C' || grade == 'D') {
        cout << "Keep practicing!" << endl;
    } else {
        cout << "Please see your instructor." << endl;
    }
    
    return 0;
}

Order Matters!

#include <iostream>
using namespace std;

int main() {
    int score = 95;
    
    // WRONG order - 95 >= 60 is true, so grade will be D!
    if (score >= 60) {
        cout << "Grade D" << endl;  // This executes first!
    } else if (score >= 70) {
        cout << "Grade C" << endl;
    } else if (score >= 80) {
        cout << "Grade B" << endl;
    } else if (score >= 90) {
        cout << "Grade A" << endl;  // Never reached for 95!
    }
    
    // CORRECT order - check highest thresholds first
    if (score >= 90) {
        cout << "Grade A" << endl;  // This executes for 95
    } else if (score >= 80) {
        cout << "Grade B" << endl;
    } else if (score >= 70) {
        cout << "Grade C" << endl;
    } else if (score >= 60) {
        cout << "Grade D" << endl;
    }
    
    return 0;
}
Pro Tip: When using range checks in else if ladders, always start with the most restrictive condition (highest or lowest threshold) first.
05

The switch Statement

The switch statement is ideal when you need to compare a variable against multiple constant values. It's often cleaner than long else if chains.

#include <iostream>
using namespace std;

int main() {
    int day;
    cout << "Enter day number (1-7): ";
    cin >> day;
    
    switch (day) {
        case 1:
            cout << "Monday" << endl;
            break;
        case 2:
            cout << "Tuesday" << endl;
            break;
        case 3:
            cout << "Wednesday" << endl;
            break;
        case 4:
            cout << "Thursday" << endl;
            break;
        case 5:
            cout << "Friday" << endl;
            break;
        case 6:
            cout << "Saturday" << endl;
            break;
        case 7:
            cout << "Sunday" << endl;
            break;
        default:
            cout << "Invalid day number!" << endl;
    }
    
    return 0;
}

Fall-Through Behavior

#include <iostream>
using namespace std;

int main() {
    int month;
    cout << "Enter month (1-12): ";
    cin >> month;
    
    int days;
    
    switch (month) {
        // Months with 31 days
        case 1: case 3: case 5: case 7:
        case 8: case 10: case 12:
            days = 31;
            break;
        
        // Months with 30 days
        case 4: case 6: case 9: case 11:
            days = 30;
            break;
        
        // February (simplified)
        case 2:
            days = 28;
            break;
        
        default:
            days = 0;
            cout << "Invalid month!" << endl;
    }
    
    if (days > 0) {
        cout << "Days in month: " << days << endl;
    }
    
    return 0;
}

switch with Characters

#include <iostream>
using namespace std;

int main() {
    char operation;
    double num1, num2, result;
    
    cout << "Enter two numbers: ";
    cin >> num1 >> num2;
    cout << "Enter operation (+, -, *, /): ";
    cin >> operation;
    
    switch (operation) {
        case '+':
            result = num1 + num2;
            cout << num1 << " + " << num2 << " = " << result << endl;
            break;
        case '-':
            result = num1 - num2;
            cout << num1 << " - " << num2 << " = " << result << endl;
            break;
        case '*':
            result = num1 * num2;
            cout << num1 << " * " << num2 << " = " << result << endl;
            break;
        case '/':
            if (num2 != 0) {
                result = num1 / num2;
                cout << num1 << " / " << num2 << " = " << result << endl;
            } else {
                cout << "Error: Division by zero!" << endl;
            }
            break;
        default:
            cout << "Invalid operation!" << endl;
    }
    
    return 0;
}
Don't Forget break! Without break, execution "falls through" to the next case. This is sometimes intentional (as shown above), but usually a bug.

switch vs if-else

Aspect switch if-else
Use Case Comparing against discrete values Complex conditions, ranges
Expression Types int, char, enum (integral types) Any boolean expression
Ranges ❌ Cannot check ranges directly ✅ Can check ranges (x > 10)
Readability Better for many discrete values Better for complex logic
Performance Often optimized to jump table Sequential evaluation
06

Nested Conditionals

Nested conditionals are if statements inside other if statements. They allow for more complex decision trees but should be used carefully to maintain readability.

#include <iostream>
using namespace std;

int main() {
    int age;
    bool hasLicense;
    
    cout << "Enter your age: ";
    cin >> age;
    cout << "Do you have a license? (1=yes, 0=no): ";
    cin >> hasLicense;
    
    // Nested conditional
    if (age >= 18) {
        if (hasLicense) {
            cout << "You can drive!" << endl;
        } else {
            cout << "You're old enough, but need a license." << endl;
        }
    } else {
        cout << "You're too young to drive." << endl;
        int yearsLeft = 18 - age;
        cout << "Wait " << yearsLeft << " more year(s)." << endl;
    }
    
    return 0;
}

Flattening Nested Conditionals

#include <iostream>
using namespace std;

int main() {
    int age = 20;
    bool hasLicense = true;
    
    // Deep nesting (harder to read)
    if (age >= 18) {
        if (hasLicense) {
            if (age <= 70) {
                cout << "Can drive" << endl;
            }
        }
    }
    
    // Flattened with combined conditions (better)
    if (age >= 18 && hasLicense && age <= 70) {
        cout << "Can drive" << endl;
    }
    
    // Or using early returns in functions
    // (demonstrated in function context)
    
    return 0;
}

Complex Decision Example

#include <iostream>
#include <string>
using namespace std;

int main() {
    string customerType;
    double purchaseAmount;
    int loyaltyYears;
    
    cout << "Customer type (regular/premium): ";
    cin >> customerType;
    cout << "Purchase amount: $";
    cin >> purchaseAmount;
    cout << "Years as customer: ";
    cin >> loyaltyYears;
    
    double discount = 0;
    
    if (customerType == "premium") {
        if (purchaseAmount >= 100) {
            if (loyaltyYears >= 5) {
                discount = 25;  // Premium + $100+ + 5+ years
            } else {
                discount = 20;  // Premium + $100+
            }
        } else {
            discount = 15;  // Premium base
        }
    } else {  // regular customer
        if (purchaseAmount >= 100) {
            if (loyaltyYears >= 3) {
                discount = 15;  // Regular + $100+ + 3+ years
            } else {
                discount = 10;  // Regular + $100+
            }
        } else if (loyaltyYears >= 5) {
            discount = 5;  // Regular loyal customer
        }
    }
    
    cout << "Your discount: " << discount << "%" << endl;
    double finalPrice = purchaseAmount * (1 - discount / 100);
    cout << "Final price: $" << finalPrice << endl;
    
    return 0;
}
07

Ternary Operator (Conditional Operator)

The ternary operator ?: is a shorthand for simple if-else statements. It's great for assigning values based on a condition in a single line.

#include <iostream>
#include <string>
using namespace std;

int main() {
    // Syntax: condition ? value_if_true : value_if_false
    
    int age = 20;
    
    // Instead of:
    // string status;
    // if (age >= 18) status = "adult";
    // else status = "minor";
    
    // Use ternary:
    string status = (age >= 18) ? "adult" : "minor";
    cout << "Status: " << status << endl;
    
    // Finding maximum
    int a = 10, b = 20;
    int max = (a > b) ? a : b;
    cout << "Max: " << max << endl;
    
    // Absolute value
    int num = -5;
    int absVal = (num >= 0) ? num : -num;
    cout << "Absolute value: " << absVal << endl;
    
    // In output directly
    int score = 75;
    cout << "Result: " << ((score >= 60) ? "Pass" : "Fail") << endl;
    
    // Nested ternary (use sparingly!)
    int x = 15;
    string size = (x < 10) ? "small" : 
                  (x < 20) ? "medium" : "large";
    cout << "Size: " << size << endl;
    
    return 0;
}
When to Use: Use ternary for simple, one-line conditional assignments. For complex logic, stick with if-else for better readability.
08

Best Practices

Writing clean, maintainable conditional code is essential. Here are key practices to follow.

1. Always Use Braces

// AVOID: No braces (error-prone)
if (condition)
    doSomething();
    doSomethingElse();  // This ALWAYS executes!

// BETTER: Always use braces
if (condition) {
    doSomething();
    doSomethingElse();
}

2. Use Early Returns

// AVOID: Deep nesting
void processOrder(Order order) {
    if (order.isValid()) {
        if (order.hasStock()) {
            if (order.paymentProcessed()) {
                // Ship order
                ship(order);
            }
        }
    }
}

// BETTER: Early returns (guard clauses)
void processOrder(Order order) {
    if (!order.isValid()) return;
    if (!order.hasStock()) return;
    if (!order.paymentProcessed()) return;
    
    // Ship order
    ship(order);
}

3. Prefer Positive Conditions

// AVOID: Negative conditions
if (!isNotLoggedIn) {
    // confusing!
}

// BETTER: Positive conditions
if (isLoggedIn) {
    // clear and readable
}

4. Avoid Magic Numbers

// AVOID: Magic numbers
if (score >= 90) {
    grade = 'A';
}

// BETTER: Named constants
const int A_THRESHOLD = 90;
const int B_THRESHOLD = 80;

if (score >= A_THRESHOLD) {
    grade = 'A';
} else if (score >= B_THRESHOLD) {
    grade = 'B';
}

5. Use switch for Multiple Values

// AVOID: Long if-else for value matching
if (day == 1) {
    name = "Monday";
} else if (day == 2) {
    name = "Tuesday";
} else if (day == 3) {
    // ... and so on
}

// BETTER: switch statement
switch (day) {
    case 1: name = "Monday"; break;
    case 2: name = "Tuesday"; break;
    case 3: name = "Wednesday"; break;
    // ...
}

6. Keep Conditions Simple

// AVOID: Complex inline condition
if (age >= 18 && age <= 65 && hasLicense && !isSuspended && 
    (carType == "standard" || (carType == "commercial" && hasCommercialLicense))) {
    // hard to read!
}

// BETTER: Extract to meaningful functions or variables
bool isEligibleAge = (age >= 18 && age <= 65);
bool hasValidLicense = hasLicense && !isSuspended;
bool canDriveCarType = (carType == "standard") || 
                       (carType == "commercial" && hasCommercialLicense);

if (isEligibleAge && hasValidLicense && canDriveCarType) {
    // clear intent!
}

Key Takeaways

if Statement

Execute code only when condition is true

if-else

Two-way branching for true/false paths

else if Ladder

Check multiple conditions in sequence

switch Statement

Multi-way branch for discrete values

Ternary Operator

Shorthand for simple if-else assignments

Best Practices

Use braces, early returns, clear conditions

Knowledge Check

Quick Quiz

Test what you have learned about C++ conditionals

1 What is the output if x = 5?
if (x > 10)
    cout << "A";
else if (x > 3)
    cout << "B";
else
    cout << "C";
2 What happens if you forget break in a switch case?
3 What is the value of result?
int x = 7;
int result = (x % 2 == 0) ? 100 : 200;
4 Which data types can be used in a switch statement?
5 What's wrong with this code?
int x = 5;
if (x = 10) {
    cout << "Ten!";
}
6 When is else if preferred over switch?
Answer all questions to check your score