Hallo, wenn ich innerhalb einer schleife ein return mache, wird dann nur die Schleife beendet oder die FUnktion?? void foo() { uint8_t i=0; while(i<10) { ... if(i == foo) return; } } Beende ich damit die Funktion? Oder nur die while? Jens
kurz noch ein guter Rat. return immer nur am Ende einer C-funktion. Natürlich kann es überall stehen, aber wenn es mal zum Fehlersuchen oder Laufzeitmessen kommt sind die ersten Probleme vorprogrammiert. Dieses versteckte return wird dann einfach übersehen. Ein guter Programierstil hat immer nur 1 return und das am Ende. JL
jl wrote:
> Ein guter Programierstil hat immer nur 1 return und das am Ende.
Wie würdest du folgendes realisieren:
Laderoutine für irgendeine Datei. fopen liefert NULL, also wird direkt
ein Fehler zurückgegeben. Meist sieht das dann so aus:
if (fp==NULL)
return -1;
Dann die eigentliche Laderoutine mit weiteren Fehlerabfragen und return
-2, -3 usw. und ganz am Ende:
return 0;
Das "return nur am Ende der Funktion" Dogma muss man sich gut überlegen. Da gibt es dann Experten, die verkomplizieren den Code durch eigentlich überflüssige Hilfsvariablen, weil sie unbedingt nur ein return am Ende der Funktion haben wollen. Das ist natürlich bullshit.
Returns vor dem Funktionsende sind (ähnlich wie Breaks und Continues) getarnte und und in ihren Möglichkeiten eingeschränkte Verianten des Gotos. Alle diese Anweisungen haben aber auch ihren Sinn, zumindest aus Sicht der Entwickler der Sprache C, sonst gäbe es sie nicht. Ob die Verwendung einer dieser Anweisungen guter oder schlechter Stil ist, hängt davon ab, welche Effizienz- oder Lesbarkeitseinbußen die Umgehung dieser Anweisungen nach sich ziehen würde, und wie Effizienz und Lesbarkeit im konkreten Programmteil gewichtet sind.
>Oder kurz ausgedrückt: Es ist Geschmackssache, wie so vieles!
So ist es... in Zeiten der objektorientierten Programmierung ist der
Ausstieg z.B. über Exceptions sogar durchaus üblich.
Ich versuche immer so schnell wie möglich aus der Funktion/Schleife
rauszukommen und vermeide damit unnötig tiefe Schachtelungen und zig.
Flags.
Muss natürlich entsprechend kommentiert werden, damit es lesbar bleibt.
Wird es doch zu unübersichtlich ist das eher ein Zeichen dafür, dass der
Code weiter zerlegt werden sollte.
Muss natürlich je nach Einzelfall entschieden werden.
Gibt ja auch Leute, die versuchen fußgesteuerte Schleifen, den ternären
Operator und +=, ^=, <<=, etc zu vermeiden/verbieten... man kann es sich
auch schwer machen.
Kai Giebeler wrote: >>Oder kurz ausgedrückt: Es ist Geschmackssache, wie so vieles! > > So ist es... in Zeiten der objektorientierten Programmierung ist der > Ausstieg z.B. über Exceptions sogar durchaus üblich. > und da kommt es wieder auf die Sprache an. In C++ sollte man es tunlichst vermeiden, reguläre Ausstiege mit exceptions zu machen, exceptions sollten da nur für Fehlerbehandlung verwendet werden....
Das mit den Exceptions war nur ein Beispiel für einen Ausstieg in der Mitte. Um Gottes Willen Exceptions nicht für den regulären Programmablauf verwenden - sonst hießen die ja nicht "Ausnahme".
> return immer nur am Ende einer C-funktion.
Macht oft den Code unnötig kompliziert. Ich prüfe oft am Anfang einer
Funktion die Vorbedingungen ab und kehre dann ggf. direkt mit einem
return zurück. Warum soll ich da den gesamten Funktionsinhalt in eine
Verschachtelung aus mehreren ifs stecken?
Was sieht einfacher übersichtlicher aus:
[C
file_id file_create(const char* name)
{
file_id ret;
if (name != NULL)
{
if (!file_id_pool_full())
{
if (!file_exists(name))
{
if (can_create(name))
{
// ok, create the file
ret = ...
}
else
{
ret = -1;
}
}
else
{
ret = -2;
}
}
else
{
ret = -3;
}
}
else
{
ret = -4;
}
return ret;
}
[/C]
oder
1 | file_id file_create(const char* name) |
2 | {
|
3 | // check all the preconditions
|
4 | |
5 | if (name == NULL) |
6 | return -4; |
7 | |
8 | if (file_id_pool_full()) |
9 | return -3; |
10 | |
11 | if (file_exists(name)) |
12 | return -2; |
13 | |
14 | if (!can_create(name)) |
15 | return -1; |
16 | |
17 | // ok, create the file
|
18 | return ... |
19 | }
|
> Dieses versteckte return wird dann einfach übersehen. Man könnte auch argumentieren, daß die Funktion zu lang bzw. zu komplex ist, wenn die returns dadurch so versteckt werden, daß man sie übersehen kann. > Returns vor dem Funktionsende sind (ähnlich wie Breaks und Continues) > getarnte und und in ihren Möglichkeiten eingeschränkte Verianten des > Gotos. > in Zeiten der objektorientierten Programmierung ist der Ausstieg z.B. > über Exceptions sogar durchaus üblich. Die sind in der Hinsicht eigentlich schlimmer als goto, da sie nicht nur direkt in der aktuellen Funktion selbst, sondern auch irgendwo anders in einer aufgerufenen Funktion geworfen werden können und entsprechend auch in irgendeinem Aufrufer gefangen werden können. Beim goto stehen Start und Ziel des Sprungs wenigstens in der selben Funktion, und sie sind zur Compilezeit festgelegt.
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.