www.mikrocontroller.net

Forum: Compiler & IDEs Return in Schleife


Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
break beendet die Schleife, return immer die ganze Funktion.

Autor: jl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: sous (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder kurz ausgedrückt: Es ist Geschmackssache, wie so vieles!

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bernhard M. (boregard)
Datum:

Bewertung
0 lesenswert
nicht 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....

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht 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".

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
file_id file_create(const char* name)
{
   // check all the preconditions

   if (name == NULL)
       return -4;

    if (file_id_pool_full())
       return -3;

    if (file_exists(name))
       return -2;

    if (!can_create(name))
       return -1;

    // ok, create the file
    return ...
}

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.