Es gibt drei Schleifen in C: for
, while
und do-while
. Was ist der Unterschied zwischen ihnen?
Zum Beispiel scheint es fast alle while
Aussagen können durch ersetzt werden for
Aussagen, oder? Dann, was ist der Vorteil mit while
?
Benutzer355546
Es gibt drei Schleifen in C: for
, while
und do-while
. Was ist der Unterschied zwischen ihnen?
Zum Beispiel scheint es fast alle while
Aussagen können durch ersetzt werden for
Aussagen, oder? Dann, was ist der Vorteil mit while
?
Robert Grener
EIN while-Schleife wertet immer zuerst die Bedingung aus.
while (condition) {
//gets executed after condition is checked
}
EIN do/while-Schleife führt immer den Code in der aus do{}
zuerst blocken und dann die Bedingung auswerten.
do {
//gets executed at least once
} while (condition);
EIN für Schleife ermöglicht es Ihnen, eine Zählervariable, eine Prüfbedingung und eine Möglichkeit zum Inkrementieren Ihres Zählers in einer Zeile zu initiieren.
for (int x = 0; x < 100; x++) {
//executed until x >= 100
}
Am Ende des Tages sind sie alle immer noch Schleifen, aber sie bieten eine gewisse Flexibilität, wie sie ausgeführt werden.
Hier ist eine großartige Erklärung für die Argumentation hinter der Verwendung der verschiedenen Arten von Schleifen, die zur Klärung der Dinge beitragen können. Danke Clyfe
Der Hauptunterschied zwischen der
for
‘s und diewhile
‘s ist eine Frage der Pragmatik: Wir verwenden normalerweisefor
wenn es eine bekannte Anzahl von Iterationen gibt, und verwendenwhile
konstruiert, wenn die Anzahl der Iterationen nicht im Voraus bekannt ist. Daswhile
vsdo ... while
Das Problem ist auch pragmatisch, der zweite führt die Anweisungen beim Start einmal aus und verhält sich danach genauso wie das einfache while.
For-Schleifen sind besonders schön, weil sie prägnant sind. Damit diese for-Schleife:
for (int x = 0; x < 100; x++) {
//executed until x >= 100
}
um als While-Schleife geschrieben zu werden, müssten Sie Folgendes tun:
int count = 0;
while (count < 100) {
//do stuff
count++;
}
In diesem Fall gibt es einfach mehr Zeug, mit dem man Schritt halten kann und das count++;
könnte in der Logik verloren gehen. Dies kann je nach Ort zu Problemen führen count
inkrementiert wird und ob sie vor oder nach der Logik der Schleife inkrementiert werden soll oder nicht. Mit einer for
-Schleife wird Ihre Zählervariable immer vor der nächsten Iteration der Schleife inkrementiert, was Ihrem Code eine gewisse Einheitlichkeit verleiht.
Der Vollständigkeit halber ist es wahrscheinlich sinnvoll, darüber zu sprechen break
und continue
Anweisungen hier, die bei der Schleifenverarbeitung nützlich sind.
Unterbrechung beendet sofort die aktuelle Schleife und es werden keine weiteren Iterationen ausgeführt.
//will only run "do stuff" twice
for (int x = 0; x < 100; x++) {
if (x == 2) {
break;
}
//do stuff
}
fortsetzen wird die beenden aktuelle Iteration und weiter zum nächsten.
//will run "do stuff" until x >= 100 except for when x = 2
for (int x = 0; x < 100; x++) {
if (x == 2) {
continue;
}
//do stuff
}
Beachten Sie, dass in einer for-Schleife continue
wertet die part3
Ausdruck von for (part1; part2; part3)
; Im Gegensatz dazu springt es in einer While-Schleife nur, um die Schleifenbedingung neu zu bewerten.
Sollten Sie das Verhalten von ‘Continue;’ in einer ‘for’-Schleife vs. einer ‘while’-Schleife? Ansonsten gute Antwort.
– Jonathan Leffler
1. Juni 2010 um 15:30 Uhr
+1 für ausgezeichnete Antwort. Bemerkenswert: for-Schleifen benötigen keine Zählervariable. In Sprachen im C-Stil sind sie eigentlich für (
– Sean Edwards
1. Juni 2010 um 15:42 Uhr
Der Hauptunterschied zwischen der for's
und die while's
ist eine Frage der Pragmatik: Wir verwenden normalerweise for
wenn es eine gibt bekannte Anzahl von Iterationenund verwenden while
konstruiert wann die Anzahl der Iterationen ist im Voraus nicht bekannt. Das while
vs do ... while
Es geht auch um Pragmatik, der zweite führt die Anweisungen aus einmal am Anfang, und danach verhält es sich genauso wie das einfache while
.
– Klyfe
1. Juni 2010 um 15:48 Uhr
+1 gut geschriebene Antwort, und manchmal ist es gut für alle, die “Grundlagen” zu überdenken
– JYelton
1. Juni 2010 um 17:36 Uhr
Ich liebe die Antwort, besonders den Teil, in dem Sie über die Einheitlichkeit beim Erhöhen des Zählers im Falle eines „for“ im Vergleich zu möglicherweise irgendwo in der Iteration im Falle eines „while“ sprechen. Ehrlich gesagt hätte ich es nie so eloquent ausgedrückt, obwohl es hier nicht viel Neues gibt
– Schravan
1. Juni 2010 um 18:03 Uhr
psanzani
Wenn es starke Bedenken hinsichtlich Geschwindigkeit und Leistung gibt, besteht der beste Ansatz darin, den vom Compiler erzeugten Code auf Assemblyebene zu überprüfen.
Der folgende Code zeigt beispielsweise, dass das „do-while“ etwas schneller ist. Dies liegt daran, dass die „jmp“-Anweisung nicht von der „do-while“-Schleife verwendet wird.
Übrigens, in diesem speziellen Beispiel ist der schlimmste Fall durch die “for”-Schleife gegeben. :))
int main(int argc, char* argv[])
{
int i;
char x[100];
// "FOR" LOOP:
for (i=0; i<100; i++ )
{
x[i] = 0;
}
// "WHILE" LOOP:
i = 0;
while (i<100 )
{
x[i++] = 0;
}
// "DO-WHILE" LOOP:
i = 0;
do
{
x[i++] = 0;
}
while (i<100);
return 0;
}
// “FOR”-SCHLEIFE:
010013C8 mov dword ptr [ebp-0Ch],0
010013CF jmp wmain+3Ah (10013DAh)
for (i=0; i<100; i++ )
{
x[i] = 0;
010013D1 mov eax,dword ptr [ebp-0Ch] <<< UPDATE i
010013D4 add eax,1
010013D7 mov dword ptr [ebp-0Ch],eax
010013DA cmp dword ptr [ebp-0Ch],64h <<< TEST
010013DE jge wmain+4Ah (10013EAh) <<< COND JUMP
010013E0 mov eax,dword ptr [ebp-0Ch] <<< DO THE JOB..
010013E3 mov byte ptr [ebp+eax-78h],0
010013E8 jmp wmain+31h (10013D1h) <<< UNCOND JUMP
}
// “WHILE-SCHLEIFE:
i = 0;
010013EA mov dword ptr [ebp-0Ch],0
while (i<100 )
{
x[i++] = 0;
010013F1 cmp dword ptr [ebp-0Ch],64h <<< TEST
010013F5 jge wmain+6Ah (100140Ah) <<< COND JUMP
010013F7 mov eax,dword ptr [ebp-0Ch] <<< DO THE JOB..
010013FA mov byte ptr [ebp+eax-78h],0
010013FF mov ecx,dword ptr [ebp-0Ch] <<< UPDATE i
01001402 add ecx,1
01001405 mov dword ptr [ebp-0Ch],ecx
01001408 jmp wmain+51h (10013F1h) <<< UNCOND JUMP
}
// “DO-WHILE”-SCHLEIFE:
i = 0;
. 0100140A mov dword ptr [ebp-0Ch],0
do
{
x[i++] = 0;
01001411 mov eax,dword ptr [ebp-0Ch] <<< DO THE JOB..
01001414 mov byte ptr [ebp+eax-78h],0
01001419 mov ecx,dword ptr [ebp-0Ch] <<< UPDATE i
0100141C add ecx,1
0100141F mov dword ptr [ebp-0Ch],ecx
01001422 cmp dword ptr [ebp-0Ch],64h <<< TEST
01001426 jl wmain+71h (1001411h) <<< COND JUMP
}
while (i<100);
Der Lesbarkeit halber
Übrigens können Sie goto auch als Schleife verwenden.
– Wirbelwind
1. Juni 2010 um 15:14 Uhr
Für eine andere Sache gibt es Rekursion. Und Sie können jeden Loop-Stil durch jeden anderen Stil ersetzen.
– Wirbelwind
1. Juni 2010 um 15:15 Uhr
Tatsächlich … sind alle Schleifen wirklich nur schicke GOTO-Zweige.
– Armstärkste
1. Juni 2010 um 15:34 Uhr
@WhirlWind Abgesehen davon, dass Sie in Sprachen ohne Rekursion wahrscheinlich mit Stapelüberläufen enden. (Und Sie könnten hier landen und nach Stapelüberläufen fragen, was mich ein wenig zum Lächeln bringen würde.)
– Sean Edwards
1. Juni 2010 um 15:53 Uhr
@Sean ja, darüber habe ich nachgedacht und ob es eine Möglichkeit gibt, den Stapelüberlauf zu umgehen. Natürlich, wenn es eine Schwanzrekursion gibt …
– Wirbelwind
1. Juni 2010 um 15:58 Uhr
Sie sind alle austauschbar; Sie könnten einen Typ auswählen und für immer nichts anderes verwenden, aber normalerweise ist einer für eine bestimmte Aufgabe bequemer. Es ist, als würde man sagen: „Warum Schalter haben, man kann einfach ein paar if-Anweisungen verwenden“ – stimmt, aber wenn es ein gängiges Muster ist, eine Variable auf eine Reihe von Werten zu überprüfen, ist es praktisch und viel einfacher zu lesen, wenn es eine Sprachfunktion gibt das zu tun
Justin Ether
Wenn Sie möchten, dass eine Schleife ausgeführt wird, während eine Bedingung wahr ist, und nicht für eine bestimmte Anzahl von Iterationen, ist es für jemand anderen viel einfacher zu verstehen:
while (cond_true)
als so etwas:
for (; cond_true ; )
Ich weiß es nicht viel Einfacher. Ich würde vermuten, dass, wenn C nicht die erste Form hätte, wir uns alle inzwischen daran gewöhnt hätten, die zweite zu sehen.
– Café
2. Juni 2010 um 5:11 Uhr
Fair genug, aber ich garantiere, dass ich “WTF” denken würde, wenn ich die zweite Version in irgendeinem Code sehen würde, den ich pflege…
– Justin Ethier
2. Juni 2010 um 13:11 Uhr
Code sollte sich wie Prosa lesen, ersterer ist der natürlichen Sprache viel näher. Vielleicht nicht “viel einfacher”, aber sehr wahrscheinlich viel schneller zu erkennen und zu verstehen.
– FredCooke
23. April 2014 um 0:01 Uhr
Armstärkste
Denken Sie daran, a for
Schleife ist im Wesentlichen eine Phantasie while
Schleife. Sie sind dasselbe.
while <some condition is true> {
// do some stuff
// possibly do something to change the condition
}
for ( some var, <some condition is true>; increment var ) {
}
Der Vorteil einer for-Schleife besteht darin, dass es schwieriger ist, versehentlich eine Endlosschleife auszuführen. Oder besser gesagt, es ist offensichtlicher, wenn Sie eine ausführen, weil Sie die Schleifenvariable im Allgemeinen in die anfängliche Anweisung einfügen.
EIN while
Schleife ist klarer, wenn Sie kein standardmäßiges inkrementierendes Muster ausführen. Zum Beispiel:
int x = 1;
while( x != 10 ) {
if ( some condition )
x = 10;
else
x += 5;
}
Ich weiß es nicht viel Einfacher. Ich würde vermuten, dass, wenn C nicht die erste Form hätte, wir uns alle inzwischen daran gewöhnt hätten, die zweite zu sehen.
– Café
2. Juni 2010 um 5:11 Uhr
Fair genug, aber ich garantiere, dass ich “WTF” denken würde, wenn ich die zweite Version in irgendeinem Code sehen würde, den ich pflege…
– Justin Ethier
2. Juni 2010 um 13:11 Uhr
Code sollte sich wie Prosa lesen, ersterer ist der natürlichen Sprache viel näher. Vielleicht nicht “viel einfacher”, aber sehr wahrscheinlich viel schneller zu erkennen und zu verstehen.
– FredCooke
23. April 2014 um 0:01 Uhr
abespalov
Sie sollten eine solche Schleife verwenden, die Ihren Bedürfnissen am besten entspricht. Zum Beispiel:
for(int i = 0; i < 10; i++)
{
print(i);
}
//or
int i = 0;
while(i < 10)
{
print(i);
i++;
}
Offensichtlich sieht in einer solchen Situation “für” besser aus als “während”. Und “do while” sollte verwendet werden, wenn einige Operationen bereits vor dem Moment durchgeführt werden müssen, in dem der Zustand Ihrer Schleife überprüft wird.
Entschuldigung für mein schlechtes Englisch).
Du hast die Bedingung vergessen
GOTO
Schleife. Während die Leute es nicht als Schleife betrachten, glaube ich, dass alle Schleifen im Wesentlichen zu bedingten GOTO-Schleifen kompiliert werden.– Armstärkste
1. Juni 2010 um 15:32 Uhr
Wird Rekursion nicht auch als Schleife betrachtet?
– Nyan
4. Juni 2010 um 5:10 Uhr
Wäre es nicht einfacher, einen Compiler zu schreiben, der in x86 eine einfache for-Schleife in den effizienteren kompiliert
loop
Anweisung (Subtraktion, Vergleich und Sprung in Einzelanweisung), als eine, die kompiliertwhile
in dieloop
Anweisung? kompilieren aktuelle Compilerfor
in einloop
überhaupt anleitung?– Ciro Santilli OurBigBook.com
6. Februar 2013 um 18:56 Uhr