Der Quelltext mit den lustigen Lottozahlen.



  • Guten Morgen,

    bearbeite gerade, viel zu lange, eine dieser C++ Aufgaben, (hoffentlich wird man mit der Zeit schneller, da der Anfang um einiges zeitintensiver ist als ich es angenommen habe), dabei wollte ich eine Beobachtung von euch bestätigen lassen.

    Hier ist erstmal ein Abschnitt von dieser Aufgabe :

    #include <iostream>
    #include <cstdlib>
    using namespace std;
    
    const int KugelZahl = 6;
    const int MaxZahl = 49; // Maximale Anzahl der sortierten Zahlen
    
    int main()
    {
        int lotto[KugelZahl];
        int i, j;
        int hilf;
        bool neueZahl;
    
        srand(time(0)); //Mische einmal durch!
        //Ermittle sechs Lottozahlen
        [b]for(i=0; i<KugelZahl; i++)[/b]
        {
    		//Schleife prüft auf Doppelte
    		do
    		{
    			lotto[i] = rand() % MaxZahl + 1;
    			neueZahl = true; //positiv denken!
    			//Alle bisherigen Zahlen gegentesten
    			[b]for(j=0;j<i;j++)[/b]
    			{
    				if(lotto[j]==lotto[i])
    				{
    					neueZahl = false; //die gab es schon!
    				}
    			}
    		} while (!neueZahl);
        }
    

    Als Anfänger wundert man sich, weshalb der Wert der for-Schleife (i) nicht zurückgesetzt wird, die for-Schleife (j) immer auf 0 gesetzt wird.

    Soweit ich das verstanden habe hängt das mit der Abarbeitung des Programmes zusammen, Schleifen die verlassen werden und in welche wieder zurückgekehrt wird, hier ist das die j-Schleife, für diese gilt die Startanweisung ihrer eigenen Schleife (hier wäre es die Setzung auf 0).
    Da aber die for-Schleife(i), in diesem Abschnitt, nicht verlassen wird gilt auch ihre eigene Startanweisung nicht und somit kann die Variable i ihren Wert behalten.

    Demnach kommt das Programm jeweils "nur" bis zur while Überprüfung, springt dann zu do und dann und dann zur for-Schleife(i).

    Die for-Schleife(i) wird verlassen wenn die 6 Werte in die Indexfelder einfgefügt und auf Ungleichheit überprüft wurden.

    Wenn THEORETISCH zu einem späteren Zeitpunkt eine Rückkehr in die for-Schleife(i) geschehen würde, aus welchem Grund auch immer, würde i auf 0 gesetzt werden, da die Schleife "wieder frisch startet".

    Kommt das der Wahrheit ungefähr nahe?

    Danke schon im Voraus!



  • Pass auf, bald kommen ganz viele Leute an und werden dir sagen, dass du nicht C++, sondern C programmierst 😃

    Du hast es schon richtig verstanden. Die Startanweisung, also meistens das Initialisieren einer Variable, wird, wie der Name schon sagt, beim Start der Schleife aufgerufen.

    Es stimmt zwar nicht zu 100%, du kannst es dir eine for-Schleife aber so vorstellen, wenn es dir hilft:

    for (int i = 0; i < 21; i++)
    {}
    
    // entspricht:
    int i = 0;
    while (i < 21)
    {
      i++;
    
    Also ja, die j-Schleife wird mehrmals gestartet, die i-Schleife aber nur ein einziges mal.
    }
    


  • Wurstinator schrieb:

    Pass auf, bald kommen ganz viele Leute an und werden dir sagen, dass du nicht C++, sondern C programmierst 😃

    Du hast es schon richtig verstanden. Die Startanweisung, also meistens das Initialisieren einer Variable, wird, wie der Name schon sagt, beim Start der Schleife aufgerufen.

    Es stimmt zwar nicht zu 100%, du kannst es dir eine for-Schleife aber so vorstellen, wenn es dir hilft:

    for (int i = 0; i < 21; i++)
    {}
    
    // entspricht:
    int i = 0;
    while (i < 21)
    {
      i++;
    
    Also ja, die j-Schleife wird mehrmals gestartet, die i-Schleife aber nur ein einziges mal.
    }
    

    Alles klar, danke für die Antwort.

    Muss dem C++ Kommentar widersprechen, da der ganze Quellcode so aussieht :

    #include <iostream>
    #include <cstdlib>
    using namespace std;
    
    const int KugelZahl = 6;
    const int MaxZahl = 49; // Maximale Anzahl der sortierten Zahlen
    
    int main()
    {
        int lotto[KugelZahl];
        int i, j;
        int hilf;
        bool neueZahl;
    
        srand(time(0)); //Mische einmal durch!
        //Ermittle sechs Lottozahlen
        for(i=0; i<KugelZahl; i++)
        {
    		//Schleife prüft auf Doppelte
    		do
    		{
    			lotto[i] = rand() % MaxZahl + 1;
    			neueZahl = true; //positiv denken!
    			//Alle bisherigen Zahlen gegentesten
    			for(j=0;j<i;j++)
    			{
    				if(lotto[j]==lotto[i])
    				{
    					neueZahl = false; //die gab es schon!
    				}
    			}
    		} while (!neueZahl);
    	}
    	//Nun werden die Zahlen sortiert (per Bubblesort)
    	for(i=KugelZahl-1; i>0; i--)
    	{
    		for(j=0;j<i;j++)
    		{
    			if(lotto[j]>lotto[j+1])
    			{
    				hilf = lotto[j];
    				lotto[j] = lotto[j+1];
    				lotto[j+1] = hilf;
    			}
    		}
    	}
    	//Ausgabe der sortierten Zahlen
    	for(i=0; i<KugelZahl; i++)
    	{
    		cout << lotto[i] << " ";
    	}
    	cout << endl;
    }
    

    Cout und cin sind Befehle für C++, war aus dem Abschnitt dort nicht erkennbar.
    Habe früher mit C programmiert, dort jedoch mit printf und und scanf, etc.
    Abgesehen davon bearbeite ich ein "Einstieg in C++" Buch, sagen tue ich es nur damit ich die vorhergesagten Kommentare etwas abbremse.



  • [quote="Peng(uin)"]

    Wurstinator schrieb:

    Pass auf, bald kommen ganz viele Leute an und werden dir sagen, dass du nicht C++, sondern C programmierst 😃

    Du hast es schon richtig verstanden. Die Startanweisung, also meistens das Initialisieren einer Variable, wird, wie der Name schon sagt, beim Start der Schleife aufgerufen.

    Es stimmt zwar nicht zu 100%, du kannst es dir eine for-Schleife aber so vorstellen, wenn es dir hilft:

    for (int i = 0; i < 21; i++)
    {}
    
    // entspricht:
    int i = 0;
    while (i < 21)
    {
      i++;
    
    Also ja, die j-Schleife wird mehrmals gestartet, die i-Schleife aber nur ein einziges mal.
    }
    

    Alles klar, danke für die Antwort.

    Muss dem C-Kommentar widersprechen, da der ganze Quellcode so aussieht :

    #include <iostream>
    #include <cstdlib>
    using namespace std;
    
    const int KugelZahl = 6;
    const int MaxZahl = 49; // Maximale Anzahl der sortierten Zahlen
    
    int main()
    {
        int lotto[KugelZahl];
        int i, j;
        int hilf;
        bool neueZahl;
    
        srand(time(0)); //Mische einmal durch!
        //Ermittle sechs Lottozahlen
        for(i=0; i<KugelZahl; i++)
        {
    		//Schleife prüft auf Doppelte
    		do
    		{
    			lotto[i] = rand() % MaxZahl + 1;
    			neueZahl = true; //positiv denken!
    			//Alle bisherigen Zahlen gegentesten
    			for(j=0;j<i;j++)
    			{
    				if(lotto[j]==lotto[i])
    				{
    					neueZahl = false; //die gab es schon!
    				}
    			}
    		} while (!neueZahl);
    	}
    	//Nun werden die Zahlen sortiert (per Bubblesort)
    	for(i=KugelZahl-1; i>0; i--)
    	{
    		for(j=0;j<i;j++)
    		{
    			if(lotto[j]>lotto[j+1])
    			{
    				hilf = lotto[j];
    				lotto[j] = lotto[j+1];
    				lotto[j+1] = hilf;
    			}
    		}
    	}
    	//Ausgabe der sortierten Zahlen
    	for(i=0; i<KugelZahl; i++)
    	{
    		cout << lotto[i] << " ";
    	}
    	cout << endl;
    }
    

    Cout,cin sind Befehle für C++, war aus dem Abschnitt dort aber nicht erkennbar.
    Habe früher mit C programmiert, dort jedoch mit printf,scanf, hatten auch dieses using namespace std nicht.

    "Einstieg in C++" heisst das Buch, dort quäle ich mich gerade im Schneckentempo hindurch.



  • Peng(uin) schrieb:

    Muss dem C-Kommentar widersprechen, da der ganze Quellcode so aussieht :

    Er meinte wohl, dass man dir eher etwas in diese Richtung andrehen möchte:

    #include <array>
    #include <algorithm>
    #include <iterator>
    #include <iostream>
    int main()
    {
        std::array<unsigned, 49> kugeln;
        unsigned i = 0;
        std::generate(kugeln.begin(), kugeln.end(), [&i]()->unsigned{return ++i;});
        std::random_shuffle(kugeln.begin(), kugeln.end());
        std::array<unsigned, 6> ziehung;
        std::copy_n(kugeln.begin(), 6, ziehung.begin());
        std::sort(ziehung.begin(), ziehung.end());
        std::copy(ziehung.begin(), ziehung.end(), std::ostream_iterator<unsigned>(std::cout, " "));
        return 0;
    }
    


  • Hm, wie beschreibt man das so knapp wie möglich:

    for(i = 0; i < max; i++)
    {
        Alles was hier in der geschweiften Klammer steht wird wiederholt bis i < max.
        Auch weitere Schleifen werden wie normale Funktionen behandelt. D.h., wenn
        sie aufgerufen werden verhalten sich wie Schleifen sich halt so verhalten.
        for(j = 0; j < max; j++)
        {
            siehe Text zuvor - wenn for(j aufgerufen wird, muss nun aber alles was
            innerhalb der j-Klammern steht abgearbeitet werden.
        }
        erst nachdem die j-Klammer geschlossen ist, ist der Rest der i-Klammer angesagt.
    }
    

    Man kann die Verschachtelungen noch tiefer gestalten. Aber das sollte man nicht übertreiben, sonst geht die Übersichtlichkeit verloren. Alte Compiler konnten maximal nur 8 Schleifen in der Tiefe verarbeiten. Wie viel da bei den Neuen geht weiss ich nicht. Aber, sollte man wirklich nachdenken über mehr als 8 for-Schleifen in der Tiefe, sollte man sich erst mal seinen bisherigen Quelltext genau ansehen. 😃

    Das so kurz.
    Man auch

    for(i = max; i > 0; i--)
    

    nach kurzem Nachdenken wird das schon.
    Aber, wenn die Varianten kommen würde das länger.
    Hier mal ein Link zu Schleifen:
    http://www.cplusplus.com/doc/tutorial/control/

    MfG f.-th.


Anmelden zum Antworten