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.