Namespaces
Variants

for loop

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
for
range- for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Führt eine Anweisung wiederholt bedingt aus, wobei die Anweisung die Schleifenbedingung nicht verwalten muss.

Inhaltsverzeichnis

Syntax

attr  (optional) for ( init-statement condition  (optional) ; expression  (optional) ) statement
attr - (seit C++11) beliebig viele Attribute
init-statement - eines der Folgenden
(seit C++23)

Beachten Sie, dass jede init-statement mit einem Semikolon enden muss. Deshalb wird sie oft informell als ein Ausdruck oder eine Deklaration gefolgt von einem Semikolon beschrieben.

condition - eine Bedingung
expression - ein Ausdruck (typischerweise ein Ausdruck, der den Schleifenzähler inkrementiert)
statement - eine Anweisung (typischerweise eine zusammengesetzte Anweisung)

Bedingung

Eine Bedingung kann entweder ein Ausdruck oder eine einfache Deklaration sein.

  • Wenn es syntaktisch als eine structured binding -Deklaration aufgelöst werden kann, wird es als structured binding-Deklaration interpretiert.
(since C++26)
  • Wenn es syntaktisch als Ausdruck aufgelöst werden kann, wird es als Ausdruck behandelt. Andernfalls wird es als Deklaration behandelt die keine strukturierte Bindungsdeklaration ist (seit C++26) .

Wenn die Steuerung die Bedingung erreicht, ergibt die Bedingung einen Wert, der verwendet wird, um zu bestimmen, ob statement ausgeführt wird.

Ausdruck

Wenn condition ein Ausdruck ist, ist der von ihm gelieferte Wert der Wert des Ausdrucks, der kontextuell zu bool konvertiert wird. Wenn diese Konvertierung fehlerhaft ist, ist das Programm fehlerhaft.

Deklaration

Wenn condition eine einfache Deklaration ist, ist der von ihr gelieferte Wert der Wert der Entscheidungsvariablen (siehe unten), kontextuell konvertiert zu bool . Wenn diese Konvertierung fehlerhaft ist, ist das Programm fehlerhaft.

Nicht-strukturierte Bindungsdeklaration

Die Deklaration unterliegt folgenden Einschränkungen:

  • Syntaktisch entspricht es der folgenden Form:
  • type-specifier-seq declarator = assignment-expression
(bis C++11)
  • attribute-specifier-seq (optional) decl-specifier-seq declarator brace-or-equal-initializer
(seit C++11)

Die Entscheidungsvariable der Deklaration ist die deklarierte Variable.

Strukturierte Bindungsdeklaration

Die Deklaration unterliegt folgenden Einschränkungen:

Die Entscheidungsvariable der Deklaration ist die eingeführte Variable e , die durch die Deklaration eingeführt wird .

(seit C++26)

Erklärung

Eine for -Anweisung, die äquivalent ist zu:

{
Initialisierungsanweisung
while ( Bedingung )
{
Anweisung
Ausdruck ;
}

}

Außer dass

  • Der Gültigkeitsbereich von init-statement und der Gültigkeitsbereich von condition sind identisch.
  • Der Gültigkeitsbereich von statement und der Gültigkeitsbereich von expression sind disjunkt und innerhalb des Gültigkeitsbereichs von init-statement und condition verschachtelt.
  • Die Ausführung einer continue statement in statement wertet expression aus.
  • Eine leere condition entspricht true .

Wenn die Schleife innerhalb der statement beendet werden muss, kann eine break statement als abschließende Anweisung verwendet werden.

Wenn die aktuelle Iteration innerhalb einer statement beendet werden muss, kann eine continue statement als Abkürzung verwendet werden.

Hinweise

Wie beim while -Loop gilt: Wenn die Anweisung keine zusammengesetzte Anweisung ist, ist der Gültigkeitsbereich der darin deklarierten Variablen auf den Schleifenkörper beschränkt, als ob es eine zusammengesetzte Anweisung wäre.

for (;;)
    int n;
// n geht außerhalb des Gültigkeitsbereichs

Im Rahmen der C++ Fortschrittsgarantie ist das Verhalten undefiniert , wenn eine Schleife , die keine triviale Endlosschleife ist (seit C++26) ohne beobachtbares Verhalten nicht terminiert. Compilern ist es erlaubt, solche Schleifen zu entfernen.

Während in C Namen, die im Gültigkeitsbereich von init-statement und condition deklariert werden, im Gültigkeitsbereich von statement überschattet werden können, ist dies in C++ verboten:

for (int i = 0;;)
{
    long i = 1;   // gültiges C, ungültiges C++
    // ...
}

Schlüsselwörter

for

Beispiel

#include <iostream>
#include <vector>
int main()
{
    std::cout << "1) typische Schleife mit einer einzelnen Anweisung als Rumpf:\n";
    for (int i = 0; i < 10; ++i)
        std::cout << i << ' ';
    std::cout << "\n\n" "2) Init-Anweisung kann mehrere Namen deklarieren,\n"
                 "solange sie dieselbe Dekl-Spezifizierer-Sequenz verwenden können:\n";
    for (int i = 0, *p = &i; i < 9; i += 2)
        std::cout << i << ':' << *p << ' ';
    std::cout << "\n\n" "3) Bedingung kann eine Deklaration sein:\n";
    char cstr[] = "Hello";
    for (int n = 0; char c = cstr[n]; ++n)
        std::cout << c;
    std::cout << "\n\n" "4) Init-Anweisung kann den auto-Typspezifizierer verwenden:\n";
    std::vector<int> v = {3, 1, 4, 1, 5, 9};
    for (auto iter = v.begin(); iter != v.end(); ++iter)
        std::cout << *iter << ' ';
    std::cout << "\n\n" "5) Init-Anweisung kann ein Ausdruck sein:\n";
    int n = 0;
    for (std::cout << "Schleifenstart\n";
         std::cout << "Schleifentest\n";
         std::cout << "Iteration " << ++n << '\n')
    {
        if (n > 1)
            break;
    }
    std::cout << "\n" "6) Konstruktoren und Destruktoren von Objekten, die\n"
                 "im Schleifenrumpf erstellt werden, werden pro Iteration aufgerufen:\n";
    struct S
    {
        S(int x, int y) { std::cout << "S::S(" << x << ", " << y << "); "; }
        ~S() { std::cout << "S::~S()\n"; }
    };
    for (int i{0}, j{5}; i < j; ++i, --j)
        S s{i, j};
    std::cout << "\n" "7) Init-Anweisung kann strukturierte Bindungen verwenden:\n";
    long arr[]{1, 3, 7};
    for (auto [i, j, k] = arr; i + j < k; ++i)
        std::cout << i + j << ' ';
    std::cout << '\n';
}

Ausgabe:

1) typische Schleife mit einer einzelnen Anweisung als Rumpf:
0 1 2 3 4 5 6 7 8 9
2) Init-Anweisung kann mehrere Namen deklarieren,
solange sie dieselbe Dekl-Spezifizierer-Sequenz verwenden können:
0:0 2:2 4:4 6:6 8:8
3) Bedingung kann eine Deklaration sein:
Hello
4) Init-Anweisung kann den auto-Typspezifizierer verwenden:
3 1 4 1 5 9
5) Init-Anweisung kann ein Ausdruck sein:
Schleifenstart
Schleifentest
Iteration 1
Schleifentest
Iteration 2
Schleifentest
6) Konstruktoren und Destruktoren von Objekten, die
im Schleifenrumpf erstellt werden, werden pro Iteration aufgerufen:
S::S(0, 5); S::~S()
S::S(1, 4); S::~S()
S::S(2, 3); S::~S()
7) Init-Anweisung kann strukturierte Bindungen verwenden:
4 5 6

Siehe auch

Range- for Schleife (C++11) führt Schleife über Bereich aus