Forum: Compiler & IDEs Return in Schleife


von Jens (Gast)


Lesenswert?

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

von Benedikt K. (benedikt)


Lesenswert?

break beendet die Schleife, return immer die ganze Funktion.

von jl (Gast)


Lesenswert?

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

von Benedikt K. (benedikt)


Lesenswert?

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;

von ... (Gast)


Lesenswert?

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.

von yalu (Gast)


Lesenswert?

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.

von sous (Gast)


Lesenswert?

Oder kurz ausgedrückt: Es ist Geschmackssache, wie so vieles!

von Kai G. (runtimeterror)


Lesenswert?

>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.

von Bernhard M. (boregard)


Lesenswert?

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....

von Kai G. (runtimeterror)


Lesenswert?

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".

von Rolf Magnus (Gast)


Lesenswert?

> 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
Noch kein Account? Hier anmelden.