Was ist die voll „für“ Schleife Syntax in C?
Frage
Ich habe einige sehr seltsame for
Schleifen zu sehen, wenn andere Leute Code zu lesen. Ich habe versucht, für eine vollständige Syntax Erklärung für die for
Schleife in C
zu suchen, aber es ist sehr schwer, weil das Wort „for
“ in keinem Zusammenhang Sätze erscheint effektiv fast unmöglich zu Google die Suche zu machen.
Diese Frage kam mich nach dem Lesen href="https://stackoverflow.com/questions/260511/russian-peasant-multiplication"> das wiederum mich neugierig gemacht.
Die for
hier:
for(p=0;p+=(a&1)*b,a!=1;a>>=1,b<<=1);
In der Mitte Zustand ein Komma ist, die beiden Teile des Codes zu trennen, was macht das Komma? Das Komma auf der rechten Seite verstehe ich, wie es sowohl a>>=1
und b<<=1
macht.
Aber innerhalb einer Schleife Ausgangsbedingung, was passiert? Ist es verlassen, wenn p==0
, wenn a==1
oder wenn beide geschehen?
Es wäre toll, wenn jemand mir dies zu verstehen helfen könnte und mich vielleicht in Richtung einer vollständigen for
Schleife Syntax Beschreibung zeigen.
Lösung
Das Komma ist nicht ausschließlich für Schleifen; es ist der Komma-Operator.
x = (a, b);
wird zuerst tun a, dann b, dann auf den Wert von b gesetzt x.
Die Syntax ist:
for (init; condition; increment)
...
Welche etwas entspricht (continue
und break
jetzt ignoriert):
init;
while (condition) {
...
increment;
}
So Ihre for-Schleife Beispiel wird (wieder ignoriert continue
und break
) entspricht
p=0;
while (p+=(a&1)*b,a!=1) {
...
a>>=1,b<<=1;
}
Welche wirkt, als ob sie (wieder continue
und break
ignorieren):
p=0;
while (true) {
p+=(a&1)*b;
if (a == 1) break;
...
a>>=1;
b<<=1;
}
Zwei zusätzliche Einzelheiten der for-Schleife, die oben in der vereinfachten Umwandlung in eine while-Schleife waren:
- Wenn die Bedingung weggelassen wird, ist es immer
true
(was zu einer Endlosschleife, es sei denn einbreak
,goto
, oder etwas anderes die Schleife bricht). - A
continue
wirkt, als wäre es ein goto an eine Markierung kurz vor dem Zuwachs war, im Gegensatz zu einemcontinue
in der while-Schleife, die den Zuwachs überspringen würden.
Auch ein wichtiges Detail über den Komma-Operator: Es ist ein Sequenzpunkt, wie &&
und ||
(weshalb ich es in separaten Erklärungen geteilt und halte seine Bedeutung intakte)
Änderungen in C99
Der C99-Standard stellt ein paar Nuancen früher nicht in dieser Erklärung erwähnt (die für C89 / C90 ist sehr gut).
Zuerst werden alle Loops sind Blöcke in ihrem eigenen Recht. Effektiv
for (...) { ... }
sich in einem Paar Klammern gewickelt
{
for (...) { ... }
}
Der Standard spricht:
ISO / IEC 9899: 1999 §6.8.5 Iterationsanweisungen
¶5 eine Iteration Anweisung ist ein Block, dessen Umfang ist eine strenge Teilmenge des Umfangs ihrer umschließenden Block. Der Schleifenkörper ist auch ein Block, dessen Umfang ist eine strenge Teilmenge des Umfangs die Wiederholungsanweisung.
Dies ist auch in der Begründung in Bezug auf den zusätzlichen Satz von Klammern beschrieben.
Zweitens kann der init
Teil in C99 sein, eine (einzige) Erklärung, wie in
for (int i = 0; i < sizeof(something); i++) { ... }
Nun ist der ‚Block um die Schleife gewickelt‘ kommt in seine eigenen; es erklärt, warum die Variable i
nicht außerhalb der Schleife zugegriffen werden kann. Sie können mehr als eine Variable deklarieren, aber sie müssen alle vom gleichen Typ sein:
for (int i = 0, j = sizeof(something); i < j; i++, j--) { ... }
Der Standard spricht:
ISO / IEC 9899: 1999 §6.8.5.3 Die for-Anweisung
Die Anweisung
for ( clause-1 ; expression-2 ; expression-3 ) statement
verhält sich wie folgt: Der Ausdruck Ausdruck-2 der kontrollierende Ausdruck ist, ist vor jeder Ausführung des Schleifenkörpers bewertet. Der Ausdruck Expressions-3 ist als ungültig Ausdruck nach jeder Ausführung des Schleifenkörpers bewertet. Wenn Klausel-1 ist ein Erklärung, der Umfang aller Variablen erklärt sie ist der Rest der Erklärung und die gesamte Schleife, die anderen zwei Ausdrücke enthält; es wird in der Reihenfolge der Ausführung erreicht vor der ersten Auswertung des Steuerausdruckes. Wenn Klausel-1 ein Ausdruck ist, ist es ausgewertet als nichtig Ausdruck vor der ersten Auswertung des Steuer Ausdrucks. 133)
Sowohl Klausel-1 und Ausdruck-3 können weggelassen werden. Ein Ausdruck weggelassen-2 wird durch eine ersetzt Nicht-Null-Konstante ist.
133) Somit Klausel-1 spezifiziert Initialisierung für die Schleife, möglicherweise erklärt ein oder mehr Variablen für die Verwendung in die Schleife; die Steuerung Ausdruck, Ausdruck-2, gibt eine vor jeder Iteration Bewertung, so dass die Ausführung der Schleife wird fortgesetzt, bis der Ausdruck gleich 0 vergleicht; und Ausdruck-3 spezifiziert eine Operation (wie beispielsweise Inkrementieren), die nach jeder Iteration durchgeführt wird.
Andere Tipps
Das Komma trennt nur zwei Ausdrücke und ist überall in C gültig, wo ein normaler Ausdruck erlaubt ist. Diese werden durchgeführt, um von links nach rechts. Der Wert des am weitesten rechts stehenden Ausdrucks ist der Wert des Gesamtausdrucks.
for
Schlaufen bestehen aus drei Teilen, von denen jedes auch leer sein kann; eine (die erste) wird am Anfang ausgeführt wird, und eine (die dritte) am Ende jeder Iteration. Diese Teile in der Regel initialisieren und einen Zähler inkrementieren verbunden sind; aber sie können nichts tun.
Der zweite Teil ist ein Test , die am Anfang jeder Ausführung ausgeführt. Wenn die Testausbeuten false
, wird die Schleife abgebrochen. Das ist alles dort ist zu ihm.
Die C-Stil-for-Schleife besteht aus drei Ausdrücke:
for (initializer; condition; counter) statement_or_statement_block;
- Die initializer läuft einmal, wenn die Schleife beginnt.
- Die Bedingung wird vor jeder Iteration geprüft. Die Schleife läuft so lange es true ergibt.
- Der Zähler läuft einmal nach jeder Iteration.
Jeder dieser Teile kann ein Ausdruck gültig in der Sprache sein, die Schleife in schreiben. Das bedeutet, dass sie mehr kreativ genutzt werden. Alles, was Sie vorher tun wollen in die initializer gehen können, was Sie wollen in tun, zwischen in den Zustand gehen oder den Zähler, bis zu dem Punkt, wo die Schleife mehr keinen Körper hat.
Um das zu erreichen, kommt der Komma-Operator in sehr handlich. Es ermöglicht Ihnen, Ketten Ausdrücke zusammen einen einzigen neuen Ausdruck zu bilden. Die meiste Zeit ist es auf diese Weise in einer for-Schleife, die anderen Auswirkungen des Komma-Operator (z Bewertungsüberlegungen) spielen eine untergeordnete Rolle verwendet wird.
Auch wenn Sie kreativ mit Hilfe Syntax kluge Dinge tun können - ich würde bleiben davon klar, bis ich einen wirklich guten Grund, dies zu tun finden. Spielen Code Golf mit for-Schleifen macht Code schwerer zu lesen und zu verstehen (und halten).
Die Wikipedia hat eine schöne Artikel auf der for-Schleife rel="nofollow auch.
Alles ist optional in einer for
Schleife. Wir können mehr als eine Variable initialisieren, die wir für mehr als eine Bedingung überprüfen können, können wir mehr als eine Variable mit dem Komma-Operator iterieren.
Die folgende for
Schleife werden Sie in eine Endlosschleife nehmen. Achten Sie darauf, durch den Zustand zu überprüfen.
for(;;)
Konrad erwähnt der entscheidende Punkt, dass ich wiederholen möchte. Der Wert des am weitesten rechts stehenden Ausdrucks ist der Wert des Gesamtausdrucks
Ein Gnu Compiler diese Warnung angegeben, wenn ich legte zwei Tests in der „Zustand“ in der for-Schleife
warning: left-hand operand of comma expression has no effect
Was ich wirklich gedacht für die „Bedingung“ waren zwei Tests mit einem „&&“ zwischen. Per Konrad Aussage würde wirken sich nur auf den Test auf rechts von dem Komma die Bedingung.
die for-Schleife ist die Ausführung für bestimmte Zeit (;;)
die syntex für for-Schleife
für (;;)
oder
für (initializer; Bedingung; Zähler)
z (RMV = 1; RMV <= 15; RMV ++)
Ausführung bis 15-mal in für Block
1.First INITIALIZ der Wert, weil der Wert beginnen
(z) = 1 oder RMV RMV = 2
2.second Anweisung testet die Bedingung wahr oder falsch ist, wird die Bedingung erfüllt Anzahl Zeitausführung des for-Schleife und die Bedingung falsch beenden für Block,
z i = 5; i <= 10 die Bedingung wahr ist
i=10;i<10 the condition is false terminate for block,
3.third ist Zunahme oder -abnahme
(z) rmv ++ oder ++ rmv