Upload
vanbao
View
215
Download
0
Embed Size (px)
Citation preview
Kapitel 16: Java GrundlagenGrundlagen der Programmierung 1
Holger Karl
Wintersemester 2016/2017
Inhaltsverzeichnis
Inhaltsverzeichnis 1
Abbildungsverzeichnis 2
Liste von Definitionen u.ä. 216.1 Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316.2 Java: Dateien, Programmstruktur, Ausführung . . . . . . . . . . 316.3 Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516.4 Datentypen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 816.5 Variablendeklarationen und Zuweisungen . . . . . . . . . . . . 1016.6 Kontrollstrukturen: Verzweigungen . . . . . . . . . . . . . . . . 1916.7 Kontrollstrukturen: Schleifen . . . . . . . . . . . . . . . . . . . 22
1
16.8 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . 28
Abbildungsverzeichnis
16.1 Zuweisung von int-Variablen . . . . . . . . . . . . . . . . . . . 1516.2 Zuweisung von String-Variablen . . . . . . . . . . . . . . . . . 1616.3 Zuweisung an Strings: Erzeugen eines neuen Strings durch einen
Ausdruck . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1616.4 Zuweisung von Arrays und Manioulation eines Elementes . . . 1716.5 Ein Array durch clone kopieren . . . . . . . . . . . . . . . . . . 19
Liste von Definitionen u.ä.
16.1 Definition (Statisches main) . . . . . . . . . . . . . . . . . . . 316.2 Definition (Vor Benutzung deklarieren) . . . . . . . . . . . . . 1016.3 Definition (dangling else: Festlegung) . . . . . . . . . . . . . . 20
2
16.1. Überblick 3
16.1 Überblick
16.1.1 Was bisher geschah
• Konzeptionell haben wir die Grundlagen für Programmierung allgemeinaus den Python-Kapiteln
• Das vorherige Kapitel hat die Konzepte statisch typisierter Sprachenveranschaulicht
16.1.2 Dieses Kapitel
• Wir schauen uns Java Grundlagen an• Aufteilung auf Dateien und das Ausführungsmodell• Kontrollstrukturen• Variablen als Schachtel statt als Schilder: Konsequenzen• Syntax von Typdefinitionen
16.2 Java: Dateien, Programmstruktur, Ausführung
16.2.1 Objektorientierung und Dateien
• Java ist sehr viel konsequenter objektorientiert als Python• Eine Auswirkung: Verteilung eins Programms auf Dateien
– Regel: Eine Datei = eine Klasse
16.2.2 Programmstruktur aus mehreren Dateien?
• Programm besteht aus einer oder mehreren Klassen• Wo geht es los?
– Insbesondere: Zu Programmbeginn gibt es ja noch keine Objekte?– Also kann man nur statische Methoden ausführen!– Aber welche?
Definition 16.1 (Statisches main). Regel: Genau eine Klasse eines Pro-gramms muss eine statischeMethode main enthalten. Bei dieser Methodebeginnt die Programmausführung.
Diese Datei darf andere Klassen (aus anderen Dateien) importieren. Typi-scherweise wird die Methode main Objekte dieser Klassen instanziieren unddort Methoden aufrufen.
4 Liste von Definitionen u.ä.
16.2.3 Dateiname entspricht Klassenname
• Dateinamen sind nicht frei wählbar• Muss vielmehr der in der Datei definierten Klasse entsprechen
– Um .java ergänzt– Auf Groß-/Kleinschreibung achten!
16.2.4 Übersetzen und Starten eines Programms
• Java unterscheidet dieÜbersetzungunddieAusführung eines Programms• Eine *.java ist nicht direkt ausführbar• Compiler: javac
– Übersetzt von *.java nach *.class– *.class Binärdatei mit Zwischencode; nicht direkt für Menschenlesbar
• Ausführung: java– Argument: der Name der Klasse, die die main-Methode enthält
* Nicht die .class-Datei* Die wird dann gesucht
– java interpretiert die class-Datei
16.2.5 Übersetzen und Starten eines Programms – Beispiel
1 class TestClass {2
3 public static void main(String [] args) {4 System.out.println("Hello, world!");5 }6
7 }
1 javac TestClass.java2 java TestClass3 # das hier wäre falsch:4 # java TestClass.class
16.2.6 Mehrere Dateien zusammenfügen
Programmcode: import
• Möchte man andere Klassen nutzen, braucht man import– Sehr ähnlich zu Python
16.3. Syntax 5
Übersetzung
• Alle Dateien mit javac übersetzen• Nur die Klasse/Datei mit public static void mainmit java star-ten!
16.2.7 Anmerkung: Java und Jupyterhub
• Jupyterhub ist nur bedingt auf die Ausführung von Java ausgelegt• Insbesondere ist der derzeitige Java Standard, Version 8, nicht zu einerREPL in der Lage– Es gibt Java REPL, aber das ist ungetestet und nicht Standard– Das geht erst mit der Beta-Version, Java 9
• Wenn Sie die Beispiele hier auf einem eigenen Rechner nachvollziehenwollen, so befolgen Sie die Anleitungen zur Installation eines Java-9Kernels für Jupyterhub
16.2.8 Anmerkung: Java, Dateien, Editoren, IDE
• Da Java und Jupyterhub nicht so schön zusammenpassen: Sie brauchenEditoren
• Die Liste aus vorherigem Kapitel passt hier ebenfalls– Jeder ordentliche Editor für Entwickler unterstützt viele Sprachen
• IDEs: NetBeans, Eclipse, IntelliJ IDEA, Android Studio, BlueJ (zum Ler-nen nicht schlecht, mit REPL), jEdit (spezialisierter Editor, praktischeine IDE)– Aber tun Sie sich das für GP1 nicht an!– Lernaufwand sehr hoch– Später ist eine IDE (nicht notwendig Eclipse) sinnvoll
16.3 Syntax
16.3.1 Syntax: Klammern, Klammern
• Syntax von Java offenbar anders als die von Python• Offensichtlichster Unterschied: die ganzen Klammern { } ?• Java definiert Blöcke durch öffnende/schließende geschweifte Klammern{, }– Nicht durch Einrückung; die wird vom Compiler ignoriert– Aber: Einrückung zur Lesbarkeit empfohlen (und unerlässlich)
6 Liste von Definitionen u.ä.
Konfusion: Klammer vs. Einrückung
Häufig Fehlerquelle!
• Klammern und Einrückungen stimmen nicht überein• Compiler schaut auf Klammer; Mensch auf Einrückung
16.3.2 Syntax: Geschwätzig
• Zweiter Unterschied: Javas Syntax ist sehr weitschweifig• Daumenregel für vergleichbare Programme: Java etwa viermal längerals Python
Lesbarkeit?
• Ja, eine Zeile Python kann schwerer lesbar sein als eine Zeile Java• Sie tut aber auch die Arbeit von 10 Zeilen Java• Siehe auch: Succinctness is power, Vergleich von Programmiersprachenund in Python from __future__ import braces
16.3.3 Syntax: Semikolon
• Das Semikolon ; am Ende der Zeile mit println?• Anweisungen müssen in Java mit Semikolon beendet werden!
16.3.4 Hello world aus zwei Welten
Python
1 print("Hello World!")
Hello World!
Java (in Datei: HelloWorld.java)
1 class HelloWorld{2 public static void main(String [] args) {3 System.out.println("Hello, world!");4 }5 }
Hello, world!
16.3. Syntax 7
16.3.5 Schlüsselwörter
• Anscheinend benutzt Java Schlüsselwörter• Im Beispiel:
– class ist vertraut* Danach sieht das aus wie eine Methodendeklaration?* Mit einer Methode main?
– static kann man raten* static: Eine Aussage über die Methode main?
· Offenbar: als statische Klassenmethode festlegen– Aber was ist public?
16.3.6 Datentypen
Bei Parameter der Methode
• Die Methode main scheint ein Argument args zu bekommen• String ist wohl ein Hinweis auf einen Datentyp• Und das []-Paar? Irgendwas mit Liste?
Bei Methode
• Rückgabewert der Methode: void– Der leere Typ, also keine Rückgabe
• Durch die Angabe von Typen bei Parameter und Rückgabewert bekommtdie Methode selbst eine (Sammlung von) Typen– Die Signatur der Methode
16.3.7 Kommentare
Java kennt zwei Arten von Kommentaren:
• Bis zum Ende der Zeile, mit zwei Strichen markiert: //• Ein Kommentar über eine oder mehrere Zeilen, mit /* und */ einge-rahmt
1 /* Dieser Programmcode demonstriert lediglich die Kommentare.2 In dieser Zeile geht der Kommentar weiter */3
4 // das hier wäre ein Kommentar, der am Ende der Zeile zuende ist
16.4 Datentypen
8 Liste von Definitionen u.ä.
16.4.1 Einfache Datentypen
Java unterschiedet verschiedene Arten von Datentypen
• Hier zunächst: einfache Datentypen• Zahlen
– Ganze Zahlen, unterschieden nach Speicherplatz* byte, 8 bits* short, 16 bits* int, 32 bits* long, 64 bits
– Fließkommazahlen* float, 32 bits* double, 64 bits
– Mit üblichen arithmetischen Operationen und Vergleichen• Einzelne Zeichen char: In Hochkomma angegeben: ’a’, ’b’
16.4.2 Zuweisungen zwischen Zahlen, implizite typecasts
• Ganze Zahlen und Fließkommazahlen: Kürzere Datentypen können anlängere Datentypen zugewiesen werden– Genauer: Ein Wert vom Typ eines kürzeren Datentyps kann an eineVariable eines längeren Typs zugewiesen werden
– Ähnlich zu: Oberklasse/Unterklasse; aber es sind keine Klassen;Zahlen sind keine Objekte* Anders als: everything is an object in Python* Grund: Effizienz
• Zusätzlich:– long darf an float zugewiesen werden– char darf an int zugewiesen werden
16.4.3 Implizite typecasts in Ausdrücken
Typecasts passieren auch bei derAuswertung von (arithmetischen)Ausdrücken:
• Der kleinereWert wird in den größeren umgewandelt• Dann wird der arithmetische Ausdruck berechnet• Ergebnis hat dann den größeren Typ
Beispiel
• Hier wird die Zahl int 42 zunächst in die entsprechende double 42.0umgewandelt
• Dann passiert die Addition
16.4. Datentypen 9
• Ergebnis hat Wert double
1 (42 + 17.11)
$1 ==> 59.11
Anmerkung: Formatierung der Ausgabe
Die Darstellung der Ausgabe eines Code-Beispiels sieht bei Java ein bisschenanders als bei Python. Insbesondere werden Variablennamen mit angegebenoder, wenn es sich wie hier nur um einen einzelnen Ausdruck handelt, dannwird eine laufende Nummer vorangestellt. Tritt in einer Zuweisung ein Fehlerauf, so produziert dies hier im Skript keinerlei Ausgabe!
16.4.4 Zusammengesetzte Datentypen: Array
• Java kennt – als Teil der Sprache – lediglich einen zusammengesetztenDatentyp: das Array (Feld)– Eine Folge von Elementen identischen Typs– Durch Index sind einzelne Elemente zugreifbar– Elemente dürfen verändert werden
• Notation des Typs: Gewünschter Elementtyp, gefolgt von []• Initialisierung: Literale mit {} aufzählen
– int[] zahlen = {1, 2, 3, 4};• Denken Sie sich ein Array als eine sehr limitierte Variante von Pythonslist– Z.B.: kein einfaches Slicing eines Arrays
16.4.5 Mehrdimensionale Arrays
• Verallgemeinerung: Arrays dürfen mehrere Dimensionen haben– Also zweidimensional: Ein Array von Arrays eines bestimmten Typs
• Notation: Gewünschter Elementtyp, gefolgt von– [][] für zweidimensionale Arrays– [][][] für dreidimensionale Arrays– usw.
• Zugriff: Durch mehrfaches []
16.4.6 Spezialfall: String
• Zeichenketten: Array von Zeichen– Also eigentlich: char[]
• Aber weil wichtiger Spezialfall, eigener Typ: String
10 Liste von Definitionen u.ä.
• Konstanten: In Anführungszeichen eingeschlossen ~". . . "~– Unterscheide: ~’x’~ und ~"x"~ !
• Strings sind Objekte der Klasse String– Methodenbeispiele:length(),charAt(i),indexOf(substring),startsWith(substring), . . .
• Strings sind unveränderlich, immutable
16.4.7 Klassen als Datentypen
• Klassen definierten Typen• Haben eigene, komplexe Syntax zur Definition• Siehe nächstes Kapitel
16.5 Variablendeklarationen und Zuweisungen
16.5.1 Variablendeklaration mit Typen
Definition 16.2 (Vor Benutzung deklarieren). Eine Variable muss vor derersten Benutzung deklariert (dem Compiler bekannt gemacht) werden: IhrName und ihr Typ werden in einer Anweisung angegeben.
Die Benutzung einer nicht deklarierten Variable führt zu einem Fehler beider Übersetzung.
Bei der Deklaration kann eine Variable optional auch mit einem initialenWert versehen werden.
16.5.2 Variablendeklaration mit einfachen Typen: Beispiele
Ohne Initialisierung
Der Wert nicht initialisierter Variablen ist nicht definiert!
1 // Eine Anweisung zur Deklaration der Variable x:2 int x;3
4 // Nach einem Typ dürfen mehrere Variablen stehen, durch Komma getrennt:5 short y, z;6 char u;
16.5. Variablendeklarationen und Zuweisungen 11
16.5.3 Variablendeklaration mit einfachen Typen: Beispiele
Mit Initialisierung
Die initialisierenden Literale müssen von passendem Typ sein
1 int x = 42;2 short y = 17, z=11;3 char u = ’a’;
x ==> 42y ==> 17z ==> 11u ==> ’a’
Fehler bei Initialisierung
Welche dieser drei Anweisungen scheitert/n?
1 int x = ’a’;2 short y = 99999;3 char u = 65;
x ==> 97u ==> ’A’
Anmerkung: Formatierung der Ausgabe
Fehlermeldungen werden bei der Ausgabe unterdrückt!
16.5.4 Anmerkung: Code-Fragmente
Vorsicht, diese Code-Fragmente sind (mit einem Java8-Standard-Version)nicht unmittelbar ausführbar!
• Es fehlt die umgebende Klasse; es gibt keinen Code ausserhalb einerKlasse
• Sie brauchen dazu eine Java9-Beta-Version mit REPL• Oder Sie fügen es in eine Klasse ein (Datei fragment.java):
1 class fragment{2 public static void main(Strings [] args) {
12 Liste von Definitionen u.ä.
3 // hier das Code-Fragment einfügen4 // ...5 }6 }
16.5.5 Zuweisungen, Fall 1: gleicher, einfacher Typ
1 int x = 42;2 int y;3
4 y = x + 1;5
6 char u=’a’;7 char b;8 b = u;
x ==> 42y ==> 0y ==> 43u ==> ’a’b ==> ’’b ==> ’a’
16.5.6 Zuweisungen, Fall 2: kompatibler, einfacher Typ
Tatsächlich sind bereits die einfachen Beispiele von dieser Natur:
• Der Wert 17 ist eigentlich ein byte• Aber da byte an short und short and int zugewiesen werden darf,ist das kein Problem
1 int x;2 x = 17;3
4 float a = 3.14f;5 double b;6 b = a;
x ==> 0x ==> 17a ==> 3.14
16.5. Variablendeklarationen und Zuweisungen 13
b ==> 0.0b ==> 3.140000104904175
Anmerkungen
• Um die Zahl 3.14 an eine float-Variable zuweisen zu können, müssenwir das Literal als solches markieren: wir stellen ein f der Zahl nach
• b hat nicht exakt den Wert 3.14: Es kommt bei der Umwandlung zu Feh-lern und Ungenauigkeiten. Häufiges Problem bei Fliesskommazahlen.
16.5.7 Zuweisungen, Fall 3: nicht kompatibler, einfacher Typ
Was passiert, wenn die rechte Seite einen zu großen Typ hat?
Fließkommazahlen
1 double a = 3.14;2 float b;3 b = a;
1. FehlermeldungCompiler lehnt das ab:
1 | Error:2 | incompatible types: possible lossy conversion from double to float3 | b = a;
Ganze Zahlen
Aber das sollte doch gehen? 42 passt doch in ein short?
1 int x = 42;2 short y;3 y = x;
1. FehlermeldungNein! Der Compiler weiß nicht, wie der tatsächliche Wert aussieht undlehnt diese Zuweisung ab• (Ja, in diesem einfachen Beispiel könnte es der Compiler wissen –im allgemeinen nicht)
14 Liste von Definitionen u.ä.
1 | Error:2 | incompatible types: possible lossy conversion from int to short3 | b = a;
16.5.8 Zuweisung mit expliziten typecasts
Wie wandelt man Typen explizit in einander um?
• Aufforderung an den Compiler, den Verlust an Werten, Genauigkeit, . . .zu akzeptieren
• Notation: Den Zieltyp in Klammern vor den Ausdruck schreiben• Funktioniert auch in Teilausdrücken
1 int x;2 double y = 42.17;3 x = (int) y;4 x = (int) (y + 0.0001);5 x = x + (int) 0.00001;
16.5.9 Zuweisungen einfacher Typen: Werte in Schachteln
• Erinnerung: Primär fassen wir Variablen hier als Schachteln auf, in dieWerte gelegt werden können
• Zuweisung?– Bei einer Zuweisungwird derWert von einer Schachtel in die anderekopiert
1 public class Zuweisung {2 public static void main(String[] args) {3 // Zwei interger-Variablen zuweisen:4 int x, y;5 x = 17;6 y = x;7 }8 }
(PT link)
Visualisierung
Das Verhalten ist hier wie erwartet (Abbildung 16.1): In x und y ist jeweils derWert 17 abgelegt.
16.5. Variablendeklarationen und Zuweisungen 15
Abbildung 16.1: Zuweisung von int-Variablen
16.5.10 Zuweisungen komplexer Typen
Was passiert bei Zuweisungen komplexer Typen?
• Bis jetzt: String und Array
1 public class Zuweisung2 {2 public static void main(String[] args) {3 // Zwei Strings zuweisen:4 String s1 = "Hallo";5 String s2;6 s2 = s1;7 }8 }
(PT link)
Zuweisung von Referenz!
• s1 und s2 speichern gar nicht den Wert!• Sondern zeigen nur darauf?
Visualisierung
Offenbar speichern die Variablen s1 und s2 die Zeichenkette an sich garnicht (Abbildung 16.2). Vielmehr wird dort eine Referenz auf die Zeichenketteabgelegt. Bei der Zuweisung s2 = s1 wird diese Referenz kopiert.
16.5.11 Zuweisung komplexer Typen: Beispiel 2 (Strings verändern)
1 public class Zuweisung3 {2 public static void main(String[] args) {3 // Zwei Strings zuweisen:
16 Liste von Definitionen u.ä.
Abbildung 16.2: Zuweisung von String-Variablen
4 String s1 = "Hallo";5 String s2;6 s2 = s1;7 s1 = s1 + " GP1!";8 System.out.println(s1);9 System.out.println(s2);10 }11 }
(PT link)
Visualisierung
Vor der Zuweisung ans1 zeigen beiden String-Variablen auf das gleicheObjekt.Mit dem Ausdruck s1 + GP1! entsteht ein neues Objekt. Die Variable s1 zeigtdann auf dieses neue Objekt; s1 behält die Referenz auf das alte Objekt bei.(Also ganz ähnlich wie bei Python.) Siehe Abbildung 16.3.
Abbildung 16.3: Zuweisung an Strings: Erzeugen eines neuen Strings durcheinen Ausdruck
16.5.12 Zuweisung komplexer Typen: Beispiel 3 (array)
1 public class ZuweisungA {2 public static void main(String[] args) {3 // Ein Array deklarieren und initialisieren:
16.5. Variablendeklarationen und Zuweisungen 17
4 int[] a1 = {1, 2, 3};5 int[] a2;6 a2 = a1;7 System.out.println(a2[1]);8 a1[1] = 17;9 System.out.println(a2[1]);10 }11 }
(PT link)
Visualisierung
Wie erwartet zeigen sowohl a1 als auch a2 auf das gleiche Array-Objekt. NachÄnderung des ersten Eintrags bei a1 zeigt sich dieser neue Wert, auch wennüber die Variable a2 darauf zugegriffen wird. Abbildung 16.4 illustriert dies.
Abbildung 16.4: Zuweisung von Arrays und Manioulation eines Elementes
16.5.13 Zeiger (Referenzen)
• Variablen eines komplexen Typs speichern nicht den Wert selbst• Vielmehr speichern sie einen Zeiger (eine Referenz) auf den Wert• Das ist ähnlich zur Schild-Vorstellung bei Python
– Allerdings nicht konsequent– Z.B. gibt es keine Referenzen auf Funktionen/Methoden
16.5.14 Unterschiedliche Semantik von Variablen
Insgesamt also:
• Java benutzt unterschiedliche Semantik von Variablen– Einfache Variablen: Schachtel mit Wert
* Sog. primitive types* byte, short, int, long, float, double, boolean, char
18 Liste von Definitionen u.ä.
– Variablen komplexer Typen: Schachtel mit Zeiger (Referenz) aufWert* Sog. reference types* Alle anderen Typen: Array und insbes. alle Klassen
• Das ist ziemlich bad news für einen Sprachentwurf :-(
Semantik der Zuweisung
• Die ist konsistent: Wert in Schachtel kopieren• Konsequenz für Übergabe von Parametern an Methoden (siehe unten)
16.5.15 Unterschiedliche Semantik: Warum?
• Unterscheidung zwischen primitive und reference types einer der kom-plexeren Aspekte von Java
• Warum macht man das? Effizienz!– Man muss nicht alles als Objekt behandeln– Primitive Typen viel einfacher zu handhaben für Zwischensprache
• Nachteil: Signifikante Fehlerquelle– Insbes. bei Methodenaufruf
16.5.16 Kopie des Werts einer Referenzvariable?
• Herstellen einer Kopie zur Zuweisung alleine nicht möglich!• Wir brauchen eine Methode, die das Kopieren übernimmt• Beispiel Array: Wir müssen jeden einzelnen Eintrag des Arrays kopieren
– Arrays definieren Methode: clone
1 public class CopyArray {2 public static void main(String[] args) {3 // Ein Array deklarieren und initialisieren:4 int[] a1 = {1, 2, 3};5 int[] a2;6 a2 = a1.clone();7 System.out.println(a2[1]);8 a1[1] = 17;9 System.out.println(a2[1]);10 }11 }
(PT link)
22
16.6. Kontrollstrukturen: Verzweigungen 19
Visualisierung
Nach Aufruf der Methode a1.clone() existiert ein zweites Array, dessenElement die gleichen Werte haben wie die von a1 (Abbildung 16.5). Durch dieZuweisung a1[17]werden in diesem zweiten Array keine Einträge verändert;a1 und a2 referenzieren verschiedene Objekte.
Abbildung 16.5: Ein Array durch clone kopieren
16.6 Kontrollstrukturen: Verzweigungen
16.6.1 Verzweigungen: if, else
• Normale Verzweigungen ganz ähnlich zu Python• Unterschiede:
– Bedingung muss in Klammern stehen– Einrückung hat kein Bedeutung– Also Optionen nach Ausdruck oder nach else:
* Genau eine Anweisung (mit Semikolon abgeschlossen)* Oder ein Block, in geschweifte Klammern eingeschlossen
16.6.2 ifmit einer Anweisung
1 if (Bedingung)2 // Anweisung für wahr-Fall:3 ...;4 else5 // anweisung für falsch-Fall:6 ...;
Kompakt in einer Zeile
Generell: Zeilenumbruch, Einrückungen sind bedeutungslos!
20 Liste von Definitionen u.ä.
• Nur Hilfe für den Menschen; dem Compiler egal
1 if (Bedingung) ...; else ...;
16.6.3 ifmit Blöcken
1 if (Bedingung) {2 // Anweisung für wahr-Fall:3 ...;4 ...;5 ...;6 } else {7 // anweisung für falsch-Fall:8 ...;9 ...;10 ...;11 }
16.6.4 Dangling else
Ohne Klammern ist folgender Code nicht unmittelbar klar verständlich:
• Zu welchem if gehört das else?• Ein sog. dangling else
1 if (a > b)2 if (a > 0) max = a;3 else4 max = b;
Definition 16.3 (dangling else: Festlegung). Das dangling else erfordert eineFestlegung. Java legt fest: Ein else gehört zum unmittelbar davor stehendenif (es sei denn, geschweifte Klammern bilden Blöcke).
16.6.5 Dangling else (2)
Anmerkung: Einrückung
Die Einrückung im obigen Beispiel legt eine andere Semantik nahe. Zur noch-maligen Betonung: Einrückung ist für den Java-Compiler irrelevant!
16.6. Kontrollstrukturen: Verzweigungen 21
Anmerkung: dangling else in Python?
Das Problem tritt in Python nicht auf; durch die Einrückungsstruktur kann eskeine Mehrdeutigkeit geben.
16.6.6 Dangling else: Äquivalenz
Ohne Klammer (und sinnvoll eingerückt)
1 if (...)2 if (...)3 ...;4 else5 ...;
Äquivalent mit expliziten Klammern
1 if (...) {2 if (...)3 ...;4 else5 ...;6 }
else zum äußeren if: Erfordert Klammern
1 if (...) {2 if (...)3 ...;4 } else5 ...;
16.6.7 Kein elif
• Java kennt keine Struktur die elif entspricht• Im Zweifel durch else if-Struktur nachbauen
16.6.8 switch: Mehrfachverzweigung
Java kennt eine Mehrfachverzweigung: switch
• switch vergleicht einen Ausdruck vom Typ int, short, byte, charoder Stringmit konstantenWert
22 Liste von Definitionen u.ä.
• Jedem konstanten Wert kann ein Block zugeordnet werden– Wird ausgeführt, wenn der Vergleich richtig ist
• Zusätzlich: default- Zweig
16.6.9 switch: Beispiel
1 int month;2 switch (month) {3 case 1, 2, 3, 4, 10, 11, 12:4 System.out.println("Austern essen!");5 case 5, 6, 7, 8, 9:6 System.out.println("Austern vermeiden!");7 default:8 System.out.println("Austern sind nicht das Hauptproblem in diesem Programm!");9 }
16.7 Kontrollstrukturen: Schleifen
16.7.1 while-Schleifen
• Sehr ähnlich zu Python• Schleifenrumpf: Einrückung egal; durch {}markieren
– {} kann entfallen wenn nur eine Anweisung• Bedingung in Klammern
1 while (Bedingung) {2 ...;3 ...;4 }
16.7.2 Variante: do- while -Schleife
• Schleifenrumpf auf jeden Fall einmal ausführen• Bedingung wird am Ende des Rumpfs geprüft, nicht am Anfang• Vorsicht: Nach Bedingung muss ein Semikolon stehen!
1 do {2 ...;
16.7. Kontrollstrukturen: Schleifen 23
3 ...;4 } while (Bedingung);
16.7.3 for-Schleife
Java kennt eine klassische und eine moderne for-Schleife
• Die klassische Variante unterscheidet sich deutlich von der Python for-Schleife– Viel primitiver gestrickt
• Die moderne Variante ist dem Python for viel ähnlicher– Im Sinne von: Iteration über eine Aufzählung
16.7.4 Klassisches for: Ersatz von while-Muster
• Javas klassisches for ist eigentlich nur eine kompakte Notation für einewhile-Schleife mit bestimmtem Muster
• Muster:– Vor der Schleife werden Variablen initialisiert
* Z.B.: Zähler auf 0 setzen– Schleifenbedingung prüfen
* Z.B.: Zähler noch nicht zu groß?– Schleifenrumpf ausführen– Variablen verändern
* Z.B.: Zähler um eins erhöhen
16.7.5 while-Schleife: Beispiel für Muster
Addieren wir die ersten 10 Zahlen auf:
1 //Variable für Ergebnis:2 int summe=0;3 // zaehler initialisieren:4 int zaehler=1;5 while (zaehler <= 10) {6 // Eigentliche Aktion:7 summe += zaehler;8
9 // Zähler erhöhen10 zaehler += 1;11 }12 System.out.println(summe);
24 Liste von Definitionen u.ä.
summe ==> 0zaehler ==> 155
16.7.6 Knapper: for
• Wie üblich: Häufige Muster verdienen Sprachunterstützung• for-Schleife: Spezialisiert auf dieses Muster• Vier Teile:
– Initialisierung von Variablen (auch mehrere) vor der Schleife– Schleifenbedingung– Schleifenrumpf (na klar. . . )– Manipulation der Variablen am Ende des Rumpfs
16.7.7 for-Schleife: Syntax
Vier Teile:
• Drei davon als (sozusagen) Parameter der Anweisung for– Durch Semikolon getrennt!– In Klammer
• Schleifenrumpf analog zu while-Schleife nach der Klammer
1 for ( ... /* Variablen initialisieren */ ;2 ... /* Schleifenbedingung */ ;3 ... /* Variablen manipulieren */ )4 ... ; /* Schleifenrumpf */
16.7.8 for-Schleife: Variablen
Wo kommen Variablen für die Schleife her?
Option 1: Normale Variablen, vorher deklariert
• Behalten nach Schleife den Wert• Ggf. sinnvoll, wenn Variable nach Schleife noch gebraucht wird
Option 2: Variable in Schleifenkopf deklarieren
• Damit eindeutig als Zählvariable für die Schleife markiert• Verschwindet nach der Schleife aus dem Scope• Wenn nach Schleife Bedingung geprüft werden soll, dafür separate Va-riable vorsehen!
• Meist als besserer Stil angesehen
16.7. Kontrollstrukturen: Schleifen 25
1 public class ForVariable {2 public static void main(String[] args) {3 for (int i= 5; i<8; i++) System.out.print(i + ", ");4
5 // Variable i out of scope, das geht nicht:6 // System.out.print(i);7 }8 }
16.7.9 Klassisches for: Beispiel
Geben wir die Zahlen 1 bis 10 aus
1 int i;2 for (i = 1;3 i <= 10;4 i++)5 System.out.println(i);6
7 // und zum Beweis: i hat auch nach der for-Schleife den letzten Wert8 System.out.println(i);
i ==> 01234567891011
Warum ist der Wert von i nach der Schleife 11?
• Beim letzten Durchlauf: 10 ausgeben• Danach wird die Anweisung i++ ausgeführt
– Am Ende jeden Rumpfs!• Danach wird Schleifenbedingung geprüft: 11 <= 10
– Falsch, Schleifenende
26 Liste von Definitionen u.ä.
16.7.10 Beispiel: Multiplikationstabelle ausgeben
Geben wir eine Multiplikationstabelle für die Zahlen 1 bis 10 aus
1 int i, j;2
3 // Kopfzeile der Tabelle4 System.out.print("i\t")5 for (j=1; j <= 10; j++)6 System.out.print("|\t" + j);7 Systme.out.println("\n---------------------------");8
9 // die eigentliche Tabelle:10 for (i=1; i<=10; i++) {11 System.out.print(i + "\t");12 for (j=1; j<=10; j++) {13 System.out.print("|\t");14 System.out.printf("%4s", i*j);15 }16 System.out.println();17 }
i ==> 0j ==> 0i| 1| 2| 3| 4| 5| 6| 7| 8| 9| 101 | 1| 2| 3| 4| 5| 6| 7| 8| 9|102 | 2| 4| 6| 8| 10| 12| 14| 16| 18|203 | 3| 6| 9| 12| 15| 18| 21| 24| 27|304 | 4| 8| 12| 16| 20| 24| 28| 32| 36|405 | 5| 10| 15| 20| 25| 30| 35| 40| 45|506 | 6| 12| 18| 24| 30| 36| 42| 48| 54|607 | 7| 14| 21| 28| 35| 42| 49| 56| 63|708 | 8| 16| 24| 32| 40| 48| 56| 64| 72|80
16.7. Kontrollstrukturen: Schleifen 27
9 | 9| 18| 27| 36| 45| 54| 63| 72| 81|9010 | 10| 20| 30| 40| 50| 60| 70| 80| 90|100
16.7.11 Modernes for: Iterator
• Java kennt für Aufzählungen auch eine for-Schleife mit einem Iterator– Sehr ähnlich zu Pythons for-Schleife– Die Schleifenvariable wird hier in der for-Anweisung samt richti-gem Typ deklariert
• Beispiel:
1 // Ein Array deklarieren und initialisieren:2 int[] primzahlen = {2, 3, 5, 7, 11, 13};3 for (int p: primzahlen)4 System.out.print(p + " ");
primzahlen ==> [I@6e1567f12 3 5 7 11 13
Aufzählungen in Java?
• Arrays sind Aufzählungen und haben einen Iterator• Weitere Aufzählungstypen: Siehe später
16.7.12 Schleifenabbruch: break
• Java kennt ein break analog zu Python– Bricht die innerste Schleife ab
• Erweiterung: Man kann sogar umschliessende Schleifen abbrechen– Durch Benennung der Schleifen– Aber recht unübersichtlich – vermeiden!
16.7.13 Funktionen
• Funktionen außerhalb von Klassen gibt es nicht
16.8 Zusammenfassung
28 Liste von Definitionen u.ä.
16.8.1 Zusammenfassung
• Grundstruktur von Java-Programmen: Alles in einer Klasse– Eine Klasse, eine Datei– Programm kann aus mehreren Dateien, Klassen bestehen– Per import zusammengefügt
• Einmal pro Programm: eine Klasse mit einer Methode static voidmain
• Statisch typisierte Sprache– Für Variablen muss vor Benutzung der Typ deklariert werden– Konsequenzen für Zuweisung und (implizite/explizite) typecasts
• Syntax:– Semikolon nach Anweisungen– Keine Einrückungen sondern Klammern
• Die Unterscheidung zwischen primitiven und Referenztypen macht dieSprache komplex
• Kontrollstrukturen wenig überraschend