Skip to content

C++ Decision Statements

Overview

Decision statements (also known as conditional statements or branching statements) allow programs to execute different code paths based on different conditions. C++ provides various decision statements, including if statements, switch statements, etc. Mastering decision statements is the foundation for writing logically clear programs.

🔀 if Statements

Basic if Statements

cpp
#include <iostream>

int main() {
    int score = 85;
    
    std::cout << "=== Basic if Statements ===" << std::endl;
    
    // Single if statement
    if (score >= 60) {
        std::cout << "Congratulations! You passed!" << std::endl;
    }
    
    // Can omit braces (not recommended)
    if (score >= 90)
        std::cout << "Excellent score!" << std::endl;
    
    // Always recommend using braces
    if (score >= 80) {
        std::cout << "Good score!" << std::endl;
    }
    
    return 0;
}

if-else Statements

cpp
#include <iostream>

int main() {
    int temperature = 25;
    
    std::cout << "=== if-else Statements ===" << std::endl;
    
    if (temperature > 30) {
        std::cout << "It's hot, recommend turning on the AC." << std::endl;
    } else {
        std::cout << "The weather is still cool." << std::endl;
    }
    
    // Age check
    int age = 20;
    if (age >= 18) {
        std::cout << "You are an adult." << std::endl;
    } else {
        std::cout << "You are a minor." << std::endl;
    }
    
    // Even-odd number check
    int number = 7;
    if (number % 2 == 0) {
        std::cout << number << " is an even number." << std::endl;
    } else {
        std::cout << number << " is an odd number." << std::endl;
    }
    
    return 0;
}

if-else if-else Statements

cpp
#include <iostream>

int main() {
    int score = 78;
    
    std::cout << "=== if-else if-else Statements ===" << std::endl;
    
    // Grade determination
    if (score >= 90) {
        std::cout << "Grade: A (Excellent)" << std::endl;
    } else if (score >= 80) {
        std::cout << "Grade: B (Good)" << std::endl;
    } else if (score >= 70) {
        std::cout << "Grade: C (Medium)" << std::endl;
    } else if (score >= 60) {
        std::cout << "Grade: D (Pass)" << std::endl;
    } else {
        std::cout << "Grade: F (Fail)" << std::endl;
    }
    
    // Season check
    int month = 8;
    std::cout << "\nSeason check:" << std::endl;
    if (month >= 3 && month <= 5) {
        std::cout << "Spring" << std::endl;
    } else if (month >= 6 && month <= 8) {
        std::cout << "Summer" << std::endl;
    } else if (month >= 9 && month <= 11) {
        std::cout << "Autumn" << std::endl;
    } else if (month == 12 || month == 1 || month == 2) {
        std::cout << "Winter" << std::endl;
    } else {
        std::cout << "Invalid month" << std::endl;
    }
    
    return 0;
}

Nested if Statements

cpp
#include <iostream>

int main() {
    int age = 25;
    bool hasLicense = true;
    bool hasExperience = false;
    
    std::cout << "=== Nested if Statements ===" << std::endl;
    
    // Driver qualification check
    if (age >= 18) {
        std::cout << "Age requirements met." << std::endl;
        
        if (hasLicense) {
            std::cout << "Has driver's license." << std::endl;
            
            if (hasExperience) {
                std::cout << "Can drive independently." << std::endl;
            } else {
                std::cout << "Recommend having an experienced driver accompany." << std::endl;
            }
        } else {
            std::cout << "Need to obtain driver's license first." << std::endl;
        }
    } else {
        std::cout << "Age does not meet driving requirements." << std::endl;
    }
    
    // User permission check
    bool isLoggedIn = true;
    bool isAdmin = false;
    bool isOwner = true;
    
    std::cout << "\nPermission check:" << std::endl;
    if (isLoggedIn) {
        if (isAdmin) {
            std::cout << "Admin permission: Can perform all operations." << std::endl;
        } else if (isOwner) {
            std::cout << "Owner permission: Can edit own content." << std::endl;
        } else {
            std::cout << "Regular user permission: Can only view content." << std::endl;
        }
    } else {
        std::cout << "Please log in first." << std::endl;
    }
    
    return 0;
}

🔄 switch Statements

Basic switch Statements

cpp
#include <iostream>

int main() {
    int day = 3;
    
    std::cout << "=== Basic switch Statements ===" << std::endl;
    
    switch (day) {
        case 1:
            std::cout << "Monday" << std::endl;
            break;
        case 2:
            std::cout << "Tuesday" << std::endl;
            break;
        case 3:
            std::cout << "Wednesday" << std::endl;
            break;
        case 4:
            std::cout << "Thursday" << std::endl;
            break;
        case 5:
            std::cout << "Friday" << std::endl;
            break;
        case 6:
            std::cout << "Saturday" << std::endl;
            break;
        case 7:
            std::cout << "Sunday" << std::endl;
            break;
        default:
            std::cout << "Invalid day" << std::endl;
            break;
    }
    
    return 0;
}

switch Statement Fall-Through Behavior

cpp
#include <iostream>

int main() {
    char grade = 'B';
    
    std::cout << "=== switch Statement Fall-Through ===" << std::endl;
    
    // Intentionally omitted break
    switch (grade) {
        case 'A':
        case 'a':
            std::cout << "Excellent score!" << std::endl;
            break;
        case 'B':
        case 'b':
            std::cout << "Good score!" << std::endl;
            break;
        case 'C':
        case 'c':
            std::cout << "Average score." << std::endl;
            break;
        case 'D':
        case 'd':
            std::cout << "Passing score." << std::endl;
            break;
        case 'F':
        case 'f':
            std::cout << "Failing score." << std::endl;
            break;
        default:
            std::cout << "Invalid grade." << std::endl;
            break;
    }
    
    // Intentional fall-through
    int month = 4;
    std::cout << "\nMonth days:" << std::endl;
    switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            std::cout << "31 days" << std::endl;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            std::cout << "30 days" << std::endl;
            break;
        case 2:
            std::cout << "28 days or 29 days" << std::endl;
            break;
        default:
            std::cout << "Invalid month" << std::endl;
            break;
    }
    
    return 0;
}

switch Statement Advanced Usage

cpp
#include <iostream>

enum class Operation {
    ADD,
    SUBTRACT,
    MULTIPLY,
    DIVIDE
};

double calculate(double a, double b, Operation op) {
    switch (op) {
        case Operation::ADD:
            return a + b;
        case Operation::SUBTRACT:
            return a - b;
        case Operation::MULTIPLY:
            return a * b;
        case Operation::DIVIDE:
            if (b != 0) {
                return a / b;
            } else {
                std::cout << "Error: Divider cannot be zero!" << std::endl;
                return 0;
            }
        default:
            std::cout << "Unknown operation" << std::endl;
            return 0;
    }
}

int main() {
    std::cout << "=== switch Statement Advanced Usage ===" << std::endl;
    
    double x = 10.5, y = 3.2;
    
    std::cout << "x = " << x << ", y = " << y << std::endl;
    std::cout << "Addition: " << calculate(x, y, Operation::ADD) << std::endl;
    std::cout << "Subtraction: " << calculate(x, y, Operation::SUBTRACT) << std::endl;
    std::cout << "Multiplication: " << calculate(x, y, Operation::MULTIPLY) << std::endl;
    std::cout << "Division: " << calculate(x, y, Operation::DIVIDE) << std::endl;
    
    // Character-based switch
    char operation = '+';
    std::cout << "\nCharacter operator processing:" << std::endl;
    switch (operation) {
        case '+':
            std::cout << "Perform addition operation" << std::endl;
            break;
        case '-':
            std::cout << "Perform subtraction operation" << std::endl;
            break;
        case '*':
            std::cout << "Perform multiplication operation" << std::endl;
            break;
        case '/':
            std::cout << "Perform division operation" << std::endl;
            break;
        default:
            std::cout << "Unknown operator" << std::endl;
            break;
    }
    
    return 0;
}

🆕 C++17 if Statement Initializers

if Statement Initializers

cpp
#include <iostream>
#include <map>
#include <string>

int main() {
    std::cout << "=== C++17 if Statement Initializers ===" << std::endl;
    
    std::map<std::string, int> scores = {
        {"Alice", 95},
        {"Bob", 87},
        {"Charlie", 92}
    };
    
    // C++17 if statement initializer
    if (auto it = scores.find("Alice"); it != scores.end()) {
        std::cout << "Found Alice's score: " << it->second << std::endl;
        // it is only accessible within this if statement scope
    } else {
        std::cout << "Did not find Alice" << std::endl;
        // it is also accessible in else block, but value is end()
    }
    // it is not accessible here
    
    // Traditional approach comparison
    auto it = scores.find("Bob");  // it scope is too large
    if (it != scores.end()) {
        std::cout << "Found Bob's score: " << it->second << std::endl;
    }
    // it is still accessible, might lead to accidental use
    
    // switch statement initializer
    if (auto value = 42; value > 30) {
        std::cout << "Value is greater than 30: " << value << std::endl;
    }
    
    return 0;
}

🎯 Conditional Operators (Ternary Operators)

Conditional Operator Usage

cpp
#include <iostream>
#include <string>

int main() {
    std::cout << "=== Conditional Operators ===" << std::endl;
    
    int a = 10, b = 20;
    
    // Basic usage: condition ? value_if_true : value_if_false
    int max_value = (a > b) ? a : b;
    std::cout << "max(" << a << ", " << b << ") = " << max_value << std::endl;
    
    // String selection
    int score = 75;
    std::string result = (score >= 60) ? "Passed" : "Failed";
    std::cout << score << " points: " << result << std::endl;
    
    // Nested conditional operators
    int x = 15, y = 10, z = 25;
    int max_three = (x > y) ? ((x > z) ? x : z) : ((y > z) ? y : z));
    std::cout << "Max of three numbers: " << max_three << std::endl;
    
    // Clearer approach
    auto findMax = [](int a, int b, int c) {
        if (a >= b && a >= c) return a;
        if (b >= c) return b;
        return c;
    };
    std::cout << "Max using lambda: " << findMax(x, y, z) << std::endl;
    
    // Conditional operator in output
    int number = 7;
    std::cout << number << " is " << ((number % 2 == 0) ? "even" : "odd") << std::endl;
    
    // Function pointer selection
    auto add = [](int a, int b) { return a + b; };
    auto multiply = [](int a, int b) { return a * b; };
    
    bool useAddition = true;
    auto operation = useAddition ? add : multiply;
    std::cout << "Selected operation result: " << operation(5, 3) << std::endl;
    
    return 0;
}

🔒 Logical Expressions and Short-Circuit Evaluation

Complex Condition Checks

cpp
#include <iostream>
#include <string>

bool isValidEmail(const std::string& email) {
    return !email.empty() && 
           email.find('@') != std::string::npos && 
           email.find('.') != std::string::npos;
}

bool isValidAge(int age) {
    return age >= 0 && age <= 150;
}

bool isValidUser(const std::string& name, const std::string& email, int age) {
    return !name.empty() && isValidEmail(email) && isValidAge(age);
}

int main() {
    std::cout << "=== Complex Condition Checks ===" << std::endl;
    std::cout << std::boolalpha;
    
    // User validation
    std::string name = "Alice";
    std::string email = "alice@example.com";
    int age = 25;
    
    if (isValidUser(name, email, age)) {
        std::cout << "User information is valid" << std::endl;
    } else {
        std::cout << "User information is invalid, please check:" << std::endl;
        if (name.empty()) {
            std::cout << "- Name cannot be empty" << std::endl;
        }
        if (!isValidEmail(email)) {
            std::cout << "- Email format is incorrect" << std::endl;
        }
        if (!isValidAge(age)) {
            std::cout << "- Age is not in valid range" << std::endl;
        }
    }
    
    // Short-circuit evaluation demonstration
    std::cout << "\n=== Short-Circuit Evaluation Demo ===" << std::endl;
    
    int value = 0;
    
    // && short-circuit: subsequent conditions are not evaluated if first condition is false
    if (value != 0 && 100 / value > 10) {
        std::cout << "This will not be executed" << std::endl;
    } else {
        std::cout << "Avoided division by zero error" << std::endl;
    }
    
    // || short-circuit: subsequent conditions are not evaluated if first condition is true
    bool isAdmin = true;
    if (isAdmin || expensiveCheck()) {  // expensiveCheck() will not be called
        std::cout << "Permission check passed" << std::endl;
    }
    
    return 0;
}

bool expensiveCheck() {
    std::cout << "Executing expensive check" << std::endl;  // This will not be printed
    return false;
}

🎨 Decision Statement Best Practices

Code Style and Readability

cpp
#include <iostream>
#include <string>

// Good practices
namespace GoodPractice {
    void processScore(int score) {
        // Use clear conditions and early returns
        if (score < 0 || score > 100) {
            std::cout << "Invalid score" << std::endl;
            return;
        }
        
        if (score >= 90) {
            std::cout << "Excellent (A)" << std::endl;
        } else if (score >= 80) {
            std::cout << "Good (B)" << std::endl;
        } else if (score >= 70) {
            std::cout << "Medium (C)" << std::endl;
        } else if (score >= 60) {
            std::cout << "Passing (D)" << std::endl;
        } else {
            std::cout << "Failing (F)" << std::endl;
        }
    }
    
    // Use enums to improve readability
    enum class UserType { GUEST, USER, ADMIN };
    
    void checkPermission(UserType type) {
        switch (type) {
            case UserType::ADMIN:
                std::cout << "Admin: All permissions" << std::endl;
                break;
            case UserType::USER:
                std::cout << "User: Basic permissions" << std::endl;
                break;
            case UserType::GUEST:
                std::cout << "Guest: Read-only permissions" << std::endl;
                break;
        }
    }
}

// Avoid these practices
namespace BadPractice {
    void processScore(int score) {
        // Avoid: Excessive nesting
        if (score >= 0) {
            if (score <= 100) {
                if (score >= 90) {
                    std::cout << "Excellent" << std::endl;
                } else {
                    if (score >= 80) {
                        std::cout << "Good" << std::endl;
                    } else {
                        // More nesting...
                    }
                }
            }
        }
    }
    
    // Avoid: Magic numbers
    void checkAccess(int userLevel) {
        if (userLevel == 3) {  // What does 3 represent?
            // ...
        }
    }
}

int main() {
    std::cout << "=== Decision Statement Best Practices ===" << std::endl;
    
    // Good practice examples
    GoodPractice::processScore(85);
    GoodPractice::checkPermission(GoodPractice::UserType::ADMIN);
    
    // Use constants to improve readability
    const int PASSING_SCORE = 60;
    const int EXCELLENT_SCORE = 90;
    
    int studentScore = 75;
    if (studentScore >= EXCELLENT_SCORE) {
        std::cout << "Excellent student!" << std::endl;
    } else if (studentScore >= PASSING_SCORE) {
        std::cout << "Passing student." << std::endl;
    } else {
        std::cout << "Needs retake." << std::endl;
    }
    
    // Use functions to improve readability
    auto isWeekend = [](int day) {
        return day == 6 || day == 7;  // Saturday or Sunday
    };
    
    int today = 6;
    if (isWeekend(today)) {
        std::cout << "Today is weekend!" << std::endl;
    } else {
        std::cout << "Today is weekday." << std::endl;
    }
    
    return 0;
}

Common Pitfalls and Solutions

cpp
#include <iostream>

int main() {
    std::cout << "=== Common Pitfalls and Solutions ===" << std::endl;
    
    // Pitfall 1: Assignment vs Comparison
    int x = 5;
    // if (x = 10) {  // Error! This is assignment, not comparison
    if (x == 10) {    // Correct: Comparison
        std::cout << "x equals 10" << std::endl;
    }
    
    // Pitfall 2: Floating-point comparison
    double a = 0.1 + 0.2;
    double b = 0.3;
    // if (a == b) {  // May be false!
    const double EPSILON = 1e-9;
    if (std::abs(a - b) < EPSILON) {
        std::cout << "Floating-point numbers equal (using epsilon range)" << std::endl;
    }
    
    // Pitfall 3: Forgot break statement
    int day = 2;
    switch (day) {
        case 1:
            std::cout << "Monday" << std::endl;
            // Forgot break, will continue to next case
        case 2:
            std::cout << "Tuesday" << std::endl;
            break;  // Remember to add break
        default:
            std::cout << "Other" << std::endl;
            break;
    }
    
    // Pitfall 4: Empty statement
    if (x > 0); {  // Note the semicolon! Creates an empty if statement
        std::cout << "This will always execute" << std::endl;
    }
    
    // Correct approach
    if (x > 0) {
        std::cout << "x is positive" << std::endl;
    }
    
    return 0;
}

Summary

C++ decision statements are core tools for program logic control:

Main Decision Statement Types

  • if statements: Basic conditional checks, support single, double, and multiple branches
  • switch statements: Multiple value matching, suitable for discrete value checks
  • Conditional operators: Concise ternary expressions, suitable for simple conditional assignments

Key Features

  • Short-circuit evaluation: Optimization feature of logical operators
  • Scope control: C++17 if initializers
  • Type safety: Enum types improve code readability
  • Fall-through: switch statement fall-through behavior

Best Practices

  • Use braces to enhance readability
  • Avoid excessive nesting, use early returns
  • Use meaningful constants instead of magic numbers
  • Pay attention to floating-point comparison specifics
  • Use enums reasonably to improve code quality

Mastering the correct use of decision statements is an important foundation for writing logically clear and maintainable C++ programs.

Content is for learning and research only.