if-else 语句 (C++)
if-else 语句控制条件分支。 仅当 condition
计算结果为非零值(或 true
)时,才会执行 if-branch
中的语句。 如果 condition
的值为非零,则执行以下语句,并跳过以下可选 else
语句后面的语句。 否则,将跳过以下语句,如果存在 else
,则随后执行 else
后面的语句。
计算结果为非零的 condition
表达式包括:
true
- 非 null 指针,
- 任何非零算术值,或
- 一种类类型,用于定义对算术、布尔值或指针类型的明确转换。 (有关转换的信息,请参阅标准转换。)
语法
init-statement
:
expression-statement
simple-declaration
condition
:
expression
attribute-specifier-seq
optdecl-specifier-seq
declarator
brace-or-equal-initializer
statement
:
expression-statement
compound-statement
expression-statement
:
expression
opt;
compound-statement
:
{
statement-seq
opt}
statement-seq
:
statement
statement-seq
statement
if-branch
:
statement
else-branch
:
statement
selection-statement
:
if
constexpr
opt17(
init-statement
opt17condition
)
if-branch
if
constexpr
opt17(
init-statement
opt17condition
)
if-branch
else
else-branch
17 从 C++17 开始,此可选元素可用。
if-else 语句
在 if
语句的所有形式中,可计算 condition
, 它具有除了结构以外的任何值,包括所有副作用。 控制从 if
语句传递给程序中的下一个语句,除非已执行的 if-branch
或 else-branch
包含 break
、continue
或 goto
。
if...else
语句的 else
子句与同一范围内没有相应 else
语句的最接近的上一个 if
语句相关联。
示例
此示例代码演示了多个正在使用的 if
语句,包括使用和不使用 else
:
// if_else_statement.cpp
#include <iostream>
using namespace std;
int main()
{
int x = 10;
if (x < 11)
{
cout << "x < 11 is true!\n"; // executed
}
else
{
cout << "x < 11 is false!\n"; // not executed
}
// no else statement
bool flag = false;
if (flag == true)
{
x = 100; // not executed
}
int *p = new int(25);
if (p)
{
cout << *p << "\n"; // outputs 25
}
else
{
cout << "p is null!\n"; // executed if memory allocation fails
}
}
输出:
x < 11 is true!
25
带有初始值设定项的 if 语句
从 C++17 开始,if
语句还可能包含声明和初始化命名变量的 init-statement
表达式。 当变量仅在 if-statement 范围内需要时,请使用 if-statement 的此形式。 特定于 Microsoft:此形式从 Visual Studio 2017 版本 15.3 开始提供,至少需要 /std:c++17
编译器选项。
示例
// Compile with /std:c++17
#include <iostream>
#include <mutex>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
map<int, string> m{ {1, "one"}, {2, "two"}, {10,"ten"} };
mutex mx;
bool shared_flag = true; // guarded by mx
int getValue() { return 42; }
int main()
{
if (auto it = m.find(10); it != m.end())
{
cout << it->second << "\n";
}
if (int x = getValue(); x == 42)
{
cout << "x is 42\n";
}
if (lock_guard<mutex> lock(mx); shared_flag)
{
cout << "setting shared_flag to false\n";
shared_flag = false;
}
string s{ "if" };
if (auto keywords = { "if", "for", "while" }; any_of(keywords.begin(), keywords.end(), [&s](const char* kw) { return s == kw; }))
{
cout << "Error! Token must not be a keyword\n";
}
}
输出:
ten
x is 42
setting shared_flag to false
Error! Token must not be a keyword
if constexpr 语句
从 C++17 开始,可以使用函数模板中的 if constexpr
语句做出编译时分支决策,而无需求助于多个函数重载。 特定于 Microsoft:此形式从 Visual Studio 2017 版本 15.3 开始提供,至少需要 /std:c++17
编译器选项。
示例
此示例演示如何根据发送到模板的类型有条件地编译模板:
// Compile with /std:c++17
#include <iostream>
template<typename T>
auto Show(T t)
{
//if (std::is_pointer_v<T>) // Show(a) results in compiler error for return *t. Show(b) results in compiler error for return t.
if constexpr (std::is_pointer_v<T>) // This statement goes away for Show(a)
{
return *t;
}
else
{
return t;
}
}
int main()
{
int a = 42;
int* pB = &a;
std::cout << Show(a) << "\n"; // prints "42"
std::cout << Show(pB) << "\n"; // prints "42"
}
if constexpr
语句在编译时计算,编译器仅生成与发送到函数模板的参数类型匹配的 if
分支的代码。 如果注释掉 if constexpr
语句并取消注释 if
语句,编译器将为这两个分支生成代码。 这意味着你收到错误:
- 如果调用
ShowValue(a);
,即使if
语句为 false 且代码从不执行,你也会在return *t
上收到错误,因为t
不是指针。 - 如果调用
ShowValue(pB);
,即使if
语句为 true 且代码从不执行,你也会在return t
上收到错误,因为t
是指针。
使用 if constexpr
可解决此问题,因为只有与发送到函数模板的参数类型匹配的语句才会被编译。
输出:
42
42
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈