Hallo, kann man in C eine while-Schleife auch mit "return" verlassen? Falls wichtig für die Frage, ich programmiere AVRs mit GCC/AVR-Studio.
TMG schrieb: > kann man in C eine while-Schleife auch mit "return" verlassen? ja, nur wird dabei nicht nur die schleife sondern auch die Funktion verlassen.
Wieso sollte man das tun wollen? Man kann doch auch einer while Schleife eine Abbruchbedingung mitgeben.
Chris K. schrieb: > Wieso sollte man das tun wollen? Man kann doch auch einer while Schleife > eine Abbruchbedingung mitgeben. Fehlerbeandlung?
1 | while( Bedingung ) { |
2 | |
3 | if ( fehler ) { |
4 | return -1; |
5 | }
|
6 | }
|
Aus dem C-Standard:
1 | 6.8.6.3 The break statement |
2 | Constraints
|
3 | 1 A break statement shall appear only in or as a switch body or loop body. |
4 | Semantics
|
5 | 2 A break statement terminates execution of the smallest enclosing switch or iteration statement. |
6 | |
7 | 6.8.6.4 The return statement |
8 | Constraints
|
9 | 1 A return statement with an expression shall not appear in a function whose return type is void. A return statement without an expression shall only appear in a function whose return type is void. |
10 | Semantics
|
11 | 2 A return statement terminates execution of the current function and returns control to its caller. A function may have any number of return statements. |
Wie aber schon richtig gesagt wurde, eine while-Schleife hat eine Abbruchbedingung. Sonst überleg dir ein anderes Konstrukt.
Chris K. schrieb: > Wieso sollte man das tun wollen? Man kann doch auch einer while Schleife > eine Abbruchbedingung mitgeben. Weil diese Abbruchbedingung zum Start des Schleifendurchgang noch nicht vorliegt?
Lars Schmitt schrieb: > Sonst überleg dir ein anderes Konstrukt. warum sollte er da machen? return ist durchaus sinnvoll zu Fehlerbehandlung!
foobar schrieb: > Weil diese Abbruchbedingung zum Start des Schleifendurchgang noch nicht > vorliegt? Dann wäre wohl eine do-while-Schleife angebrachter.
Peter II schrieb: > warum sollte er da machen? return ist durchaus sinnvoll zu > Fehlerbehandlung! Na klar. Aber wir sollen wir durch unsere Glaskugeln überhaupt wissen was er möchte. Grundsätzlich lautet die Antwort auf die Frage: > kann man in C eine while-Schleife auch mit "return" verlassen? ein einfaches "ja".
Fred R. schrieb: > While > Goto Outside > Do > > Outside: WÜRG. Bitte ganz schnell vergessen, oder Assembler programmieren. @TMG: Dir fehlt ein gutes C Buch, das du auch lesen musst. Das sind die absoluten Basics. Um Schleifen zu beenden oder in den nächsten Durchlauf zu springen gibt es zwei Schlüsselwörter: "break" und "continue". Die müssen sitzen. Ja und in einer Funktion kann man auch mit return aus einer Schleife. Das beendet aber nicht nur die Schleife, sondern die ganze Funktion.
Frank M. schrieb: > Dann wäre wohl eine do-while-Schleife angebrachter. Vieleicht war es ja auch eine for Schleife. Manchmal ist die Welt auch grau und nicht nur schwarz und weiß :-)
Peter II schrieb: > return ist durchaus sinnvoll zu > Fehlerbehandlung! Oder um ein eine Schleife per Switch verlassen zu können. Oder verschachtelte Schleifen.
Danke für die vielen Antworten! Der Andere schrieb: > "break" und "continue". > > Die müssen sitzen. > > Ja und in einer Funktion kann man auch mit return aus einer Schleife. > Das beendet aber nicht nur die Schleife, sondern die ganze Funktion. Danke, das beantwortet meine Frage!
Chris K. schrieb: > while Schleife > eine Abbruchbedingung mitgeben. Nein, kann man nicht! Schleifen in C/C++ haben (per se) keine Abbruchbedingung! Es sind immer Laufbedingungen! Bei Schleifen (in C/C++) heisst es immer : Laufe solange wie... Und nicht: Breche ab wenn... Das ist ein wesentlicher Unterschied. Auch wenn jeder hier vermutlich weiss was gemeint ist, so bleibt es trotzdem falsch. Eine Abbruchbedinung hat man z.B. bei einer do-until-Schleife wie es sie in VBA gibt. Eine Abbruchbedingung kann man nur kuenstlich erzeugen durch ein if(...) break;
Kaj schrieb: > Chris K. schrieb: >> while Schleife >> eine Abbruchbedingung mitgeben. > Nein, kann man nicht! Schleifen in C/C++ haben (per se) > keine Abbruchbedingung! Es sind immer Laufbedingungen! > > Bei Schleifen (in C/C++) heisst es immer : Laufe solange wie... > Und nicht: Breche ab wenn... Und diese Haarspalterei hilft niemandem, der einzige Unterschied ist nämlich die Negierung.
Ich bin jetzt kein C Entwickler, aber in anderen Sprachen gibt es das auch das man aus einem while frühzeitig raus will. Am einfachsten ist das wohl so zu lösen:
1 | int i = 0; |
2 | int cancel = 0; |
3 | |
4 | while (i < 100 && cancel == 0) |
5 | {
|
6 | printf("%i ", i); |
7 | i++; |
8 | |
9 | if (i == 50) |
10 | cancel = 1; |
11 | }
|
Martin schrieb: > Am einfachsten ist > das wohl so zu lösen: ganz bestimmt nicht. Einfach ist ein break.
1 | int i = 0; |
2 | while (i < 100 ) |
3 | {
|
4 | printf("%i ", i); |
5 | i++; |
6 | |
7 | if (i == 50) |
8 | break; |
9 | }
|
Peter II schrieb: > ganz bestimmt nicht. Einfach ist ein break. Eben, ausserdem ist Martins "cancel" Beispiel auch noch beliebig falsch, da der Schleifenkörper nicht an dem Punkt abgebrochen wird, sondern bis zum Anfang des nächsten Durchlaufs weiterläuft. Das kann je nachdem was hinter dem "cancel = 1" noch an Code steht beliebig falsch sein.
Der Andere schrieb: > Das kann je nachdem was hinter dem "cancel = 1" noch an Code steht > beliebig falsch sein. Naja, wenn aber der Rest der Schleife doch noch durchlaufen werden soll, kann man das mit der Cancel-Variablen so machen. Einfacher wäre jedoch dann ein "i = 100;" gewesen ;-)
:
Bearbeitet durch Moderator
Aus so einer while-Schleife kommt man nur raus, wenn man fristgerecht kündigt, sonst bleibt man ein weiteres Jahr drin.
TMG schrieb: > kann man in C eine while-Schleife auch mit "return" verlassen? Ja, wird so gemacht, wenn der Code nach der Schleife nicht mehr gebraucht wird. ZB bei strchr: char* strchr(char *s,char c){ while(*s){ if (*s==c)return s; s++; } return NULL; }
Fred R. schrieb: > While > Goto Outside > Do > > Outside: Persönlich finde ich das die schlimmste Methode. Sehr unübersichtlich wenn der Code größer wird und vor allem glaube ich wird bei dieser Methode nicht aufgeräumt, richtig? Also würden die innerhalb der Schleife angelegten temporären Variablen nicht nicht wieder gelöscht und für ehwig im Speicher verweilen. Oder täusche ich mich da jetzt?
Lu schrieb: > Also würden die innerhalb der Schleife angelegten temporären Variablen > nicht nicht wieder gelöscht und für ehwig im Speicher verweilen. Oder > täusche ich mich da jetzt? ja, du täuscht dich. Aufgeräumt wird immer.
Kaj schrieb: > Chris K. schrieb: >> while Schleife >> eine Abbruchbedingung mitgeben. > Nein, kann man nicht! Schleifen in C/C++ haben (per se) > keine Abbruchbedingung! Es sind immer Laufbedingungen! Korinthen kacken kann ich auch: Deine Aussage ist Unsinn, da es gar keine Sprache namens "C/C++" gibt. Es gibt aber die Sprache C und die Sprache C++, für die das gesagte gleichermaßen gilt. Ich sag ja auch nicht "Eine Kuh/Katze hat vier Beine". > Eine Abbruchbedingung kann man nur kuenstlich erzeugen durch > ein if(...) break; Was verstehst du unter "künstlich erzeugt"? Es ist doch praktisch die wörtliche Entsprechung von: > Breche ab wenn...
Der Andere schrieb: > Eben, ausserdem ist Martins "cancel" Beispiel auch noch beliebig falsch, > da der Schleifenkörper nicht an dem Punkt abgebrochen wird, sondern bis > zum Anfang des nächsten Durchlaufs weiterläuft. > Das kann je nachdem was hinter dem "cancel = 1" noch an Code steht > beliebig falsch sein. Ein bisschen Kreativität muss da jeder schon noch selber mitbringen. War ja original kein Code vorgeben. Peter II schrieb: > ganz bestimmt nicht. Einfach ist ein break. ja in Sprachen in es dieses Feature gibt schon Frank M. schrieb: > Einfacher wäre > jedoch dann ein "i = 100;" gewesen ;-) Einfacher ja, aber zumindest etwas was ich bei einem Review so nicht durchlassen würde (weder maintainable noch intuitiv)
Auch wenn sie in Einzelfällen ihre Berechtigung haben, sind Programmsprünge mit break, continue oder goto in der Regel schlechter Programmierstil.
Rüdiger schrieb: > Auch wenn sie in Einzelfällen ihre Berechtigung haben, sind > Programmsprünge mit break, continue oder goto in der Regel schlechter > Programmierstil. das ist doch Unsinn. bei goto kann man sich ja noch streiten aber break und continue sind üblich und werden auch ständig gebraucht.
Rüdiger schrieb: > Auch wenn sie in Einzelfällen ihre Berechtigung haben, sind > Programmsprünge mit break, continue oder goto in der Regel schlechter > Programmierstil. break und continue sind genau dafür da, Schleifen zu verlassen oder abzukürzen. Was nimmt 'guter Programmierstil' stattdessen?
Ich würde es mal so formulieren: Wenn man ohnehin schon den Bad-Style-Fail gemacht hat einen Schleifenrumpf auf mehrere Bildschirmseiten Code auszudehnen, dann haut man mit continues und breaks dem Fass den Boden endgültig weg. Da blickt dann niemand mehr durch, wann und wo die Schleife durchlaufen oder abgebrochen wird. Bei einem übersichtlich kompakten Rumpf hingegen gewinnt man nichts an Lesbarkeit, wenn man syntaktische Verrenkungen macht nur um Teufel-komm-raus contiues oder breaks zu vermeiden. Da ist ein break jederzeit besser als zusätzliche Abbruchvariablen oder -bedingungen.
TMG schrieb: > kann man in C eine while-Schleife auch mit "return" verlassen? ja aber sollte man nicht, wie gesagt wurde break; TMG schrieb: > ich programmiere AVRs mit GCC/AVR-Studio. echt? oder nur C & P? break sollte man aber schon kennen.
Joachim B. schrieb: > TMG schrieb: >> kann man in C eine while-Schleife auch mit "return" verlassen? > > ja aber sollte man nicht, wie gesagt wurde break; und wie schon oft gesagt, warum sollte man das nicht? Ich habe oben schon ein Beispiel gebracht das es zur Fehlerbehandlung sehr sinnvoll ist.
Hm, ich merke gerade, dass ich zu wenig gotos verwende. Ich hätte auch mit break und return geantwortet. Aber das goto ist ja richtig klasse: Retro-Style, wie damals in den 80ern. Zu NDW und Space Invaders gehört auch ein richtigen goto.
Rüdiger schrieb: > Auch wenn sie in Einzelfällen ihre Berechtigung haben, sind > Programmsprünge mit break, continue oder goto in der Regel schlechter > Programmierstil. Dann wünsche ich viel Spass bei der Suche nach dem Bug, weil jemand bei einer switch/case Anweisung das break vergessen hat. Sowas hat mich schon Tage gekostet. break ist genau dafür gedacht, um eine Schleife vorzeitig zu verlasse (wenn die Abbruchbedingung noch nicht erfüllt ist). Das hat weder mit schlechtem Stil noch mit Unwissenheit zu tun. Grüsse, René
Kurt schrieb: > ... einen Schleifenrumpf auf mehrere > Bildschirmseiten Code auszudehnen, dann haut man mit continues und > breaks dem Fass den Boden endgültig weg. Da blickt dann niemand mehr > durch, wann und wo die Schleife durchlaufen oder abgebrochen wird. Das kann nur jemand schreiben, der niemals mit größeren Code-Basen zutun hatte. Allen Lehrbuch-, Misra- oder SIL-Regeln zum Trotz kann man komplexe Aufgaben (in C), die z.B. 1Mio Codezeilen erfordern, nicht sinnvoll so auf LIBs, Files und Funktionen verteilen, dass McCabe-Zahlen ein-oder zweistellig bleiben. > Bei einem übersichtlich kompakten Rumpf hingegen gewinnt man nichts an > Lesbarkeit, wenn man syntaktische Verrenkungen macht nur um > Teufel-komm-raus contiues oder breaks zu vermeiden. Da ist ein break > jederzeit besser als zusätzliche Abbruchvariablen oder -bedingungen. Wenn das schon bei kleinem Code stimmt... umso wichtiger ist es bei großem Code, d.h. ein einheitlicher Einsatz dieser (und anderer) Sprachmittel. Man darf (und sollte) also break oder return in 10.000-Zeilen-Funktionen ruhig verwenden, nur nicht in "unüblicher" Weise. Wenn 1000 aufeinanderfolgende case: mit break enden, sollte kein unerwartetes return darunter sein und vice versa. Nochwas zu großem Code: Die Anzahl der Zeilen ist natürlich kein hinreichendes Kriterium. 1000 unabhängige Teilprozesse von je 1000 Codezeilen sind natürlich so sauber zu programmieren wie ein Miniprojekt von 1000 Zeilen (also grob 10 C-Files a 10 Funktionen a 10 Zeilen wie im Lehrbuch)
Kurt schrieb: > Ich würde es mal so formulieren: Wenn man ohnehin schon den > Bad-Style-Fail gemacht hat einen Schleifenrumpf auf mehrere > Bildschirmseiten Code auszudehnen, dann haut man mit continues und > breaks dem Fass den Boden endgültig weg. Da blickt dann niemand mehr > durch, wann und wo die Schleife durchlaufen oder abgebrochen wird. Genau da, wo break bzw continue steht. Wo sonst? Und die Funktion wird da beendet, wo return steht. Ein Problem?
Joachim B. schrieb: > TMG schrieb: >> kann man in C eine while-Schleife auch mit "return" verlassen? > > ja aber sollte man nicht, wie gesagt wurde break; Warum sollte man nicht, wenn der Rest der Funktion nicht mehr gebraucht wird? break ist kein Ersatz für return, break verlässt die Schleife, return die Funktion.
Thomas S. schrieb: > schau mal hier. > http://www.peacesoftware.de/ckurs11.html dort steht aber nicht von einem return? Was soll es ihn dann helfen?
Da steht wie man eine while-Schleife verlassen kann. Andere Möglichkeiten gibt es glaube ich nicht.
Thomas S. schrieb: > Da steht wie man eine while-Schleife verlassen kann. > > Andere Möglichkeiten gibt es glaube ich nicht. doch, nämlich return.
sorry, hab ich falsch verstanden. Ich dachte es soll die Schleife verlassen werden und nicht gleich die ganze die Funktion.
Thomas S. schrieb: > sorry, hab ich falsch verstanden. Ich dachte es soll die Schleife > verlassen werden und nicht gleich die ganze die Funktion. wenn die Funktion verlassen wird, wird auch die schleife verlassen.
natürlich. alles klar. Dann kann man ja auch gleich das ganze Programm beenden. Da wird die Schleiffe auch verlassen.
Thomas S. schrieb: > schau mal hier. > http://www.peacesoftware.de/ckurs11.html Was ist das denn für ein schlechtes Tutorial?
@ Wilhelm M. Also ich hatte keine Probleme mit diesem Tutorial-Ausschnitt. Weiter hab ich nichts überprüft. Nicht meine Aufgabe.
Thomas S. schrieb: > @ Wilhelm M. > Also ich hatte keine Probleme mit diesem Tutorial-Ausschnitt. > > Weiter hab ich nichts überprüft. Nicht meine Aufgabe. Folgendes fiel mir sofort auf:
1 | int i, x = 55; // i ist uninitialsiert |
2 | double x; // x ist schon als int deklariert , wird nicht initialisiert. |
3 | |
4 | for(i = 100; i > -x; i--) // i besser innerhalb definieren, x ist nicht initialiert (s.o.) |
5 | {
|
6 | // ...
|
7 | }
|
Dann habe ich aufgehört zu lesen ...
:
Bearbeitet durch User
Da hast Du recht. Bei sowas nutzt kein break und auch kein return. Aber ... wir sind alle nur menschen ... Gruß aus Spandau
Wilhelm M. schrieb: > Folgendes fiel mir sofort auf: > int i, x = 55; // i ist uninitialsiert > double x; // x ist schon als int deklariert , wird nicht initialisiert. > > for(i = 100; i > -x; i--) // i besser innerhalb definieren, x ist nicht > initialiert (s.o.) > { > // ... > } Die doppelte Verwendung von x ist Murks. Doch ist es Ansichtssache, wo man definiert und wo man initialisiert. Ich bevorzuge alle Definitionen am Anfang einer Funktion und Initialisierung kurz vor Gebrauch.
Thomas S. schrieb: > Da hast Du recht. > Bei sowas nutzt kein break und auch kein return. > > Aber ... wir sind alle nur menschen ... > > Gruß aus Spandau Noch ne andere Stelle daraus: "Wie man sieht, wurde die Variable ' x' in der aurufenden Funktion verändert, die Adresse der Variablen x wird mit dem Kaufmannns-und in die Funktion FunktionMitPointer(&x); hineingegeben und dort mit dem * Operator dereferenziert und verändert. Weil man hier nicht die Variable sondern die Referenz, die Adresse der Variablen, übergibt nennt sich das ganze Call By Reference." Call-by-reference ist Quatsch! Wenn solche Sachen durch solche schlechten Tutorials verbreitet werden, ist das wirklich schlecht.
Wilhelm M. schrieb: > Noch ne andere Stelle daraus: > > "... in der aurufenden Funktion ..." Ja, sogar die arme Funktion schreit vor Schmerzen ;-)
Wilhelm M. schrieb: > Call-by-reference ist Quatsch! Das ist es tatsächlich nicht, auch wenn es in C++ explizit das Konstrukt der Referenz gibt.
Fred R. schrieb: > While > Goto Outside > Do > > Outside: Ein goto kann durchaus sehr übersichtlichen Code erlauben, wenn es gefühlte 100 Kriterien gibt und man alles an einer Stelle behandeln möchte. z.B. eine Fehlerausgabe oder so. Aber ich würde es auch sparsam einsetzen, nur da, wo es wirklich sehr der Übersichtlichkeit dient oder den Code sehr vereinfacht. Ansonsten würde ich in diesem Fall auch break verwenden um die Schleife zu verlassen oder return, wenn man auch gleich die Funktion verlassen will.
Rufus Τ. F. schrieb: > Wilhelm M. schrieb: >> Call-by-reference ist Quatsch! > > Das ist es tatsächlich nicht, auch wenn es in C++ explizit das Konstrukt > der Referenz gibt. Technisch gesehen ist das eine Parameterübergabe per-value, weil in Zeigerwert kopiert(!) wird.
Wilhelm M. schrieb: > Technisch gesehen ist das eine Parameterübergabe per-value, weil in > Zeigerwert kopiert(!) wird. wenn es geinlined wird, muss gar nicht kopiert werden.
Peter II schrieb: > Wilhelm M. schrieb: >> Technisch gesehen ist das eine Parameterübergabe per-value, weil in >> Zeigerwert kopiert(!) wird. > > wenn es geinlined wird, muss gar nicht kopiert werden. Darum geht es doch gar nicht ...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.