for-Schleife
Führt eine Anweisung wiederholt bedingt aus, wobei die Anweisung die Schleifenbedingung nicht verwalten muss.
Inhalt |
[bearbeiten] Syntax
attr (optional) for ( init-statement condition (optional) ; expression (optional) ) statement |
|||||||||
| attr | - | (seit C++11) eine beliebige Anzahl von Attributen | ||
| init-statement | - | eine von
Beachten Sie, dass jede init-statement mit einem Semikolon enden muss. Deshalb wird sie oft informell als Ausdruck oder Deklaration gefolgt von einem Semikolon beschrieben. | ||
| condition | - | eine Bedingung | ||
| expression | - | ein Ausdruck (typischerweise ein Ausdruck, der den Schleifenzähler inkrementiert) | ||
| Anweisung | - | eine Anweisung (typischerweise eine zusammengesetzte Anweisung) |
[bearbeiten] Bedingung
Eine condition kann entweder ein Ausdruck oder eine einfache Deklaration sein.
|
(seit C++26) |
- Wenn sie syntaktisch als Ausdruck aufgelöst werden kann, wird sie als Ausdruck behandelt. Andernfalls wird sie als Deklaration behandelt, die keine strukturierte Bindungsdeklaration ist(seit C++26).
Wenn die Steuerung zur Bedingung gelangt, liefert die Bedingung einen Wert, der verwendet wird, um zu bestimmen, ob die Anweisung ausgeführt wird.
[bearbeiten] Ausdruck
Wenn condition ein Ausdruck ist, ist der gelieferte Wert der Wert des Ausdrucks, der kontextuell zu bool konvertiert wird. Wenn diese Konvertierung fehlerhaft ist, ist das Programm fehlerhaft.
[bearbeiten] Deklaration
Wenn condition eine einfache Deklaration ist, ist der gelieferte Wert der Wert der Entscheidungsvariable (siehe unten), kontextuell zu bool konvertiert. Wenn diese Konvertierung fehlerhaft ist, ist das Programm fehlerhaft.
[bearbeiten] Nicht-strukturierte Bindungsdeklaration
Die Deklaration hat folgende Einschränkungen
- Folgt syntaktisch der folgenden Form
|
(bis C++11) |
|
(seit C++11) |
- Der Deklarator darf keine Funktion oder ein Array angeben.
- Die Typ-Spezifizierer-Sequenz(bis C++11)Deklarations-Spezifizierer-Sequenz darf nur Typ-Spezifizierer und constexpr enthalten, und sie(seit C++11) darf keine Klasse oder Aufzählung definieren.
Die Entscheidungsvariable der Deklaration ist die deklarierte Variable.
Strukturierte BindungsdeklarationDie Deklaration hat folgende Einschränkungen
Die Entscheidungsvariable der Deklaration ist die erfundene Variable e, die durch die Deklaration eingeführt wird. |
(seit C++26) |
[bearbeiten] Erklärung
Eine for-Anweisung ist äquivalent zu
{
|
|||||||||
Außer dass
- Der Geltungsbereich von init-statement und der Geltungsbereich von condition sind gleich.
- Der Geltungsbereich von statement und der Geltungsbereich von expression sind getrennt und verschachtelt innerhalb des Geltungsbereichs von init-statement und condition.
- Die Ausführung einer continue-Anweisung in statement wertet expression aus.
- Eine leere condition ist äquivalent zu true.
Wenn die Schleife innerhalb von statement beendet werden muss, kann eine break-Anweisung als beendende Anweisung verwendet werden.
Wenn die aktuelle Iteration innerhalb von statement beendet werden muss, kann eine continue-Anweisung als Abkürzung verwendet werden.
[bearbeiten] Hinweise
Wie bei der while-Schleife ist, wenn statement keine zusammengesetzte Anweisung ist, der Geltungsbereich von darin deklarierten Variablen auf den Schleifenkörper beschränkt, als ob es eine zusammengesetzte Anweisung wäre.
for (;;) int n; // n goes out of scope
Als Teil der C++ Fortschrittsgarantie ist das Verhalten undefiniert, wenn eine Schleife, die keine triviale Endlosschleife ist(seit C++26) ohne beobachtbares Verhalten nicht terminiert. Compiler dürfen solche Schleifen entfernen.
Während in C Namen, die im Geltungsbereich von init-statement und condition deklariert wurden, im Geltungsbereich von statement überschattet werden können, ist dies in C++ verboten.
for (int i = 0;;) { long i = 1; // valid C, invalid C++ // ... }
[bearbeiten] Schlüsselwörter
[bearbeiten] Beispiel
#include <iostream> #include <vector> int main() { std::cout << "1) typical loop with a single statement as the body:\n"; for (int i = 0; i < 10; ++i) std::cout << i << ' '; std::cout << "\n\n" "2) init-statement can declare multiple names, as\n" "long as they can use the same decl-specifier-seq:\n"; for (int i = 0, *p = &i; i < 9; i += 2) std::cout << i << ':' << *p << ' '; std::cout << "\n\n" "3) condition may be a declaration:\n"; char cstr[] = "Hello"; for (int n = 0; char c = cstr[n]; ++n) std::cout << c; std::cout << "\n\n" "4) init-statement can use the auto type specifier:\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-statement can be an expression:\n"; int n = 0; for (std::cout << "Loop start\n"; std::cout << "Loop test\n"; std::cout << "Iteration " << ++n << '\n') { if (n > 1) break; } std::cout << "\n" "6) constructors and destructors of objects created\n" "in the loop's body are called per each iteration:\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-statement can use structured bindings:\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) typical loop with a single statement as the body: 0 1 2 3 4 5 6 7 8 9 2) init-statement can declare multiple names, as long as they can use the same decl-specifier-seq: 0:0 2:2 4:4 6:6 8:8 3) condition may be a declaration: Hello 4) init-statement can use the auto type specifier: 3 1 4 1 5 9 5) init-statement can be an expression: Loop start Loop test Iteration 1 Loop test Iteration 2 Loop test 6) constructors and destructors of objects created in the loop's body are called per each iteration: S::S(0, 5); S::~S() S::S(1, 4); S::~S() S::S(2, 3); S::~S() 7) init-statement can use structured bindings: 4 5 6
[bearbeiten] Siehe auch
Bereichs-for-Schleife(C++11) |
führt Schleife über einen Bereich aus |
| C-Dokumentation für for
| |