Оператор 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-seqdeclaratorbrace-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:
ifconstexpropt17 opt 17 opt17(init-statementcondition)if-branch
ifconstexpropt17 opt 17 opt17(init-statementcondition)if-branchelseelse-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

См. также

Операторы выбора
Ключевые слова
Оператор switch (C++)