Lernpfad:Einführung in Git/8

Aus Informatik-Box
Zur Navigation springen Zur Suche springen

In Gitea findest du ein Projekt mit dem Namen "oop2". Erstelle dir einen Fork und klone das Repository.

BlueJ oop2.png

Systematische Fehlersuche

Bei der Suche nach Fehlern in deinem Programmcode gibt es verschiedene Vorgehensweisen. Wichtig ist es, dabei systematisch vorzugehen und nicht einfach nur "Trial and Error" - also "Versuch und Irrtum" - anzuwenden.

Die Fehlersuche ist besonders schwierig, wenn das Programm kompiliert und startet - also syntaktisch korrekt ist, aber nicht die gewünschten Ergebnisse liefert - also einen semantischen Fehler enthält.

Überleg dir erst einen Plan, wie du vorgehen möchtest. Dazu musst du Vermutungen anstellen, wo im Programm der Fehler liegen könnte.

BlueJ Logo.png
Arbeitsauftrag
  1. Öffne die Klasse Calculator und analysiere ihren Quelltext.
  2. Suche die Methode int addEvenNumbers(int) und lies ihre Beschreibung im Methoden-Kommentar. Die Methode enthält zwei Fehler. Probiere sie aus. (Nicht wundern, wenn das Programm nicht mehr reagiert. Lies unten weiter.)


Die Methode bleibt in einer Endlosschleife hängen. Du kannst sie mit einem Klick auf den Pfeil unten rechts beenden.

BlueJ Endlosschleife.gif

Den Debugger benutzen

Für die systematische Fehlersuche steht dir ein mächtiges Werkzeug zur Verfügung: Der Debugger. Mit ihm kannst du das Programm zu beliebigen Zeitpunkten anhalten und dir seinen Zustand - also die Werte der Variablen - anzeigen lassen.

BlueJ Logo.png
Arbeitsauftrag
  1. Suche Zeile 18 und klicke einmal links auf die Zeilennummer. Ein rotes Stoppschild erscheint.
  2. Starte die Methode erneut und beobachte, was passiert. Analysiere das Debugger-Fenster und seine Funktion.
  3. Probiere die Buttons am unteren Rand des Debugger-Fensters aus. Behalte dabei auch den Editor mit dem Programmcode im Auge. Notiere dir Stichpunkte zu deinen Vermutungen, wie der Debugger funktioniert.
  4. Versuche die Endlosschleife zu beheben und die Methode zu korrigieren. Du kannst die Korrektheit mit der entsprechenden Testmethode prüfen.


BlueJ Debugger.png

Das Stoppschild visualisiert einen Breakpoint. Also einen Unterbrechungspunkt, an dem der Debugger das Programm anhalten soll. Du kannst beliebig viele Breakpoints setzen. Durch einen erneuten Klick auf das Schild kannst du den Breakpoint wieder löschen.

Lösung
    public int addEvenNumbers( int pUpperBound ) {
        int sum = 0, i = 1;
        while( i <= pUpperBound ) {
            // Nur gerade Zahlen addieren
            if( i%2 == 0 ) {
                sum += i;
            }
            i++;
        }
        return sum;
    }


BlueJ Logo.png
Arbeitsauftrag

Benutze bei den Aufgaben jeweils den Debugger zur Fehlersuche, die Testmethoden zur Überprüfung und committe deine Änderungen.

  1. Suche den Fehler in der Methode int ggT(int, int) und korrigiere ihn.
  2. Implementiere die Methode int kgV(int, int) nach der Vorgabe.


Lösung
/**
 * Ein einfacher Rechner.
 */
public class Calculator {

    /**
     * Bildet die Summe aller gerader Zahlen, die kleiner oder gleich
     * <var>pUpperBound</var> sind. Die Eingabe  <code>addEvenNumbers(4)</code>
     * ergibt also <code>2 + 4 = 6</code>.
     *
     * TODO: Benutze den Debugger, um die beiden Fehler in der Methode zu finden.
     *
     * @param pUpperBound Obere Grenze der Summe
     * @return
     */
    public int addEvenNumbers( int pUpperBound ) {
        int sum = 0, i = 1;
        while( i <= pUpperBound ) {
            // Nur gerade Zahlen addieren
            if( i%2 == 0 ) {
                sum += i;
            }
            i++;
        }
        return sum;
    }

    /**
     * Wendet den euklidischen Algorithmus zur Suche des größten gemeinsamen
     * Teilers bei zwei positiven ganzen Zahlen an.
     *
     * TODO: Benutze den Debugger, um den Fehler in der Methode zu finden.
     *
     * @link https://de.wikipedia.org/wiki/Euklidischer_Algorithmus
     * @param pNumberA
     * @param pNumberB
     * @return
     */
    public int ggT( int pNumberA, int pNumberB ) {
        if( pNumberA < 0 || pNumberB < 0 ) {
            return 0;
        } else if( pNumberA == 0 ) {
            return pNumberB;
        } else {
            while( pNumberB > 0 ) {
                if( pNumberA > pNumberB ) {
                    pNumberA -= pNumberB;
                } else {
                    pNumberB -= pNumberA;
                }
            }
            return pNumberA;
        }
    }

    /**
     * Berechnet das kleinste gemeinsame Vielfache zweier positiver Ganzzahlen.
     * @link https://de.wikipedia.org/wiki/Kleinstes_gemeinsames_Vielfaches#Berechnung_über_den_größten_gemeinsamen_Teiler_(ggT)
     * @param pNumberA
     * @param pNumberB
     * @return
     */
    public int kgV( int pNumberA, int pNumberB ) {
        if( pNumberA < 0 || pNumberB < 0 ) {
            return 0;
        } else {
            return (int) (pNumberA / this.ggT(pNumberA, pNumberB) * pNumberB);
        }
    }

}