Skip to content

Ch 9: 条件控制流

  • 熟练使用 if/else 条件语句
  • 掌握 switch 语句的用法
  • 理解 C++20 的初始化语句语法
  • 学会选择合适的条件结构
# Python - 用缩进表示块
score = 85
if score >= 90:
grade = "A"
print("Excellent!")
elif score >= 80:
grade = "B"
print("Good!")
elif score >= 60:
grade = "C"
print("Passed")
else:
grade = "F"
print("Failed")
// C++ - 用 {} 表示块
int score = 85;
std::string grade;
if (score >= 90) {
grade = "A";
std::cout << "Excellent!" << std::endl;
} else if (score >= 80) {
grade = "B";
std::cout << "Good!" << std::endl;
} else if (score >= 60) {
grade = "C";
std::cout << "Passed" << std::endl;
} else {
grade = "F";
std::cout << "Failed" << std::endl;
}
// 单行 if 可以省略 {}(不推荐)
if (score >= 60)
grade = "Pass";
else
grade = "Fail";
// Python 三元表达式
// Python: result = "Pass" if score >= 60 else "Fail"
// C++ 三元运算符
std::string result = (score >= 60) ? "Pass" : "Fail";
// 基本用法
int a = 10, b = 20;
int max = (a > b) ? a : b; // 20
// 嵌套(不推荐,难读)
int grade = (score >= 90) ? 5
: (score >= 80) ? 4
: (score >= 70) ? 3
: (score >= 60) ? 2
: 1;
// 推荐:用 if-else 链代替嵌套三元
# Python - 可以在 if 中直接赋值
result = get_data()
if result:
process(result)
// C++20 - 初始化语句
if (auto opt = find_item(); opt.has_value()) {
// opt 在这个作用域内可用
process(opt.value());
}
// 传统方式 - opt 在外层作用域
auto opt = find_item();
if (opt.has_value()) {
process(opt.value());
}
#include <unordered_map>
#include <optional>
// 应用 1: map find
std::unordered_map<std::string, int> ages = {{"Alice", 30}};
if (auto it = ages.find("Alice"); it != ages.end()) {
std::cout << "Found: " << it->second << std::endl;
} else {
// it 不在这个作用域
std::cout << "Not found" << std::endl;
}
// 应用 2: optional 处理
std::optional<int> find_score(const std::string& name) {
if (name == "Alice") return 95;
return std::nullopt;
}
if (auto score = find_score("Alice"); score.has_value()) {
std::cout << "Score: " << *score << std::endl;
}
// 应用 3: 资源获取 + 检查
if (auto file = open_file("data.txt"); file.is_open()) {
process(file);
} else {
std::cerr << "Failed to open file" << std::endl;
}
# Python 3.10+
command = "start"
match command:
case "start":
print("Starting...")
case "stop":
print("Stopping...")
case _:
print("Unknown command")
// C++ - switch 语句
std::string command = "start";
switch (command) {
case "start": // 编译错误!C++ 中 case 必须是整数常量!
std::cout << "Starting..." << std::endl;
break;
case "stop":
std::cout << "Stopping..." << std::endl;
break;
default:
std::cout << "Unknown command" << std::endl;
break;
}

重要: C++ switch 的 case 必须是整数常量表达式,不能是字符串!

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;
default:
std::cout << "Weekend" << std::endl;
break;
}
// 使用枚举类使 switch 更清晰
enum class State { IDLE, RUNNING, PAUSED, STOPPED };
State state = get_state();
switch (state) {
case State::IDLE:
std::cout << "Idle" << std::endl;
break;
case State::RUNNING:
std::cout << "Running" << std::endl;
break;
case State::PAUSED:
std::cout << "Paused" << std::endl;
break;
case State::STOPPED:
std::cout << "Stopped" << std::endl;
break;
}
// C++ 允许 fall-through(有意为之时)
switch (grade) {
case 'A':
case 'B':
case 'C':
std::cout << "Pass" << std::endl; // A/B/C 都执行这个
break;
case 'D':
case 'F':
std::cout << "Fail" << std::endl;
break;
}
// 显式标注 fall-through
switch (grade) {
case 'A':
std::cout << "Excellent" << std::endl;
[[fallthrough]]; // 显式说明是故意的
case 'B':
std::cout << "Good" << std::endl;
break;
}
// C++20 - switch 带初始化
switch (int result = process(); result) {
case 0:
std::cout << "Success" << std::endl;
break;
case -1:
std::cout << "Error: Not found" << std::endl;
break;
case -2:
std::cout << "Error: Permission denied" << std::endl;
break;
default:
std::cout << "Unknown error: " << result << std::endl;
break;
}
# and/or 短路求值
result = data and data.get("value") or "default"
# 链式比较
if 60 <= score < 90: # Python 特有
print("Pass")
// && 短路求值
if (ptr != nullptr && ptr->value > 0) {
// ptr != nullptr 为 false 时,不执行 ptr->value > 0
}
// || 短路求值
int* ptr = get_pointer();
int value = (ptr != nullptr) ? *ptr : 0;
// 链式比较 - C++ 不支持!需要分开写
int score = 75;
if (score >= 60 && score < 90) {
std::cout << "Pass" << std::endl;
}
#include <iostream>
#include <string>
#include <optional>
// 模拟解析函数
std::optional<int> parse_int(const std::string& s) {
try {
return std::stoi(s);
} catch (...) {
return std::nullopt;
}
}
// 判断分类
enum class Category { SMALL, MEDIUM, LARGE, HUGE };
Category classify(int value) {
if (value < 0) {
throw std::invalid_argument("Negative not allowed");
}
if (value < 10) return Category::SMALL;
if (value < 100) return Category::MEDIUM;
if (value < 1000) return Category::LARGE;
return Category::HUGE;
}
int main(int argc, char* argv[]) {
// 检查参数
if (argc != 2) {
std::cerr << "用法: " << argv[0] << " <数字>" << std::endl;
return 1;
}
// C++20 初始化 if
if (auto opt = parse_int(argv[1]); opt.has_value()) {
int num = *opt;
// if-else 链
if (num > 0) {
std::cout << "正数" << std::endl;
} else if (num < 0) {
std::cout << "负数" << std::endl;
} else {
std::cout << "零" << std::endl;
}
// switch 用枚举
switch (classify(num)) {
case Category::SMALL:
std::cout << "小数字" << std::endl;
break;
case Category::MEDIUM:
std::cout << "中等数字" << std::endl;
break;
case Category::LARGE:
std::cout << "大数字" << std::endl;
break;
case Category::HUGE:
std::cout << "巨大数字" << std::endl;
break;
}
// 三元运算符
std::string parity = (num % 2 == 0) ? "偶数" : "奇数";
std::cout << parity << std::endl;
} else {
std::cerr << "无效数字: " << argv[1] << std::endl;
return 1;
}
return 0;
}
// ✅ 推荐:始终使用 {} 即使是单行
if (ptr != nullptr) {
process(ptr);
}
// ✅ 推荐:使用枚举替代魔法数字
enum class State { IDLE, RUNNING, PAUSED, STOPPED };
State state = get_state();
switch (state) {
case State::IDLE: /* ... */ break;
case State::RUNNING: /* ... */ break;
case State::PAUSED: /* ... */ break;
case State::STOPPED: /* ... */ break;
}
// ✅ 推荐:switch 始终有 default
switch (type) {
case TYPE_A: /* ... */ break;
case TYPE_B: /* ... */ break;
default:
throw std::runtime_error("Unknown type");
}
// ✅ 推荐:使用 std::optional 而非 sentinel 值
std::optional<int> find(const std::vector<int>& v, int target) {
for (auto x : v) {
if (x == target) return x;
}
return std::nullopt;
}
// ❌ 避免:隐式 fall-through(不用 [[fallthrough]])
  • if/else 用 {} 表示块,单行可省略但推荐用 {}
  • C++20 支持 if (init; condition) 初始化语法
  • switch 的 case 必须是整数常量,不能是字符串
  • switch 要加 break,或用 [[fallthrough]] 显式标注
  • 用枚举类 enum class 替代魔法数字
  • 条件表达式用 &&/|| 短路求值

下章预告:ch10 学习循环语句,包括传统 for、while 和 C++20 范围 for。