C++17 if 与 switch 初始化语句

2026年7月12日 Crystal-Sky 7 min read C++C++17基础语法ifswitch

学习目标

完成本节学习后,应能够:

  1. 理解 C++17 中选择语句初始化器的作用;
  2. 掌握 if 初始化语句的基本语法;
  3. 掌握 switch 初始化语句的基本语法;
  4. 理解初始化变量的作用域;
  5. 在查找、加锁、解析返回值等场景中正确使用该语法;
  6. 避免常见的作用域和语法错误。

什么是选择语句初始化器

在 C++17 之前,程序员通常需要先定义变量,再在 ifswitch 中使用它。

例如:

auto it = mp.find("apple");

if (it != mp.end()) {
    std::cout << it->second << '\n';
}

这里的变量 it 在整个外层作用域中都存在,即使它只在判断语句中使用。

C++17 允许在 ifswitch 的条件前直接写一条初始化语句:

if (auto it = mp.find("apple"); it != mp.end()) {
    std::cout << it->second << '\n';
}

if 初始化语句

基本语法

C++17 中 if 初始化语句的基本形式如下:

if (初始化语句; 条件表达式) {
    // 条件成立时执行
}

else 的形式:

if (初始化语句; 条件表达式) {
    // 条件成立
} else {
    // 条件不成立
}

其中,初始化语句和条件表达式之间使用分号分隔。

最简单的示例

#include <iostream>
using namespace std;

int getValue() {
    return 10;
}

int main() {
    if (int x = getValue(); x > 0) {
        cout << "x 是正数,x = " << x << '\n';
    }

    return 0;
}

在这个例子中:

  1. 先执行 int x = getValue()
  2. 再判断 x > 0
  3. 如果条件成立,则进入 if 语句块。

结合结构化绑定使用

C++17 中,初始化语句还可以和结构化绑定一起使用。

例如,map::insert 会返回一个 pair

  • 第一个元素是迭代器;
  • 第二个元素表示是否插入成功。
#include <iostream>
#include <map>
#include <string>
using namespace std;

int main() {
    map<string, int> scores;

    if (auto [it, inserted] =
            scores.insert({"Alice", 95});
        inserted) {
        cout << "插入成功" << '\n';
    } else {
        cout << "键已经存在" << '\n';
    }

    return 0;
}

在条件表达式中直接判断 inserted

如果插入失败,仍可在 else 分支通过 it 访问已经存在的元素:

if (auto [it, inserted] =
        scores.insert({"Alice", 95});
    inserted) {
    cout << "插入成功" << '\n';
} else {
    cout << "已有分数:" << it->second << '\n';
}

处理函数返回值

如果一个函数返回状态码,可以在 if 中完成调用、保存结果和判断。

#include <iostream>
using namespace std;

int connectServer() {
    return 0;
}

int main() {
    if (int code = connectServer(); code == 0) {
        cout << "连接成功" << '\n';
    } else {
        cout << "连接失败,错误码:" << code << '\n';
    }

    return 0;
}

这里的 code 只用于当前判断,因此不需要放到外层作用域。

switch 初始化语句

基本语法

C++17 允许在 switch 中加入初始化语句:

switch (初始化语句; 条件表达式) {
    case 常量1:
        // ...
        break;

    case 常量2:
        // ...
        break;

    default:
        // ...
        break;
}

简单示例

#include <iostream>
using namespace std;

int getCommand() {
    return 2;
}

int main() {
    switch (int command = getCommand(); command) {
        case 1:
            cout << "添加" << '\n';
            break;

        case 2:
            cout << "删除" << '\n';
            break;

        case 3:
            cout << "查询" << '\n';
            break;

        default:
            cout << "未知命令" << '\n';
            break;
    }

    return 0;
}

这里先定义变量 command,然后以 command 的值进行分支选择。

switch 初始化变量的作用域

初始化变量的作用域覆盖:

  • switch 条件表达式;
  • 所有 case 分支;
  • default 分支。

离开整个 switch 后,变量失效。

switch (int code = getCommand(); code) {
    case 1:
        cout << code << '\n';
        break;

    default:
        cout << code << '\n';
        break;
}

// cout << code;  // 错误:code 已离开作用域

switch 的实际应用

假设一个函数返回命令类型:

enum class Command {
    Add,
    Remove,
    Search,
    Unknown
};

Command readCommand() {
    return Command::Search;
}

可以使用:

switch (auto cmd = readCommand(); cmd) {
    case Command::Add:
        cout << "执行添加操作" << '\n';
        break;

    case Command::Remove:
        cout << "执行删除操作" << '\n';
        break;

    case Command::Search:
        cout << "执行查询操作" << '\n';
        break;

    default:
        cout << "未知操作" << '\n';
        break;
}

这种写法把命令获取和命令分支处理放在同一个结构中。

ifswitch 初始化语句对比

项目if 初始化语句switch 初始化语句
引入版本C++17C++17
分隔符分号分号
适用判断任意布尔条件整数、枚举等离散值
变量作用域整个 if--else整个 switch
常见用途查找、插入、指针判断命令码、状态码、枚举

常见错误

忘记写分号

错误:

if (int x = getValue() x > 0) {
}

正确:

if (int x = getValue(); x > 0) {
}

在语句外使用变量

if (int x = 10; x > 0) {
    cout << x << '\n';
}

cout << x << '\n';  // 错误

变量 x 的作用域只到 if 语句结束。

误以为只能定义变量

初始化语句不一定必须是变量声明,也可以是普通表达式语句。

例如:

int x = 0;

if (x = getValue(); x > 0) {
    cout << x << '\n';
}

不过教学和实际开发中,更常见的是在初始化语句中声明局部变量。

在多个变量声明中使用不同类型

下面的写法错误:

if (int x = 1, double y = 2.0; x < y) {
}

同一条声明语句中不能这样混合声明不同类型。

可以改为使用结构体、pairtuple,或者提前声明其中一个变量。

综合示例:用户查询系统

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

int main() {
    map<string, int> users{
        {"Alice", 1001},
        {"Bob", 1002},
        {"Tom", 1003}
    };

    string name;
    cin >> name;

    if (auto it = users.find(name);
        it != users.end()) {
        cout << "用户编号:" << it->second << '\n';
    } else {
        cout << "用户不存在" << '\n';
    }

    return 0;
}

这个程序中,迭代器 it 只用于查询结果判断,因此放在 if 初始化语句中最合适。

知识总结

板书式速记

// if 初始化语句
if (auto value = getValue(); value > 0) {
    // ...
} else {
    // ...
}

// 容器查找
if (auto it = mp.find(key); it != mp.end()) {
    // ...
}

// 结构化绑定
if (auto [it, inserted] = s.insert(x); inserted) {
    // ...
}

// switch 初始化语句
switch (auto cmd = getCommand(); cmd) {
    case 1:
        break;
    default:
        break;
}