Ablauf in einer geschachtelten for Schleife



  • Ich fange gerade an, C++ aus "C++ lernen und professionel anwenden", zu lernen. Darin befindet sich folgendes Programm:

    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    int main()
    {
    	long euro, maxEuro;			//Euro-Beträge
    	double kurs;				//Euro/Dollar-Kurs
    
    	cout << "\n* * *Wechselkurstabelle € - US-$* * *\n\n";
    	cout << "\nBitte den Wechselkurs eingeben: ";
    	cin  >> kurs;
    	cout << "\nBis wieviel € wollen sie umrechnen lassen? ";
    	cin  >> maxEuro;
    
    			//---------Ausgabe der Tabelle----------
    
    	cout << "\n\n"
    	     << setw(12) << "EURO" << setw(20) << "US-$" << setw(12)
                  << "Kurs\n" << endl;
    
    	cout << fixed << setprecision(2);
    
    	long lower, upper, step;
    
    	for( lower=1, step=1; lower<=maxEuro; step*=10, lower=2*step)
    	     for( euro=lower, upper=step*10; euro<=upper && euro<=maxEuro;
                                                                      euro+=step)
    	cout << setw(12) << euro << setw(20) << euro*kurs << endl;
    	return 0;
    }
    

    Das Prog berechnet den Wert des Dollars zunächst in 1er Schritten (von1-9) und dann in 10er Schritten (von 10-90) dann in Hunderterschritten bis "maxEuro" erreicht ist.

    Ich verstehe wie er auf den ersten Wert von "euro" kommt, da lower im ersten durchgang ja noch 1 ist. Am Ende des ersten durchlaufs wird ja dann aber der Ausdruck3 (step*=10, lower=2*step) ausgeführt. Wenn ich das so nachrechne müsste dann ja "step" den Wert 10 haben und "lower" den Wert 20 haben. Damit hätte dann in der inneren for Schleife euro den Wert 20 (da "euro = lower").

    Ich weiss dass mein Gedankengang da falsch ist, aber warum. Das lässt mir keine Ruhe und ich kann nicht weitermachen bevor ich das nicht begriffen habe.

    Danke schon mal im voraus für die Antworten.



  • Nein, dein Gedankengang ist richtig - im zweiten Durchlauf beginnt die Schleife mit euro=20. Die Ausgabe 10 stammt aus der letzten Runde des ersten Schleifendurchlaufs.



  • Aber wieso gibt dann das Programm die Umrechnung von 1 euro, 2 euro, 3 euro usw. bis 9 euro aus. Danach dann 10 euro, 20 euro, 30 euro usw...

    Nach meiner rechnung müsste er ja 1 euro umrechnen, dann 20 euro usw.

    Welche reinitialisierung wird denn nach der Beendigung der Schleife zuerst gemacht, (step*=10, lower=2*step) oder (euro+=step).

    Im Buch steht auch: " Ein Ausdruck mit dem Kommataoperator hat wie jeder Ausdruck in C++ einen Typ und einen Wert. Dies ist der Typ und Wert des letzten, durch Komma getrennten Ausdrucks."

    Verstehe ich das richtig, dass bei dem Ausdruck (step*=10, lower=2*step) die berechnung step*=10 nur innerhalb dieses Ausdrucks gilt und nicht reinitialisiert wird?



  • Zyx schrieb:

    Im Buch steht auch: " Ein Ausdruck mit dem Kommataoperator hat wie jeder Ausdruck in C++ einen Typ und einen Wert. Dies ist der Typ und Wert des letzten, durch Komma getrennten Ausdrucks."

    Verstehe ich das richtig, dass bei dem Ausdruck (step*=10, lower=2*step) die berechnung step*=10 nur innerhalb dieses Ausdrucks gilt und nicht reinitialisiert wird?

    Nein, da steht nur dass der Typ des Klammerausdrucks der Typ des letzten Wertes ist (also long), und der Wert des Klammerausdrucks der letzte Wert selbst (also lower=2*step), nicht dass die anderen Werte in der Klammer nicht ausgewertet werden.

    Welche reinitialisierung wird denn nach der Beendigung der Schleife zuerst gemacht, (step*=10, lower=2*step) oder (euro+=step)

    Die zweitere wird beim Beenden der inneren Schleife gemacht, die erstere bei Beendigung der äusseren Schleife. Und jetzt darfst Du raten welche zuerst beendet wird :p



  • Na dann würd ich ja mal raten die innere wird zuerst reinitialisiert, dann die äußere, richtig?

    Soweit so gut, nur ich verstehe immer noch nicht wie beim zweiten durchlauf der schleifen euro=2 rauskommen kann. Nach meiner Rechnung würde da wie gesagt 20 rauskommen.

    Erster durchlauf: (maxEuro=100)

    for( lower=1, step=1; lower<=maxEuro; step*=10, lower=2*step)
           1         1          true         erst am ende
    
    for( euro=lower, upper=step*10; euro<=upper && euro<=maxEuro; euro+=step)
         euro = 1    upper= 1*10       true     &&    true          euro=1+1
    
    cout << setw(12) << euro << ...
                         1    
    
    dann reinitialisierung äußere for-Schleife: ...step*=10, lower=2*step)
                                                   step=1*10,lower=2*10=20
    
    Zweiter durchlauf:
    
    for( lower=1, step=1; lower<=maxEuro; step*=10, lower=2*step)
                           20<=100(true)     erst am ende
    
    for( euro=lower, upper=step*10; euro<=upper && euro<=maxEuro; euro+=step)
    

    💡
    Hehe, ich glaub beim schreiben hab ichs gerafft. Jetzt wird ja Ausdruck1 (euro=lower, upper=step*10;...) nicht mehr neu initialisiert also hat euro noch immer den wert 2 aus der reinitialisierung der inneren schleife vom ersten durchlauf, richtig? Nun aber das nächste problem. step hat doch schon im zweiten durchlauf den wert 10 (weil:...; step*=10, lower=2*step) . Wenn dann die innere for-Schleife am Ende reinitialisiert wird dann ist doch (...; euro+=step) euro=2+10=12 und das kann ja nicht stimmen. 👎

    Vielleicht kann mir ja mal jmnd den genauen Ablauf dieser beiden schleifen schritt für schritt schildern, bin sicher dann würd ich es verstehen. 👍



  • So, der Spruch:"Schlaf mal ne Nacht drüber." hat für mich ne ganz neue Bedeutung bekommen... 🙂

    Es muss dann ja so sein:

    Als erstes wird die äußere Schleife einmal durchlaufen aber nicht reinitialisiert, bis die innere schleife 10x durchlaufen wurde; also solange euro<=10. Dann wird die äußere reinitialisiert worauf sich step auf 10 erhöht. Dann wird die innere wieder 10x durchlaufen usw...

    Juhuu! Ich sag euch, das ist mal ein erfolgserlebnis für mich bei c++. Danke für die Hilfe auf jeden Fall und danke auch für den raum zum nachdenken in euren posts. Ich glaub mir hätte die Lösung dieses Problems nicht halb soviel gebracht hätte ich den ablauf nicht selbst vertanden!


Anmelden zum Antworten