MINT üben

Programmieren mit Java

Zehn Aufgaben, bei denen du Java-Programme im Kopf ablaufen lässt, Fehler aufspürst und Klassen selbst schreibst.

Dein Fortschritt:
0 / 0 Aufgaben
2

Aufgabenblock — AFB II

Zehn Aufgaben aus dem ganzen Kapitel: Fehlermeldungen einordnen, Schleifen und Methodenaufrufe verfolgen, aus Klassenkarten Code machen und eine Suche in der Liste bauen — immer in mehreren Schritten, mit drei gestuften Tipps, wenn du nicht weiterkommst.

A1
Compiler oder Laufzeit? Münzsammlung
AFB II

Lina schreibt ein Programm für ihre Münzsammlung. Sie probiert sechs Zeilen aus — jede einzeln in main von Muenzsammlung.java:

  1. int anzahl = 12.5;
  2. boolean selten = "ja";
  3. char land = "M";
  4. double wert = 7 / 2;
  5. String s = "Münzen: " + 5 + 3;
  6. int[] kiste = new int[3]; kiste[3] = 5;

Analysiere die sechs Zeilen: Welche meldet schon javac, welche bricht erst beim Ausführen ab, welche laufen ohne Fehlermeldung — und mit welchem Wert?

Ansatz: Der Compiler prüft Typen: Passt der Wert rechts zum Typ links? Was er nicht wissen kann, sind Werte, die erst beim Ausführen entstehen — etwa welcher Index wirklich benutzt wird.
Typen: 'M' ist ein char, "M" ein String. 12.5 passt nicht verlustfrei in int. 7 / 2 ist erst eine Ganzzahldivision, dann wird erweitert.
Lösung: Compilerfehler in 1, 2, 3; Laufzeitfehler in 6; Zeile 4 ergibt 3.0, Zeile 5 den Text „Münzen: 53“.
Vollständige Lösung

Compilerfehler (3) — das Programm startet gar nicht:

1: error: incompatible types: possible lossy conversion from double to int
2: error: incompatible types: String cannot be converted to boolean
3: error: incompatible types: String cannot be converted to char

Laufzeitfehler (1) — Zeile 6 wird übersetzt, bricht aber beim Ausführen ab: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3 (erlaubt sind nur 0 bis 2).

Ohne Meldung laufen 4 und 5 — trotzdem liefern sie vermutlich nicht, was Lina wollte: wert = 3.0 (Ganzzahldivision) und s = „Münzen: 53“, weil von links nach rechts erst "Münzen: " + 5 zu einem Text wird und dann die 3 angehängt wird. Solche Logikfehler findet weder javac noch die JVM.

A2
while-Schleife verfolgen: Sparschwein
AFB II

Jonas spart für Kopfhörer für 100 €. Jede Woche legt er 10 € ins Sparschwein, jede vierte Woche gibt es von der Oma 15 € dazu.

int guthaben = 0;
int woche = 0;
while (guthaben < 100) {
    woche++;
    if (woche % 4 == 0) {
        guthaben += 25;
    } else {
        guthaben += 10;
    }
}

Ermittle mit einer Tracetabelle, nach wie vielen Wochen die Schleife endet und wie viel Geld dann im Sparschwein ist.

€
Ansatz: Tabelle mit den Spalten woche, woche % 4, guthaben. Die Bedingung wird immer vor einem Durchlauf geprüft.
Zwischenstand: Nach Woche 4 sind es 10 + 10 + 10 + 25 = 55 €. Wie geht es in Woche 5 bis 8 weiter?
Lösung: Nach Woche 7 sind es 85 € (< 100), also noch ein Durchlauf: Woche 8 ist wieder eine vierte Woche.
Vollständige Lösung

Woche 1: 10 · 2: 20 · 3: 30 · 4: 55 · 5: 65 · 6: 75 · 7: 85 · 8: 85 + 25 = 110. Jetzt ist 110 < 100 falsch → Ende.

Die Schleife endet nach 8 Wochen mit 110 €. Hier passt while besser als for, weil die Anzahl der Durchläufe vorher nicht feststeht.

A3
Von Python nach Java: Paketversand
AFB II

Ein Versandshop berechnet das Porto: bis 1000 g 5 €, danach für jede angefangenen 500 g 2 € mehr. Mia hat die Python-Funktion nach Java übertragen:

def kosten(gramm):
    if gramm <= 1000:
        return 5
    zusatz = (gramm - 1000 + 499) // 500
    return 5 + zusatz * 2
public static kosten(int gramm) {
    if (gramm <= 1000) {
        return 5;
    }
    zusatz = (gramm - 1000 + 499) / 500;
    return 5 + zusatz * 2
}

Überprüfe Mias Übersetzung: Finde alle Fehler, verbessere sie und berechne mit der korrigierten Methode das Porto für 2300 g und für 3000 g.

€
€
Ansatz: Was verlangt Java, was Python nicht braucht? Denk an Typen (bei Methoden und Variablen) und an das Zeilenende.
Rechenweg: // in Python entspricht bei int-Werten dem / in Java. Für 2300 g: (2300 − 1000 + 499) / 500 = 1799 / 500.
Lösung: Drei Fehler: Rückgabetyp int fehlt, int vor zusatz fehlt, Semikolon am Ende fehlt. 1799 / 500 = 3 → 5 + 6 = 11 €.
Vollständige Lösung
public static int kosten(int gramm) {
    if (gramm <= 1000) {
        return 5;
    }
    int zusatz = (gramm - 1000 + 499) / 500;
    return 5 + zusatz * 2;
}

Beim ersten javac-Lauf erscheinen nur zwei Meldungen: invalid method declaration; return type required und ';' expected. Erst wenn diese behoben sind, meldet der Compiler cannot find symbol … variable zusatz — Syntaxfehler werden vor den Typfehlern gefunden.

2300 g: 1799 / 500 = 3 angefangene Blöcke → 5 + 3 · 2 = 11 €. 3000 g: 2499 / 500 = 4 → 5 + 8 = 13 €. Das „+ 499“ sorgt fürs Aufrunden: 1001 g kostet schon 7 €.