Typischer Effekt bei ungeschickter Programmierung



  • Hallo,

    kann jemand bitte folgendes Programm für mich analysieren und seine Besonderheiten rausschreiben. Die Realisierung der Abfrage ob es weitergeht mit int zahl ist jedoch nicht von Bedeutung. Welcher typischer Fehler tritt bei dieser ungeschickten Programmierung auf und wie kann man ihn sicher verhindern?

    Vielen Dank!!

    #include <iostream>
    #include <iomanip>
    using namespace std;

    int zahl;

    int anzahl;
    const int max1 = 10;
    int b[max1];

    void anzeigen( const int b[]);
    void summieren (long int & sum );

    int main()
    {
    int temp;
    long int sum;

    do
    { for (anzahl = 0; anzahl < max1; ++anzahl) b[anzahl]=0;
    sum=0;
    anzahl=0;
    cout << "\n\n\n\nMax. 10 int-Zahlen, 0 fuer Abbruch : \n";
    do{
    cin >> temp;
    b[anzahl]=temp;
    ++anzahl;
    }
    while (b[anzahl-1] && anzahl<max1);
    --anzahl;
    if (temp != 0) ++anzahl;
    cout << endl;

    anzeigen (b);
    summieren (sum);
    cout << "\nSumme der eingegeben " << anzahl << " Zahlen: "
    << sum << endl;

    cin >> zahl;

    }while( zahl != 0);

    return 0;
    } // end of main

    // Summe

    void summieren (long int & sum)
    {
    for (anzahl=0;anzahl<max1;++anzahl)
    sum+=b[anzahl];
    }

    // Anzeige

    void anzeigen (const int b[])
    { cout << endl << endl;
    for (anzahl=0; anzahl< max1; ++anzahl)
    {if (b[anzahl] != 0) cout << setw(6) << b[anzahl];
    if ((anzahl+1)%3==0) cout << endl;
    }
    }



  • ähm, sitzt du grad bei einer Prüfung udn ist das eine Aufgabe jenerwelcher? 😃



  • Sitze grad nicht bei einer Prüfung abba muss die Aufgabe für einen Kurs lösen 😞
    Und komme leider einfach nicht weiter....



  • Nicht weiter als was...?



  • Anfänger2007 schrieb:

    typischer Fehler

    1. Du motivierst den Leser durch fehlendes Syntaxcoloring, den Beitrag direkt wieder zu schließen.

    wie kann man ihn sicher verhindern?

    1. Vor dem Posten mal die vielen auffälligen Links im oberen Forenbereich sowie beispielhaft die Beiträge anderer anklicken oder beim Verfassen einer Nachricht die Buttons unten bewundern.



  • Nunja...mir fehlt schon mal der angesprochene Effekt..bei der zweiten do-Schleife kann ich dem Programm nicht mehr richtig folgen und die Funktion anzeigen verstehe ich auch nicht wirklich



  • ja ist auch ein krankes Stück Code *brr*
    es hilft ungemein, wenn man einen Code so schreibt das er strukturiert ist, das heißt das man Anfang und Ende eine Schleife,... einfach erkennt. Wenn du ein absoluter Crack bist, kannst du auch alles in eine Zeiel schreiben, Überblick wirst halt keinen mehr haben.

    #include <iostream> //Includedatei für die ganzen Programm Ein- und Ausgaben
    #include <iomanip>  //ähm, kenn ich nicht, hab in der MSDN nachgesehn und keine Funktion in diesem Programm gefunden die dieses Include benötigt.
    using namespace std; 
    
    int zahl; 
    
    int anzahl; 
    const int max1 = 10; 
    int b[max1]; //ok, aber b[10] ginge genauso.
    
    void anzeigen( const int b[]); //also das const hat hier nix verloren!
    void summieren (long int & sum ); //ähm, Adressoperatoren in einer Parameterliste? Sollte eher (long int *sum) heißen.
    
    int main() 
    { 
       int temp; 
       long int sum; 
    
       do 
       { 
           for (anzahl = 0; anzahl < max1; ++anzahl) b[anzahl]=0; // Initialisiert mal das ganze b-Array
           sum=0; //Initialisiert sum
           anzahl=0;  //Initialisiert anzahl, das nach der for(;;) Schleife ja den Wert 9 hat.
           cout << "\n\n\n\nMax. 10 int-Zahlen, 0 fuer Abbruch : \n"; //gibt einen lustigen Text in der Konsole aus. 
           do
           { 
              cin >> temp; // bin mir nicht sicher, aber ich glaub vorher sollt ma den Tastatupuffer leeren.
              b[anzahl]=temp; //eingelesene Zahl ins Array schreiben.
              ++anzahl; 
           } 
           while (b[anzahl-1] && anzahl<max1); //großer Schwachsinn! Das ganze sollte eigentlich so aussehen: (b[anzahl-1] != 0 && anzahl < max1) 
           --anzahl; //was das hier soll versteh ich nicht ganz
           if(temp != 0) ++anzahl; //was diese Abfrage bringt weiß auch keiner.
           cout << endl; 
           anzeigen (b); //Funktionsaufruf
           summieren (sum); //Funktionsaufruf sollte aber: summieren(&sum) lauten!
           cout << "\nSumme der eingegeben " << anzahl << " Zahlen: " << sum << endl; //wieder eine lustige Ausgabe
           cin >> zahl; //wieder eine zahl einlesen
       }
       while( zahl != 0); //Schleife rennt solang bis der Benutzer das richtige eingibt.
       return 0; 
    } // end of main 
    
    // Summe 
    
    void summieren (long int & sum) //das selbe wie oben (long int *sum)
    { 
      for (anzahl=0;anzahl<max1;++anzahl) 
      sum+=b[anzahl]; //man könnte auch sum = sum + b[anzahl] schreiben, aber so ist es eh schöner.
    } 
    
    // Anzeige 
    
    void anzeigen (const int b[]) //const hat auch hier nix verloren
    { 
       cout << endl << endl; 
       for (anzahl=0; anzahl< max1; ++anzahl) 
       {
          if (b[anzahl] != 0) cout << setw(6) << b[anzahl]; //setzt die Anzeigebreite auf 6 und gibt alle Werte außer 0 aus.
          if ((anzahl+1)%3==0) cout << endl; //Addiert anzahl mit 1, Dividiert es dann durch 3 und vergleicht ob der Rest 0 ist, was auch immer das soll.
       } 
    }
    
    //puh endlich fertig mit dem kranken Teil
    


  • Vielen Dank erstmal...eben zeile 32 und zeile 33 sowie Zeile 64 versteh ich auch nicht...



  • Joe80 schrieb:

    void summieren (long int & sum ); //ähm, Adressoperatoren in einer Parameterliste? Sollte eher (long int *sum) heißen.
    
    if ((anzahl+1)%3==0) cout << endl; //Addiert anzahl mit 1, Dividiert es dann durch 3 und vergleicht ob der Rest 0 ist, was auch immer das soll.
    

    Ich hab mir nicht den ganzen Quellcode durchgeschaut, aber zwei Sachen sind mir beim "überfliegen" aufgefallen.
    1. int & sum ist eine Referenz, also muss es nicht int *sum heißen.
    2. (anzahl+1)%3==0 bedeutet das nach jeder dritten Zahl ein Zeilenumbruch gemacht wird.



  • [code]while (b[anzahl-1] && anzahl<max1); //großer Schwachsinn! Das ganze sollte eigentlich so aussehen: (b[anzahl-1] != 0 && anzahl < max1)
    

    [/code]

    Wieso sollte das so aussehen? und kann mir einer erklären wozu zeile 32 und 33 dienen?

    Vielen Dank!!



  • while (b[anzahl-1] && anzahl<max1); //großer Schwachsinn! Das ganze sollte eigentlich so aussehen: (b[anzahl-1] != 0 && anzahl < max1)
    

    Quatsch, man muss nicht auf ungleich 0 prüfen. Du musst in C++ nicht gegen einen Wert prüfen (zumindest wenn der Typ eine Zahl ist). Die Prüfung von b[anzahl-1] ist das gleiche wie b[anzahl-1]!=0. Wenn nämlich eine Zahl 0 ist wird sie zu false ausgewertet und wenn sie ungleich 0 ist zu true.

    Zeile 33 ist zwar überflüssig, aber nachvollziehbar. Dadurch das anzahl einen runterzählt wird, muss bei einem indizierten Zugriff nicht mehr -1 geschrieben werden. Obwohl statt in Zeile 34 dann temp auf ungleich 0 zu prüfen würde ich die beiden Zeilen zu

    if(temp) --anzahl; // oder temp!=0 in der Bedingung
    

    zusammenfassen. So spart man es sich einmal runter und dann evtl. wieder hochzuzählen, sondern zählt nur runter, wenn es nötig ist.

    Aber allein wegen der ganzen globalen Variablen ist der Code ein Fall für die Mülltonne...

    Greetz



  • Danke...Ich soll im Teil b die Funktion anzeige über eine geschachtelte Schleife realisieren ohne dass sich deren Aussehe ändert..ich habe eine Lösung mit Schleifen, jedoch habe ich sie nicht geschachtelt...Kann mir da einer weiterhelfen?

    Meine Lösung:

    void anzeigen (const int b[]) 
    {   cout << endl << endl;
        int k;
    for (k=0; k< 3; ++k)
        {if (b[k] != 0) cout << setw(6) << b[k];          
    }
    cout << endl;
    for (k=3;k<6;++k)
    {
        if (b[k] != 0) cout << setw(6) << b[k];          
    }
    cout << endl;
    for (k=6;k<9;++k)
    {
        if (b[k] != 0) cout << setw(6) << b[k];          
    }
    cout << endl;
    for (k=9;k<10;++k)
    {
        if (b[k] != 0) cout << setw(6) << b[k];          
    }
    }
    


  • Hier ist ne verschachtelte Schleife.
    Ist aber ziemlich hässlich.
    Wahrscheinlich zu kompliziert gedacht.

    void anzeigen (const int b[])
    { 
        const int spalten =  3;
        int i;
        for (int k = 0;;) // hallo, Endlosschleife --> unschön
        {
        	for (i = 0; i != spalten; ++i, ++k) // 2 vars laufen gleichzeitig --> unschön
        	{
                if(k == max1) return; // Arrayende --> fertig
                if(b[k] == 0) return; // "0 fuer Abbruch" --> fertig
                cout << setw(6) << b[k];           
            }
            cout << endl;
         }	
    }
    


  • Oder einfach eine Schleife:

    void anzeigen(int const *b, int anz)  {
      for(int i=0; i<anz; ++i) {
        if(i%3==0) cout << endl;
        if(b[i]) cout << setw(6) << b[i];
      }
    }
    

    So gebe ich noch die Anzahl der Elemente mit und kann die Ausgabe auch variieren. Aufrufbeispiel:

    int b[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    anzeigen(b, 10);
    

    Greetz



  • void anzeigen( const int b[]); //also das const hat hier nix verloren!

    Also, das musst du mir jetzt mal erklären. Ob das const da steht oder nicht ist für die Übergabe in diesem Fall unwichtig, aber da der Schreiber dieses Codes b[] in der Funktion nicht verändern will kann er es doch ruhig const machen. Macht es leichter Schreibfehler und so zu finden, wenn alles, was nicht geändert werden soll const ist.

    void summieren (long int & sum ); //ähm, Adressoperatoren in einer Parameterliste? Sollte eher (long int *sum) heißen.

    Wurde bereits gesagt, das ist vollkommen in Ordnung und imho besser als wenn du jetzt anfängst mit Zeigern zu hantieren (Nachteil: es ist etwas versteckter)

    void anzeigen(const int b){
       cout << endl << endl;
       for (anzahl=0; anzahl+3< max1; anzahl+=3)
       {
          for(int i=0;i<3;++i)
            if (b[anzahl+i] != 0) cout << setw(6) << b[anzahl+i]; 
          cout << endl; 
       }
       for(int i=0;i<max1-anzahl;++i) cout<<setw(6)<<b[anzahl+i];
    }
    

    ICh bin mir jetzt nicht ganz sicher, weil ungetestet (falls was falsch ist bitte einfach sagen) Sollte aber denke ih so gehen.



  • Ah, vorhin nicht gesehen das es verschachtelt sein soll. ^^
    @Shinja:
    Bei deiner Parameterliste fehlt * bzw. [], sicher nur ein Flüchtigkeitsfehler. Ein "cout << endl;" kann man sich sparen, packt man einfach das "cout << endl;" in der Schleife vor die innere Schleife. Die letzte Schleife kann man mit in die innere Schleife aufnehmen, wenn man beim Vergleich der äußeren Schleife das "+3" weglässt:

    void anzeigen(const int *b) {
      for (anzahl=0; anzahl< max1; anzahl+=3) {
        cout << endl;
        for(int i=0;i<3 && i<max1-anzahl;++i)
          if (b[anzahl+i]) cout << setw(6) << b[anzahl+i];
      }
    }
    

    Greetz



  • Jo, die [] waren ein Flüchtigkeitsfehler, der recht einfach schlecht überlegt. Danke für die Korrekturen.

    @TE: war es das was gemeint war?



  • Ja vielen, vielen Dank!!


Log in to reply