Оператор if-else (C++)
Оператор if-else управляет условным ветвлением. Операторы в объекте if-branch
выполняются только в том случае, если condition
значение ненулевого значения (или true
). Если значение condition
ненулевого значения, выполняется следующая инструкция, а оператор, следующий за необязательным else
, пропускается. В противном случае следующая инструкция пропускается, а если есть else
оператор после else
выполнения.
condition
выражения, которые оцениваются как ненулевое:
true
- указатель, отличный от NULL,
- любое арифметическое значение ненулевого или
- Тип класса, определяющий однозначное преобразование в арифметический, логический или указательный тип. (Сведения о преобразованиях см. в разделе Стандартные преобразования.)
Синтаксис
init-statement
:
expression-statement
simple-declaration
condition
:
expression
attribute-specifier-seq
необ.decl-specifier-seq
declarator
brace-or-equal-initializer
statement
:
expression-statement
compound-statement
expression-statement
:
expression
необ.;
compound-statement
:
{
statement-seq
необ.}
statement-seq
:
statement
statement-seq
statement
if-branch
:
statement
else-branch
:
statement
selection-statement
:
if
constexpr
opt17 opt 17 opt17(
init-statement
condition
)
if-branch
if
constexpr
opt17 opt 17 opt17(
init-statement
condition
)
if-branch
else
else-branch
17 Этот необязательный элемент доступен начиная с C++17.
Операторы if-else
Во всех формах инструкции if
, которая может иметь любое значение, condition
кроме структуры, оценивается, включая все побочные эффекты. Элемент управления передается из if
инструкции в следующую инструкцию в программе, если не выполняется if-branch
или else-branch
не содержится break
, continue
или goto
.
Предложение else
инструкции if...else
связано с ближайшим предыдущим if
оператором в той же область, которая не имеет соответствующего else
оператора.
Пример
В этом примере кода показаны несколько 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.. Корпорация Майкрософт: эта форма доступна начиная с 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
Значение
Начиная с C++17, можно использовать инструкцию if constexpr
в шаблонах функций, чтобы принимать решения о ветвлениях во время компиляции, не прибегая к нескольким перегрузкам функций. Корпорация Майкрософт: эта форма доступна начиная с 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
См. также
Начиная с C++17, можно использовать инструкцию if constexpr
в шаблонах функций, чтобы принимать решения о ветвлениях во время компиляции, не прибегая к нескольким перегрузкам функций. Корпорация Майкрософт: эта форма доступна начиная с 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 Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по