C++ 中的条件语句用于根据特定条件执行不同的代码路径。条件语句是程序控制流的核心组成部分。

if 语句

基本 if 语句

int x = 10;
 
// 简单 if
if (x > 5) {
    std::cout << "x is greater than 5" << std::endl;
}
 
// 单行语句可以省略花括号(不推荐)
if (x > 5)
    std::cout << "x is greater than 5" << std::endl;
 
// 条件为假时不执行
if (x < 0) {
    std::cout << "This won't print" << std::endl;
}

if-else 语句

int age = 18;
 
if (age >= 18) {
    std::cout << "Adult" << std::endl;
} else {
    std::cout << "Minor" << std::endl;
}
 
// 嵌套 if-else
int score = 85;
 
if (score >= 90) {
    std::cout << "Grade: A" << std::endl;
} else if (score >= 80) {
    std::cout << "Grade: B" << std::endl;
} else if (score >= 70) {
    std::cout << "Grade: C" << std::endl;
} else if (score >= 60) {
    std::cout << "Grade: D" << std::endl;
} else {
    std::cout << "Grade: F" << std::endl;
}

if 语句的初始化(C++17)

// C++17 允许在 if 语句中进行初始化
if (int value = getValue(); value > 0) {
    std::cout << "Positive value: " << value << std::endl;
} else {
    std::cout << "Non-positive value: " << value << std::endl;
}
// value 的作用域仅限于 if-else 块
 
// 实用示例:检查 map 查找
std::map<std::string, int> scores = {{"Alice", 90}, {"Bob", 85}};
 
if (auto it = scores.find("Alice"); it != scores.end()) {
    std::cout << "Alice's score: " << it->second << std::endl;
} else {
    std::cout << "Alice not found" << std::endl;
}
 
// 与智能指针结合
if (auto ptr = std::make_unique<int>(42); ptr != nullptr) {
    std::cout << "Value: " << *ptr << std::endl;
}

constexpr if(C++17)

编译时条件判断,允许根据编译时常量条件选择性编译代码:

template<typename T>
void processValue(T value) {
    if constexpr (std::is_integral_v<T>) {
        std::cout << "Integer: " << value << std::endl;
    } else if constexpr (std::is_floating_point_v<T>) {
        std::cout << "Float: " << std::fixed << value << std::endl;
    } else {
        std::cout << "Other type" << std::endl;
    }
}
 
// 使用
processValue(42);        // 编译时选择整数分支
processValue(3.14);      // 编译时选择浮点数分支
processValue("hello");   // 编译时选择其他类型分支

switch 语句

基本 switch 语句

int day = 3;
 
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:
    case 7:  // fall-through: 6 和 7 执行相同的代码
        std::cout << "Weekend" << std::endl;
        break;
    default:
        std::cout << "Invalid day" << std::endl;
        break;
}

switch 的 fall-through 特性

int grade = 'B';
 
switch (grade) {
    case 'A':
        std::cout << "Excellent! ";
        [[fallthrough]];  // C++17 属性,明确表示故意 fall-through
    case 'B':
        std::cout << "Good job! ";
        [[fallthrough]];
    case 'C':
        std::cout << "Pass" << std::endl;
        break;
    default:
        std::cout << "Need improvement" << std::endl;
}
// 输入 'B' 输出: "Good job! Pass"

switch 语句的初始化(C++17)

switch (int code = getErrorCode(); code) {
    case 0:
        std::cout << "Success" << std::endl;
        break;
    case 1:
        std::cout << "Error: " << code << std::endl;
        break;
    default:
        std::cout << "Unknown error: " << code << std::endl;
}

switch 与枚举

enum class Color { RED, GREEN, BLUE };
 
Color color = Color::GREEN;
 
switch (color) {
    case Color::RED:
        std::cout << "Red" << std::endl;
        break;
    case Color::GREEN:
        std::cout << "Green" << std::endl;
        break;
    case Color::BLUE:
        std::cout << "Blue" << std::endl;
        break;
    // 编译器可能警告没有处理所有枚举值
}

条件运算符(三元运算符)

// 基本语法: condition ? true_value : false_value
int a = 10, b = 20;
int max = (a > b) ? a : b;
 
// 可以嵌套(但降低可读性)
int x = 5;
std::string result = (x > 10) ? "greater than 10" :
                     (x > 0)  ? "positive" :
                     (x == 0) ? "zero" : "negative";
 
// 在初始化中使用
const int value = (condition) ? 100 : 200;
 
// 返回不同类型(需要有共同类型)
auto result = (condition) ? 42 : 3.14;  // result 类型为 double

条件语句的高级用法

短路求值

// && 和 || 具有短路特性
bool expensiveCheck();
bool quickCheck();
 
// 如果 quickCheck() 返回 false,expensiveCheck() 不会被调用
if (quickCheck() && expensiveCheck()) {
    // 两个条件都为真
}
 
// 安全的指针检查
MyClass* ptr = getPointer();
if (ptr != nullptr && ptr->isValid()) {
    ptr->doSomething();
}
 
// 使用短路特性进行条件执行
bool flag = true;
flag && (std::cout << "This will print" << std::endl);
flag || (std::cout << "This won't print" << std::endl);

条件链

// 使用逻辑运算符创建复杂条件
int age = 25;
bool hasLicense = true;
bool isInsured = true;
 
if (age >= 18 && age <= 70 && hasLicense && isInsured) {
    std::cout << "Can rent a car" << std::endl;
}
 
// 使用括号明确优先级
if ((age >= 18 && hasLicense) || (age >= 16 && hasParentalConsent)) {
    std::cout << "Can drive" << std::endl;
}

使用 optional 和条件语句(C++17)

std::optional<int> getValue();
 
if (auto value = getValue(); value.has_value()) {
    std::cout << "Got value: " << value.value() << std::endl;
} else {
    std::cout << "No value" << std::endl;
}
 
// 或者更简洁
if (auto value = getValue()) {
    std::cout << "Got value: " << *value << std::endl;
}

条件语句的最佳实践

1. 避免深层嵌套

// 不好的做法
if (condition1) {
    if (condition2) {
        if (condition3) {
            // 深层嵌套难以阅读
        }
    }
}
 
// 更好的做法:提前返回
if (!condition1) return;
if (!condition2) return;
if (!condition3) return;
// 执行主要逻辑

2. 使用有意义的条件

// 不好的做法
if (x > 0 && x < 100 && y > 0 && y < 100) { }
 
// 更好的做法
bool isInBounds = (x > 0 && x < 100 && y > 0 && y < 100);
if (isInBounds) { }
 
// 或者创建函数
bool isValidCoordinate(int x, int y) {
    return x > 0 && x < 100 && y > 0 && y < 100;
}
if (isValidCoordinate(x, y)) { }

3. 始终使用花括号

// 容易出错
if (condition)
    doSomething();
    doAnotherThing();  // 这行总是执行!
 
// 更安全
if (condition) {
    doSomething();
    doAnotherThing();
}

4. 合理使用 switch

// 当有多个离散值时,switch 比 if-else 链更清晰
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;
            throw std::invalid_argument("Division by zero");
    }
    throw std::invalid_argument("Unknown operation");
}

模式匹配风格的条件处理

虽然 C++ 还没有真正的模式匹配,但可以使用一些技巧:

// 使用 std::variant 和 std::visit(C++17)
#include <variant>
 
using Value = std::variant<int, double, std::string>;
 
void processValue(const Value& v) {
    std::visit([](const auto& value) {
        using T = std::decay_t<decltype(value)>;
        if constexpr (std::is_same_v<T, int>) {
            std::cout << "Integer: " << value << std::endl;
        } else if constexpr (std::is_same_v<T, double>) {
            std::cout << "Double: " << value << std::endl;
        } else if constexpr (std::is_same_v<T, std::string>) {
            std::cout << "String: " << value << std::endl;
        }
    }, v);
}

条件编译

#ifdef DEBUG
    if (verbose) {
        std::cout << "Debug info: " << debugMessage << std::endl;
    }
#endif
 
// 编译时常量条件
if constexpr (sizeof(void*) == 8) {
    std::cout << "64-bit system" << std::endl;
} else {
    std::cout << "32-bit system" << std::endl;
}

条件语句是程序控制流的基础,合理使用可以让代码逻辑清晰、易于维护。选择合适的条件语句形式(if、switch、条件运算符)取决于具体的使用场景。现代 C++ 提供的特性如 if 初始化、constexpr if 等,可以让条件语句更加强大和灵活。