Genaue Auswertung for-schleife



  • Hallo,

    ist es richtig dass die genaue auswertung einer normalen forschleife zuerst das inkrementieren des zählers ist, dann überprüft wird ob die bedingung gilt und erst dann weitergemacht wird?

    Was passiert denn bei sowas:

    for(int i = 0; i < 5 && b > 0; i++)
    {
         if(something happened) b = 0;     
    }
    

    danke euch 🙂



  • also wird beim zweiten zuerst die bedingung i oder b geprüft?



  • for(int i = 0; i < 5 && b > 0; i++)
    {
         if(something happened) b = 0;     
    }
    

    ist

    {//i lokal zur schleife machen
    int i = 0;//vor dem ersten lauf initialisieren
    while( i < 5 && b > 0 )//solange die bedingung erfüllt ist
    {
         if(something happened) b = 0;     
    einsprungpunktFürContinue:;
         i++;
    }
    einsprungpunktFürBreak:;
    }
    


  • Vor dem ersten Schleifendurchlauf wird zuerst i initialisiert und dann die Bedingung (von links nach rechts unter Berücksichtigung der Operatorprioriäten und unter Verwendung von lazy evaluation (http://de.wikipedia.org/wiki/Kurzschlussauswertung)) ausgewertet. Vor jedem weiteren Durchlauf wird erst die Inkrementierung durchgeführt und dann die Bedingung geprüft.



  • vielen dank ! 👍



  • 🙂 noch eine zusatzfrage: Was passiert wenn ich mehrere inkrementierungen mache:

    for(int i = 0; c = 0; i < 5 && b>0;i++;c++)
    

    ich vermute es werden dann zuerst alle inkrementierungen gemacht und dann alle bedingungen geprüft...?


  • Mod

    volkard schrieb:

    for(int i = 0; i < 5 && b > 0; i++)
    {
         if(something happened) b = 0;     
    }
    

    ist

    {//i lokal zur schleife machen
    int i = 0;//vor dem ersten lauf initialisieren
    while( i < 5 && b > 0 )//solange die bedingung erfüllt ist
    {
         if(something happened) b = 0;     
    einsprungpunktFürContinue:;
         i++;
    }
    einsprungpunktFürBreak:;
    }
    

    Ganz streng kluggeschissen ist es:

    {//i lokal zur schleife machen
      int i = 0;//vor dem ersten lauf initialisieren
      while( i < 5 && b > 0 )//solange die bedingung erfüllt ist
      {
         {
           if(something happened) b = 0;
         }
    einsprungpunktFürContinue:;
       i++;
      }
    einsprungpunktFürBreak:;
    }
    

    Ich glaube aber nicht, dass es eine sinnvolle Anwendung gibt, die die eine oder die andere Variante ausnützen würde.


  • Mod

    glasxy schrieb:

    🙂 noch eine zusatzfrage: Was passiert wenn ich mehrere inkrementierungen mache:

    for(int i = 0; c = 0; i < 5 && b>0;i++;c++)
    

    ich vermute es werden dann zuerst alle inkrementierungen gemacht und dann alle bedingungen geprüft...?

    Du musst die Inkrementierungen mit Komma trennen. Und es passiert genau das was volkard und ich geposted haben:

    for(int i = 0, c = 0; i < 5 && b>0;i++,c++) {irgendwas;}
    

    entspricht:

    {
      int i = 0,  c = 0;
      while( i < 5 && b > 0 )
      {
         {
           irgendwas;
         }
    einsprungpunktFürContinue:;
       i++,c++;
      }
    einsprungpunktFürBreak:;
    }
    


  • glasxy schrieb:

    🙂 noch eine zusatzfrage: Was passiert wenn ich mehrere inkrementierungen mache:

    for(int i = 0; c = 0; i < 5 && b>0;i++;c++)
    

    ich vermute es werden dann zuerst alle inkrementierungen gemacht und dann alle bedingungen geprüft...?

    Dein Code ist syntaktisch falsch, der Header einer For-Schleife muss genau zwei Strichpunkte enthalten.

    Du meinst wohl folgendes (mit Komma):

    for (int i = 0, c = 0; i < 5 && b > 0; i++, c++)
    

    Ja, in diesem Fall wird zuerst i++, dann c++ ausgewertet (ganz nach den Gesetzen von operator, ). Im Initialisierungs- und Aktualisierungsteil der For-Schleife spielt der Wert des Ausdrucks keine Rolle, steht allerdings im Bedingungsteil ein Ausdruck mit Komma-Operator, so werden zwar alle Teilausdrücke ausgewertet (im Sinne von Seiteneffekten), aber nur der letzte ist relevant für die Laufbedingung der Schleife.

    for (int i = 0; i != 0, i < 5; ++i) // ist äquivalent zu
    for (int i = 0; i < 5; ++i)
    

    Allerdings habe ich das noch nie gebraucht, sowas macht wohl in nahezu keinem Fall Sinn. Nur fürs Verständnis des Komma-Operators... 😉



  • SeppJ schrieb:

    Ich glaube aber nicht, dass es eine sinnvolle Anwendung gibt, die die eine oder die andere Variante ausnützen würde.

    Sehe ich ähnlich. Unm den Effekt zu sehen, mußte der Schleifenkörper eine Variable initialisieren, ohne daß der Schleifenkörper eigene Blockklammern hat.

    for(int i=0;i!=10;++i)
       int i=fooWichtig();//Compilerwarung "unused result" unterdrücken
       //mist, jetzt hab ich "unused variable"
    

    Aber ich habe in letzter Zeit öfters mal verschachtelte Schleifen gehabt, die den selben Variablennamen für die Laufvariable hatten. 🤡


Anmelden zum Antworten