For-Schleife soll warten



  • Und Einfachheit. Man muss den Code nicht unnötig kompliziert machen, nur um irgendeine fragwürdige Regel zu befolgen.



  • Ich nutze es gerne, um vor der eigentlichen Verarbeitung einen Test zu machen:

    while(getline(in,line))
    {
       if(line.count()==0) continue;
       if(line[0]=='#') continue;
       //erst hier die zeile ernsthaft anschauen
    }
    

    Konstrukte mit tiefer Verschachtelung

    while(getline(in,line))
    {
       if(line.count()!=0)
       {
          if(line[0]!='#')
          {
             //erst hier die zeile ernsthaft anschauen
          }
       }
    }
    

    mag ich da gar nicht. Zumal ein Umbasteln der Vortests grausam wird.

    Mit elseif und doNothing() würde es zur Not gehen, aber continue sieht hier auch aussagekräftiger aus.
    Man kann den ganzen Funktionskörper in eine Funktion auslagern und statt continue return verwenden. Ob das angemessen ist, muß man im Einzelfall entscheiden.

    Mit diesen Verschachtelungen habe ich mal was Lustiges erlebt. Hardware sollte angesteuert werden. Dauernd so hin-und-her-Protokollgeschichten, Bit setzen, auf Antwort warten, Wort schreiben, Bestätigung abwarten...
    Der Vorgänger hatte mit C sehr tief geschachtelt. Das war so grausam zu lesen, daß der Arbeitgeber mir verboten hatte, C zu nehmen. Ich solle doch lieber assembler schreiben.



  • while(getline(in,line))
    {
       if(line.count()!=0)
       {
          if(line[0]!='#')
          {
             //erst hier die zeile ernsthaft anschauen
          }
       }
    }
    

    lässt sich auch als

    while(getline(in,line))
    {
       if(line.count() && line[0]!='#')
       {
           //erst hier die zeile ernsthaft anschauen
       }
    }
    

    schreiben 😉



  • volkard schrieb:

    Mit diesen Verschachtelungen habe ich mal was Lustiges erlebt. Hardware sollte angesteuert werden. Dauernd so hin-und-her-Protokollgeschichten, Bit setzen, auf Antwort warten, Wort schreiben, Bestätigung abwarten...
    Der Vorgänger hatte mit C sehr tief geschachtelt. Das war so grausam zu lesen, daß der Arbeitgeber mir verboten hatte, C zu nehmen. Ich solle doch lieber assembler schreiben.

    Wenn Kompetenz auf unglaubliches Fachwissen trifft, passiert sowas. Und jetzt hast du ein tiefsitzendes psychisches Trauma und vermeidest jede Verschachtelung, weil du angst hast, dein (ehemaliger?) Arbeitgeber könnte kommen und dir C++ wegnehmen.



  • Eisflamme schrieb:

    HighLigerBiMBam schrieb:

    "break" lässt sich oft nicht vermeiden zu verwenden, aber bei "continue" reicht es aus einfach nur nichts zu machen, weshalb ich finde, es ist ein sinnloses goto mit anderem Namen 😉

    Also meine continues sind normalerweise nicht so einfach gestrickt, dass das gehen würde.

    Da es du bist, kann man annehmen, dass die Schleifen mehr als 50 Zeilen haben und der Code sowieso für die Tonne ist.



  • Mis2com?

    Mehr als 50 Zeilen selten. Und mein Code ist gut lesbar, kommentiert, performant und funktioniert. Wenn Du also Dinge von Qualität in die Tonne schmeißt, weiß ich ja Bescheid, wie es bei Dir aussieht. :p



  • Eisflamme schrieb:

    Mehr als 50 Zeilen selten. Und mein Code ist gut lesbar, kommentiert, performant und funktioniert.

    Hat das schon mal ein anderer als du bestätigt?
    Gerade vorher hast du noch übrigens behauptet deine continue wären kompliziert.



  • 314159265358979 schrieb:

    while(getline(in,line))
    {
       if(line.count()!=0)
       {
          if(line[0]!='#')
          {
             //erst hier die zeile ernsthaft anschauen
          }
       }
    }
    

    lässt sich auch als

    while(getline(in,line))
    {
       if(line.count() && line[0]!='#')
       {
           //erst hier die zeile ernsthaft anschauen
       }
    }
    

    schreiben 😉

    Jaja, wenn man Beispiele absichtlich nicht versteht...



  • Michael E. schrieb:

    Jaja, wenn man Beispiele absichtlich nicht versteht...

    Das musst du mir jetzt aber genauer erleutern.



  • Ein Beispiel soll dir lediglich einen Gedankenschubs in die richtige Richtung geben. Du kannst dir sicherlich, ausgehend von volkards Beispiel, Szenarien überlegen mit mehr als zwei Bedingungen, die etwas länger sind und nicht notwendigerweise hintereinanderstehen müssen, sodass man nicht einfach so alle Bedingungen übersichtlich in ein if bekommt.



  • Ob da nun steht:

    if(iwas) continue;
        // Code
    

    oder

    if(!iwas)
        // Code
    

    ist meiner Meinung nach relativ egal. Du kannst mir aber gerne ein Gegenbeispiel zeigen.



  • while(true)
    {
    	if(foo())
    		continue;
    	if(bar())
    	{
    		++counter;
    		continue;
    	}
    	if(bar())
    		continue;
    	baz();
    	baz();
    }
    
    while(true)
    {
    	if(!foo())
    	{
    		if(bar())
    			++counter;
    		else
    		{
    			if(!bar)
    			{
    				baz();
    				baz();
    			}
    		}
    	}
    }
    


  • Michael E. schrieb:

    while(true)
    {
    	if(foo())
    		continue;
    	if(bar())
    	{
    		++counter;
    		continue;
    	}
    	if(bar())
    		continue;
    	baz();
    	baz();
    }
    
    while(true)
    {
    	if(!foo())
    	{
    		if(bar())
    			++counter;
    		else
    		{
    			if(!bar)
    			{
    				baz();
    				baz();
    			}
    		}
    	}
    }
    

    Beides nichtssagend und hässlich



  • Haben die Funktionen Seiteneffekte?



  • 314159265358979 schrieb:

    Haben die Funktionen Seiteneffekte?

    Möglich.



  • Und jetzt zeig mir produktiven Code, wo sowas vorkommt.



  • Aus libbzip2:

    while (True) {
             /* try to finish existing run */
             while (True) {
                if (s->strm->avail_out == 0) return False;
                if (s->state_out_len == 0) break;
                *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
                BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
                s->state_out_len--;
                s->strm->next_out++;
                s->strm->avail_out--;
                s->strm->total_out_lo32++;
                if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
             }
    
             /* can a new run be started? */
             if (s->nblock_used == s->save_nblock+1) return False;
    
             /* Only caused by corrupt data stream? */
             if (s->nblock_used > s->save_nblock+1)
                return True;
    
             s->state_out_len = 1;
             s->state_out_ch = s->k0;
             BZ_GET_SMALL(k1); s->nblock_used++;
             if (s->nblock_used == s->save_nblock+1) continue;
             if (k1 != s->k0) { s->k0 = k1; continue; };
    
             s->state_out_len = 2;
             BZ_GET_SMALL(k1); s->nblock_used++;
             if (s->nblock_used == s->save_nblock+1) continue;
             if (k1 != s->k0) { s->k0 = k1; continue; };
    
             s->state_out_len = 3;
             BZ_GET_SMALL(k1); s->nblock_used++;
             if (s->nblock_used == s->save_nblock+1) continue;
             if (k1 != s->k0) { s->k0 = k1; continue; };
    
             BZ_GET_SMALL(k1); s->nblock_used++;
             s->state_out_len = ((Int32)k1) + 4;
             BZ_GET_SMALL(s->k0); s->nblock_used++;
          }
    


  • Was ist den das schreckliches? 😮 Sehr schön pseudomäsig Verschachtelungstiefen gespart: "if (k1 != s->k0) { s->k0 = k1; continue; };" Leserlichkeit 👎

    /* Only caused by corrupt data stream? */
             if (s->nblock_used > s->save_nblock+1)
                return True;
    

    Warum steht da ein Fragezeichen hinterm Kommentar? Waren die sich nicht sicher, dass das nur bei einem korrupten Stream passiert? Warum geben die dann True zurück?



  • continue ist auch deswegen übersichtlicher, weil man nicht noch schauen muss, ob nach dem if noch etwas passiert. Es wird klar gesagt: Hier macht eine Prüfung den weiteren Verlauf des Schleifenrumpfs unnötig. Das gefällt mir.

    Und was das Beispiel angeht: Wenn es sich anders schreiben lässt, ist das Beispiel eben nicht gut genug. Wer Beispiele bringt, hat die Bringschuld und darf nicht davon ausgehen, dass "der Sinn schon rüberkommt", denn dann kann man sich das Beispiel auch einfach schenken. So genau müssen wir im C++-Umfeld schon sein.



  • Gerade hab ich dieses Werk gebaut, und das hat mich an diesen Thread erinnert.

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    #include <cmath>
    
    using namespace std;
    
    int main()
    {
        srand(time(0));
        int punkte=0;
        while(punkte<100){
            int basis=rand()%10;
            int exponent=rand()%10;
            if(basis==0 && exponent==0)
                continue;
            int potenz=pow(basis,exponent);
            if(potenz>500)
                continue;
            cout<<basis<<'^'<<exponent<<'=';
            int tip;
            cin>>tip;
            if(tip==potenz){
                cout<<"richtig!\n";
                ++punkte;
            }
            else{
                cout<<"falsch!\n";
                punkte/=2;
            }
            cout<<"Punkte: "<<punkte<<'\n';
            cout<<"\n\n\n\n\n";
        }
        cout<<"Gewonnen!\n";
        return 0;
    }
    

    Die beiden continues finde ich schön.


Anmelden zum Antworten