Udostępnij za pośrednictwem


if-else, instrukcja (C++)

Instrukcja if-else kontroluje rozgałęzianie warunkowe. Instrukcje w elemecie if-branch są wykonywane tylko wtedy, gdy condition funkcja oblicza wartość niezerową (lub true). Jeśli wartość condition jest niezerowa, zostanie wykonana następująca instrukcja, a instrukcja po opcjonalnym else zostanie pominięta. W przeciwnym razie poniższa instrukcja zostanie pominięta, a jeśli istnieje else instrukcja , po wykonaniu instrukcji else zostanie wykonana.

condition wyrażenia, które są obliczane na niezerowe, to:

  • true
  • wskaźnik o wartości innej niż null,
  • dowolna wartość arytmetyczna niezerowa lub
  • typ klasy, który definiuje jednoznaczną konwersję na typ arytmetyczny, logiczny lub wskaźnik. (Aby uzyskać informacje na temat konwersji, zobacz Konwersje standardowe).

Składnia

init-statement:
expression-statement
simple-declaration

condition:
expression
attribute-specifier-seqZdecydowaćdecl-specifier-seqdeclaratorbrace-or-equal-initializer

statement:
expression-statement
compound-statement

expression-statement:
expressionZdecydować;

compound-statement:
{statement-seqZdecydować}

statement-seq:
statement
statement-seq statement

if-branch:
statement

else-branch:
statement

selection-statement:
ifconstexpropt 17init-statement(opt17condition)if-branch
ifconstexpropt 17init-statement(opt17condition)if-branchelseelse-branch

17 Ten opcjonalny element jest dostępny od wersji C++17.

instrukcje if-else

We wszystkich formach instrukcji if , conditionktóra może mieć dowolną wartość z wyjątkiem struktury, jest obliczana, w tym wszystkie skutki uboczne. Kontrolka przekazuje instrukcję z instrukcji if do następnej instrukcji w programie, chyba że wykonany if-branch lub else-branch zawiera breakcontinue, lub goto.

Klauzula else instrukcji if...else jest skojarzona z najbliższą poprzednią if instrukcją w tym samym zakresie, który nie ma odpowiedniej else instrukcji.

Przykład

Ten przykładowy kod przedstawia kilka if instrukcji w użyciu, zarówno z , jak i bez 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
    }
}

Wyjście:

x < 11 is true!
25

if, instrukcja z inicjatorem

Począwszy od języka C++17, if instrukcja może również zawierać init-statement wyrażenie, które deklaruje i inicjuje nazwaną zmienną. Użyj tej formy instrukcji if, gdy zmienna jest potrzebna tylko w zakresie instrukcji if. Specyficzne dla firmy Microsoft: ten formularz jest dostępny od wersji 15.3 programu Visual Studio 2017 i wymaga co najmniej opcji kompilatora /std:c++17 .

Przykład

// 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";
    }
}

Wyjście:

ten
x is 42
setting shared_flag to false
Error! Token must not be a keyword

if constexpr, instrukcje

Począwszy od języka C++17, można użyć if constexpr instrukcji w szablonach funkcji, aby podejmować decyzje dotyczące rozgałęziania w czasie kompilacji bez konieczności uciekania się do wielu przeciążeń funkcji. Specyficzne dla firmy Microsoft: ten formularz jest dostępny od wersji 15.3 programu Visual Studio 2017 i wymaga co najmniej opcji kompilatora /std:c++17 .

Przykład

W tym przykładzie pokazano, jak warunkowo skompilować szablon na podstawie typu wysłanego do niego:

// 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"
}

Instrukcja if constexpr jest obliczana w czasie kompilacji, a kompilator generuje tylko kod dla if gałęzi zgodnej z typem argumentu wysyłanego do szablonu funkcji. Jeśli oznaczysz jako komentarz instrukcję if constexpr i usuń komentarz z if instrukcji, kompilator generuje kod dla obu gałęzi. Oznacza to, że występuje błąd:

  • Jeśli wywołasz ShowValue(a); błąd, return *t ponieważ t nie jest wskaźnikiem, mimo że if instrukcja jest fałszywa, a kod nigdy nie jest wykonywany.
  • Jeśli wywołasz ShowValue(pB); błąd, return t ponieważ t jest wskaźnikiem, mimo że if instrukcja jest prawdziwa, a kod nigdy nie jest wykonywany.

Użycie if constexpr rozwiązuje ten problem, ponieważ kompilowana jest tylko instrukcja zgodna z typem argumentu wysyłanego do szablonu funkcji.

Wyjście:

42
42

Zobacz też

Instrukcje wyboru
Słowa kluczowe
switch Instrukcja (C++)