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-branch
或 else-branch
包含 break
、continue
或 goto
,否則控制權會從 if
陳述式傳遞至程式中的下一個陳述式。
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 陳述式的範圍內需要該變數時,使用此形式的 if 陳述式。 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);
,您會在return *t
上收到錯誤,因為t
不是指標,即使if
陳述式為 false 而且永遠不會執行程式碼。 - 如果呼叫
ShowValue(pB);
,您會在return t
上收到錯誤,因為t
是指標,即使if
陳述式為 true 而且永遠不會執行程式碼。
使用 if constexpr
可解決此問題,因為只有符合傳送至函式範本之引數類型的陳述式才會被編譯。
輸出:
42
42
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應