For-Schleife soll warten



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



  • müsste das nicht if(basis==0 || exponent==0) heissen? Das erste finde ich überflüssig - ich würde eher beide rand() 's anpassen auf rand()%10+1; . Das zweite ist ok, ich empfinde ein continue meist schöner als das if-pendant da ich dann (gedanklich, debuggend) zum Schleifenkopf zurückspingen kann - beim einer gleichwertigen if () { /* ... */ } muss ich erst das Ende suchen und dort schaun ob noch was passiert.



  • padreigh schrieb:

    müsste das nicht if(basis==0 || exponent==0) heissen?

    Warum? Er nimmt nur den nicht einheitlich definierten Fall 0^0 raus.

    Das erste finde ich überflüssig - ich würde eher beide rand() 's anpassen auf rand()%10+1; .

    Geht nicht, wenn lediglich 0^0 verhindert werden soll.



  • volkard schrieb:

    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.

    Auch nur, weil das ganze ein Minispiel ist, das total in sich verstrickt ist und Modularisierung sich nicht lohnt.



  • Ich hab mir sagen lassen, dass sich auch große Projekte in viele kleine Mini-"Projekte" zerlegen lassen, bei denen sich Modularisierung nicht lohnt...



  • mmmmmmmmmmmmmm schrieb:

    Auch nur, weil das ganze ein Minispiel ist, das total in sich verstrickt ist und Modularisierung sich nicht lohnt.

    Ja, absolut.
    Wäre das Programm größer, oder sollte es länger leben oder mal ausgebaut werden oder sowas, dann wäre die frage() längst ausgelagert. In ernsthaften Projekten würde ich mehr auf funktionale Zerlegung achten:

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

Anmelden zum Antworten