4th Java Lesson

November 9, 2022

Thanks to Moritz Schulz, Florian Kluge for the Slides

Was wir heute machen

  1. Kaputte und komische Programme
  2. Arrays
  3. Funktionen

Kaputte Programme

  • ein paar Programme, die kaputt sind
  • Das heißt, sie kompilieren nicht.
    • javac, der Compiler (Übersetzer), beschwert sich
  • in den Beispielen: meist Syntaxfehler
    • Syntax sind die Regeln, die beschreiben, was ein gültiges Programm ist
    • ein bisschen Syntax, am Beispiel, lernen

Kaputte Programme

  • Was ist kaputt?
  • Wie kann der Fehler behoben werden?
  • Vorgehensweise
    • Ich zeige den Code.
    • Ihr überlegt, was daran kaputt ist.
    • Eine Person zeigt den Fehler.

Kaputtes Programm Nr. 1

  • 2 Fehler
public class Main {
    public static void main(String[] dontmindme)
        System.out.println("Ich bin kaputt!")
        
}

Datei: Main.java

Kaputtes Programm Nr. 1 Lösung

public class Main {
    public static void main(String[] dontmindme) {
        System.out.println("Ich bin ganz!");
    }
}

Datei: Main.java

Kaputtes Programm Nr. 1 Hinweise

  • ein ; ist am Ende jeder Zeile benötigt, es sei denn, es ist ein if, while, ….
  • die Funktion main benötigt geschweifte Klammern

Kaputtes Programm Nr. 2

  • 4 Fehler
      public class Javajavajajavajava { 
public static void moin(String[] dontmindme) {
  System.out.println("Ich bin kaputt!"};
               }

Datei: Main.java

Kaputtes Programm Nr. 2 Lösung

      public class Javajavajajavajava { 
public static void main(String[] dontmindme) {
  System.out.println("Ich bin ganz!");
}
               }

Datei: Javajavajajavajava.java

Kaputtes Programm Nr. 2 Hinweise

  • nach System.out.println kommen runde Klammern
  • die Anzahl der { muss gleich der Anzahl der } sein
  • Der Dateiname und der Klassenname sollten übereinstimmen

Kaputtes Programm Nr. 2 Lösung (formatiert)

public class Javajavajajavajava { 
    public static void main(String[] dontmindme) {
        System.out.println("Ich bin schön!");
    }
}

Kaputtes Programm Nr. 2 Hinweise (Formatierung)

  • formatierter Code ist besser lesbar und schafft besseres Verständnis
    • Konvention: Nach jeder geöffneten {: um eins nach rechts einrücken
    • } zur passenden { auf der gleichen Einrückungsstufe

Kaputtes Programm Nr. 3

  • 4 Fehler
public class Kaffee { 
    public static void main(string[] argumente) {
        string aussage = 'Ich bin kaputt';
        System.out.println(Aussage);
    }
}

Datei: Kaffee.java

Kaputtes Programm Nr. 3 Hinweise

  • Strings haben " um den Wert
    • ' nur bei einzelnen Zeichen (char)
  • String wird groß geschrieben (2 mal)
  • aussage: Variablennamen müssen immer die gleiche Groß- und Kleinschreibung haben, wie in der Deklaration

Kaputtes Programm Nr. 3 Lösung

public class Kaffee { 
    public static void main(String[] argumente) {
        String aussage = "Ich bin ganz";
        System.out.println(aussage);
    }
}

Datei: Kaffee.java

Kaputtes Programm Nr. 4

  • 5 Fehler
  • nicht die fehlenden Klammern nach if / else
public class NummerFuenf { 
    public static void main(String[] parameter) {
        a = 393;
        b = 494;
        int c = a < b;
        if (c)
            System.out.println("b ist größer!")
        else
            System.out.println("a ist größer!")
            
    }
}

Kaputtes Programm Nr. 4 Lösung

public class NummerFuenf { 
    public static void main(String[] parameter) {
        int a = 393;
        int b = 494;
        boolean c = a < b;
        if (c)
            System.out.println("b ist größer!");
        else
            System.out.println("a ist größer!");
            
    }
}

Kaputtes Programm Nr. 4 Hinweise

  • Bevor eine Variable einen Wert erhalten kann, muss sie deklariert werden
    • Dabei muss der Typ angegeben werden.
  • a < b ist vom Typ boolean
    • deshalb muss c auch vom Typ boolean sein
  • nach System.out.println("...") fehlten ;

Kaputtes Programm Nr. 5 Lösung (formatiert)

public class NummerFuenf { 
    public static void main(String[] parameter) {
        int a = 393;
        int b = 494;
        boolean c = a < b;
        if (c) {
            System.out.println("b ist größer!");
        } else {
            System.out.println("a ist größer!");
        }
            
    }
}

Kaputtes Programm Nr. 5 Hinweise (Formatierung)

  • wenn nach einem if nur eine Zeile kommt, die dazu gehört
    • dann können die geschweiften Klammern weggelassen werden
  • Empfehlung: immer die geschweiften Klammern mitschreiben
    • denn sonst besteht die Gefahr, dass eine zweite Zeile hinzukommt,
      • diese durch fehlende Klammern immer ausgeführt wird
      • statt: nur bei erfolgreicher Bedingung

Komische Programme

  • nicht alle Fehler sind Syntaxfehler
    • es gibt auch logische Fehler
  • manchmal verhalten sich Programme anders als erwartet
    • jedoch beschreibt der Code (in der Regel) das Verhalten genau
  • gleiche Vorgehensweise
    • aber auch noch, hin und wieder: Anschauen im Debugger

Komisches Programm Nr. 1

public class AbsoluteDifferenz { 
    public static void main(String[] args) {
        int a = 93;
        int b = 34;
        
        if (a < b) {
            System.out.println(a - b);
        } else {
            System.out.println(b - a);
        }
    }
}

Komisches Programm Nr. 1 Hinweis

  • Das Programm soll die absolute Differenz berechnen.
  • Das heißt, dass immer eine positive Zahl entstehen soll.
  • Dafür muss immer von einer größeren eine kleinere Zahl abgezogen werden.
  • Allerdings war hier genau das Gegenteil der Fall: Es wurden immer negative Zahlen.

Komisches Programm Nr. 1 Lösung

public class AbsoluteDifferenz { 
    public static void main(String[] args) {
        int a = 93;
        int b = 34;
        
        if (a > b) { //hier war der Fehler
            System.out.println(a - b);
        } else {
            System.out.println(b - a);
        }
    }
}

Tipp: Debugger

Komisches Programm Nr. 2

  • 2 Fehler (davon 1 Syntax, 1 Logik)
public class VielfacheVonDrei { 
    public static void main(String[] args) {
        int i = 0;
        
        while (i < 1000) {
            if (i % 3) {
                i = i+1;
                System.out.println(i);
            }
        }
    }
}

Komisches Programm Nr. 2 Hinweise

  • Sobald i den Wert 1 hat, wird die Bedingung beim if nicht mehr erfüllt.
  • Das heißt, dass sich der Wert von i nicht mehr ändern kann:
    • Das geschehe ja schließlich nur innerhalb vom body von if
  • Deshalb ist die Bedingung i < 1000 immer wahr
  • Es bildet sich eine Endlosschleife zwischene while (true) und if (false)
  • Endlosschleifen sind ein beliebter Fehler
    • Schleifen, deren Bedingungen sich nie mehr ändern,
    • was bewirkt, dass sie nie aufhören => endlos laufen

Komisches Programm Nr. 2 Lösung

public class VielfacheVonDrei { 
    public static void main(String[] args) {
        int i = 0;
        
        while (i < 1000) {
            if (i % 3 == 0) { // das muss ein Vergleich sein!
                System.out.println(i);
            }
            i = i+1; // an der richtigen Stelle!
        }
    }
}
Arrays
  • in Arrays können wir mehrere Werte hintereinander speichern
  • ein Array ist quasi eine “Liste von Werten gleicher Art”
// Deklaration
datentyp[] arrayName;
Arrays
  • wir können Arrays von nahezu allen Datentypen erstellen
    • dabei sind die eckigen Klammern [] wesentlich
// Beispiel
String[] wochentage;
float[] notenspiegel;
Arrays
  • um Elemente in einem Array zu speichern,
    • können wir einen Array direkt mit ihnen deklarieren
String[] wochentage = {
    "Montag",
    "Dienstag",
    // ...
    "Sonntag"
};
Arrays
  • um Elemente in einem Array zu speichern,
    • können wir einen Array direkt mit ihnen deklarieren
float[] notenspiegel = {
    1.0f,
    1.3f,
    // ...
    5.0f
};
Arrays
  • … diese Syntax funktioniert aber nur, wenn direkt die Elemente angegeben werden
  • Ein “leeres” Array wird mit new deklariert.
    • später mehr dazu beim Thema “Objektorientierte Programmierung”
  • Dabei müssen wir die Größe unseres Arrays festlegen,
    • denn jeder Array hat eine begrenzte Größe.
int size = 5;
String[] cities = new String[size]; // hat Platz für 5 Elemente
Arrays
  • wir können mithilfe des index (= Stelle) auf einzelne Elemente in einem Array zugreifen
  • Aufgepasst: der Computer fängt bei 0 an zu zählen!
    • arr[0] ist das erste Element, nicht arr[1]
                        //index?    index?    index?        index?
String[] wochentage = {"Montag", "Dienstag", "Mittwoch", "Donnerstag"};
String montag = wochentage[/* ? */];
Pro Tipp
  • mit arrayName.length können wir die Länge des Arrays bekommen
int[] arr = {1, 2, 3, 4, 5};

System.out.println(arr.length); // 5
Frage
  • Denkt ihr, dieser Code würde funktionieren?
int[] arr = {1, 2, 3, 4, 5};

System.out.println(arr[5]);
Antwort
  • Nein, denn Java erzeugt folgenden Fehler:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index 5 out of bounds for length 5
  • “Index außerhalb der Grenzen”:
    • Der höchste Index in arr ist arr.length-1
Arrays
  • Wir können Werte von Arrays auch überschreiben
int[] arr = {1, 2, 3, 4, 5};

arr[0] = 9;

System.out.println(arr[0]); //9
Aufgabe 1
public class AufgabeEins {
    public static void main(String[] args) {
        int[] arr = {10,8,3,9,6,1,5};
        
        // Gehe durch den Array mit einer while-Loop
        // Entscheide bei jedem Wert:
        // Ist der Wert gerade?
        //     => Dann gebe das Wort "gerade" und den Wert aus
        // Ist der Wert ungerade?
        //     => Dann gebe das Wort "ungerade" und den Wert aus
        // Du kannst auch weitere Variablen anlegen.
        // Am besten verwendest du arr.length, statt selbst zu zählen,
        //     wie viele Elemente arr hat.
    }
}
Aufgabe 1 Lösungsschritt
public class AufgabeEins {
    public static void main(String[] args) {
        int[] arr = {10,8,3,9,6,1,5};
        
        int i = 0;
        
        while (i < arr.length) {
            // Entscheide bei jedem Wert:
            // Ist der Wert gerade?
            //     => Dann gebe das Wort "gerade" und den Wert aus
            // Ist der Wert ungerade?
            //     => Dann gebe das Wort "ungerade" und den Wert aus
            i++;
        }
    }
}
Aufgabe 1 Lösungsvorschlag
public class AufgabeEins {
    public static void main(String[] args) {
        int[] arr = {10,8,3,9,6,1,5};
        
        int i = 0;
        
        while (i < arr.length) {
            // Ist der Wert mit Index i gerade?
            if (arr[i] % 2 == 0) {
                System.out.println("gerade: " + arr[i])
            }
            // Ist der Wert mit Index i ungerade?
            if (arr[i] % 2 == 1) {
                System.out.println("ungerade: " + arr[i])
            }
            i++;
        }
    }
}
Arrays und For-loops
  • neben while loops gibt es außerdem for loops
  • abstrakt gezeigt:
for (statement1; statement2; statement3) {
  /*
    Statement1 - executed before the loop starts (once)
    Statement2 - defines the loop-condition
    Statement3 - is executed at the end of the body
  */
  // body
}

ist äquivalent zu:

statement1;
while (statement2) {
  // body
  statement3;
}
Arrays und For-loops
  • am konkreten Beispiel:
for (int i = 0; i < 5; i++) {
  System.out.println(i);
}

ist äquivalent zu:

int i = 0;
while (i < 5) {
  System.out.println(i);
  i++;
}
Arrays und For-loops
  • Wieso for-Schleifen?
  • Es ist ein häufiges Muster, eine Variable (z.B. i) alle Werte zwischen 0 und n annehmen zu lassen
    • zum Beispiel beim Durchgehen eines Arrays
  • Da sind while-Schleifen unübersichtlicher,
    • denn sie verteilen Deklaration, Bedingung und Wertzuweisung an drei Orte.
Aufgabe 1.1
  • Ersetzt die while-Schleife im Programm durch eine äquivalente for-Schleife
Aufgabe 1.1 Lösungsvorschlag
public class AufgabeEins {
    public static void main(String[] args) {
        int[] arr = {10,8,3,9,6,1,5};
        
        for (int i = 0; i < arr.length; i++) {
            // Ist der Wert mit Index i gerade?
            if (arr[i] % 2 == 0) {
                System.out.println("gerade: " + arr[i])
            }
            // Ist der Wert mit Index i ungerade?
            if (arr[i] % 2 == 1) {
                System.out.println("ungerade: " + arr[i])
            }
        }
    }
}
Aufgabe 2
  • Entwickelt ein weiteres Programm, welches
    • alle negativen Zahlen in einem Array durch ihren Betrag ersetzt
    • danach alle Elemente des Arrays ausgibt
    • Herausforderungen:
      1. den Array von hinten durchgehen
      2. die zuletzt betrachtete negative Zahl negativ lassen
      3. das größte Element finden
      4. den Durchschnitt bilden
public class AufgabeZwei {
    public static void main(String[] args) {
        int[] arr = {10,-19,13,-9,0,14,-99};
        
        // ...
    }
}
Aufgabe 2 Lösungsvorschlag
public class AufgabeZwei {
    public static void main(String[] args) {
        int[] arr = {10,-19,13,-9,0,14,-99};
        
        for(int i = 0; i < arr.length; i++) {
            if (arr[i] < 0) {
                arr[i] = arr[i] * (-1);
            }
        }
        
        for(int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}
Aufgabe 2.1 Lösungsvorschlag (von hinten)
public class AufgabeZwei {
    public static void main(String[] args) {
        int[] arr = {10,-19,13,-9,0,14,-99};
        
        for(int i = arr.length -1; i >= 0; i--) {
            if (arr[i] < 0) {
                arr[i] = arr[i] * (-1);
            }
        }
        
        for(int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}
Aufgabe 2.2 Lösungsvorschlag (das letzte lassen)
public class AufgabeZwei {
    public static void main(String[] args) {
        int[] arr = {10,-19,13,-9,0,14,-99};
        
        // -1 als ungültiger Index als Startwert
        int letzte = -1;
        
        for(int i = arr.length -1; i >= 0; i--) {
            if (arr[i] < 0) {
                arr[i] = arr[i] * (-1);
                letzte = i;
            }
        }
        
        // Wurde überhaupt ein negatives Element gefunden?
        if (letzte != -1) {
            // wieder negieren
            arr[letzte] = arr[letzte] * -1;
        }
        
        for(int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}
Aufgabe 2.3 Lösungsvorschlag (das größte Element finden)
public class AufgabeZwei {
    public static void main(String[] args) {
        int[] arr = {10,-19,13,-9,0,14,-99};
        
        // das kleinstmögliche Minimum
        int max = -2147483648;
        
        for(int i = arr.length -1; i >= 0; i--) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        
        System.out.println("Das Maximum ist " + max);
    }
}
Aufgabe 2.4 Lösungsvorschlag (den Durchschnitt bilden)
public class AufgabeZwei {
    public static void main(String[] args) {
        int[] arr = {10,-19,13,-9,0,14,-99};
        
        float sum = 0;
        
        for(int i = arr.length -1; i >= 0; i--) {
            sum += arr[i]; // das gleiche wie: sum = sum + arr[i];
        }
        
        float average = sum / arr.length;
        
        System.out.println("Das arithmetische Mittel ist " + average);
    }
}