Freigeben über


if-else-Anweisung (C++)

Die if-else-Anweisung steuert die bedingte Verzweigung. Anweisungen im if-branch-Element werden nur ausgeführt, wenn condition in einen Wert ungleich null (oder true) ausgewertet wird. Wenn der Wert von condition ungleich null ist, wird die folgende Anweisung ausgeführt, und die Anweisung, die auf das optionale else-Element folgt, wird übersprungen. Andernfalls wird die folgende Anweisung übersprungen, und die Anweisung wird nach dem else-Element ausgeführt, wenn ein else-Element vorhanden ist.

Die folgenden condition-Ausdrücke werden in ungleich null ausgewertet:

  • true
  • ein Nicht-Null-Zeiger,
  • ein beliebiger arithmetischer Wert, der ungleich null ist, oder
  • ein Klassentyp, der eine eindeutige Konvertierung in einen arithmetischen oder booleschen Typ oder einen Zeigertyp definiert. (Weitere Informationen zu Konvertierungen finden Sie unter Standardkonvertierungen.)

Syntax

init-statement:
expression-statement
simple-declaration

condition:
expression
attribute-specifier-seqopt decl-specifier-seq declarator brace-or-equal-initializer

statement:
expression-statement
compound-statement

expression-statement:
expressionopt ;

compound-statement:
{optstatement-seq }

statement-seq:
statement
statement-seq statement

if-branch:
statement

else-branch:
statement

selection-statement:
if constexpropt17 ( init-statementopt17 condition ) if-branch
if constexpropt17 ( init-statementopt17 condition ) if-branch else else-branch

17 Dieses optionale Element ist ab C++17 verfügbar.

if-else-Anweisungen

In allen Formen der if-Anweisung wird das condition-Element ausgewertet, das außer einer Struktur einen beliebigen Wert aufweisen kann, einschließlich aller Nebeneffekte. Die Kontrolle wird von der if-Anweisung an die nächste Anweisung im Programm übergeben, es sei denn, das ausgeführte if-branch- oder else-branch-Element enthält eine break-, continue- oder goto-Anweisung.

Die else-Klausel einer if...else-Anweisung wird der nächstgelegenen vorangegangenen if-Anweisung im selben Bereich zugeordnet, der keine entsprechende else-Anweisung aufweist.

Beispiel

In diesem Beispielcode wird die Verwendung mehrerer if-Anweisungen veranschaulicht – sowohl mit als auch ohne 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
    }
}

Ausgabe:

x < 11 is true!
25

if-Anweisung mit einem Initialisierer

Ab C++17 kann eine if-Anweisung außerdem einen init-statement-Ausdruck enthalten, der eine benannte Variable deklariert und initialisiert. Verwenden Sie diese Form der if-Anweisung, wenn die Variable ausschließlich innerhalb des Bereichs der if-Anweisung erforderlich ist. Microsoft-spezifisch: Dieses Formular ist ab der Version 15.3 von Visual Studio 2017 verfügbar und erfordert mindestens die Compileroption /std:c++17.

Beispiel

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

Ausgabe:

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

if constexpr-Anweisungen

Ab C++17 können Sie in Funktionsvorlagen eine if constexpr-Anweisung verwenden, um Entscheidungen für die Verzweigung zur Kompilierzeit zu treffen, ohne dabei mehrere Funktionsüberladungen nutzen zu müssen. Microsoft-spezifisch: Dieses Formular ist ab der Version 15.3 von Visual Studio 2017 verfügbar und erfordert mindestens die Compileroption /std:c++17.

Beispiel

In diesem Beispiel wird veranschaulicht, wie Sie eine Vorlage basierend auf dem Typ bedingt kompilieren können, der an die Vorlage gesendet wurde:

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

Die if constexpr-Anweisung wird zur Kompilierzeit ausgewertet, und der Compiler generiert Code ausschließlich für die if-Verzweigung, die dem Typ des Arguments entspricht, das an die Funktionsvorlage gesendet wird. Wenn Sie die if constexpr-Anweisung auskommentieren und die Auskommentierung für die if-Anweisung aufheben, generiert der Compiler Code für beide Verzweigungen. Das bedeutet, dass Sie eine Fehlermeldung erhalten:

  • Da es sich bei t nicht um einen Zeiger handelt, tritt bei return *t ein Fehler auf, wenn Sie ShowValue(a); aufrufen, obwohl die if-Anweisung FALSE ist und der Code nie ausgeführt wird.
  • Da es sich bei t um einen Zeiger handelt, tritt bei return t ein Fehler auf, wenn Sie ShowValue(pB); aufrufen, obwohl die if-Anweisung TRUE ist und der Code nie ausgeführt wird.

Durch die Verwendung von if constexpr kann dieses Problem gelöst werden. Das liegt daran, dass ausschließlich die Anweisung kompiliert wird, die dem Typ des Arguments entspricht, das an die Funktionsvorlage gesendet wird.

Ausgabe:

42
42

Weitere Informationen

Auswahlanweisungen
Schlüsselwörter
switch-Anweisung (C++)