Einführung in das Programmieren - IT

Werbung
Modul
Einführung in das Programmieren
Autoren:
Felix Freiling
Philipp Klein
Friedrich-Alexander-Universität Erlangen-Nürnberg
Modul
Einführung in das Programmieren
Studienbrief 1: Eine Einführung in Programmiersprachen
Studienbrief 2: Klassen- und Methodendefinition
Studienbrief 3: Kontroll- und Datenstrukturen
Studienbrief 4: Vererbung, Polymorphie und Generics
Studienbrief 5: Test Driven Development und Debugging
Autoren:
Felix Freiling
Philipp Klein
1. Auflage
Friedrich-Alexander-Universität Erlangen-Nürnberg
© 2015 Friedrich-Alexander-Universität Erlangen-Nürnberg
Lehrstuhl für Informatik 1
IT-Sicherheitsinfrastrukturen
Martensstr. 3
91058 Erlangen
1. Auflage (2. März 2015)
Das Werk einschließlich seiner Teile ist urheberrechtlich geschützt. Jede Verwendung außerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne
Zustimmung der Verfasser unzulässig und strafbar. Das gilt insbesondere
für Vervielfältigungen, Übersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronischen Systemen.
Um die Lesbarkeit zu vereinfachen, wird auf die zusätzliche Formulierung
der weiblichen Form bei Personenbezeichnungen verzichtet. Wir weisen deshalb darauf hin, dass die Verwendung der männlichen Form explizit als
geschlechtsunabhängig verstanden werden soll.
Inhaltsverzeichnis
Seite 3
Inhaltsverzeichnis
Einleitung zu den Studienbriefen
I.
Abkürzungen der Randsymbole und Farbkodierungen . . . . . . . . . . . . . . . . . . . . . . .
II.
Zu den Autoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
III.
Modullehrziele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Studienbrief 1 Eine Einführung in Programmiersprachen
1.1 Lernergebnisse . . . . . . . . . . . . . . . . . . . . . .
1.2 Advance Organizer . . . . . . . . . . . . . . . . . . . .
1.3 Zahlensysteme . . . . . . . . . . . . . . . . . . . . . .
1.3.1 Was passiert bei einer Addition? . . . . . . . .
1.3.2 Umrechnung ins Binärsystem . . . . . . . . . .
1.3.3 Bits und Bytes . . . . . . . . . . . . . . . . . .
1.3.4 Hexadezimalsystem . . . . . . . . . . . . . . .
1.3.5 Operatoren . . . . . . . . . . . . . . . . . . . .
1.3.6 Negative Zahlen . . . . . . . . . . . . . . . . .
1.3.7 Darstellung gebrochener Zahlen . . . . . . . .
1.3.8 Zusammenfassung . . . . . . . . . . . . . . .
1.4 Opcodes und Assembler . . . . . . . . . . . . . . . . .
1.4.1 Opcodes . . . . . . . . . . . . . . . . . . . . .
1.4.2 Vereinfachung durch Assemblersprache . . . .
1.5 Höhere Programmiersprachen . . . . . . . . . . . . . .
1.5.1 Compiler . . . . . . . . . . . . . . . . . . . . .
1.5.2 Java . . . . . . . . . . . . . . . . . . . . . . . .
1.6 Objektorientierte Programmierung: Ein Beispiel . . . .
1.6.1 Öffnen des Projekts . . . . . . . . . . . . . . .
1.6.2 Klassen . . . . . . . . . . . . . . . . . . . . . .
1.6.3 Methoden . . . . . . . . . . . . . . . . . . . .
1.6.4 Attributwerte . . . . . . . . . . . . . . . . . . .
1.7 Zusammenfassung . . . . . . . . . . . . . . . . . . . .
1.8 Übungen . . . . . . . . . . . . . . . . . . . . . . . . .
1.8.1 Erläuterungen zum Übungsablauf . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Studienbrief 2 Klassen- und Methodendefinition
2.1 Lernergebnisse . . . . . . . . . . . . . . . . . . .
2.2 Advance Organizer . . . . . . . . . . . . . . . . .
2.3 IDEs und Texteditoren . . . . . . . . . . . . . . .
2.3.1 Welche Vorteile und Features bieten IDEs?
2.3.2 Welche IDEs gibt es? . . . . . . . . . . . .
2.3.3 Texteditoren . . . . . . . . . . . . . . . .
2.3.4 Worin soll ich Programmieren? . . . . . .
2.4 Was bedeutet Programmieren? . . . . . . . . . .
2.5 Klassendefinition und Attribute . . . . . . . . . .
2.5.1 Schlüsselwort class . . . . . . . . . . . .
2.5.2 Namenskonventionen . . . . . . . . . . .
2.5.3 Attribute . . . . . . . . . . . . . . . . . .
2.6 Methodendefinition . . . . . . . . . . . . . . . . .
2.6.1 Methodenkopf . . . . . . . . . . . . . . .
2.6.2 Methodenrumpf . . . . . . . . . . . . . .
2.7 Einschub: System.out.println() . . . . . . . . . . .
2.8 Variablen . . . . . . . . . . . . . . . . . . . . . .
2.8.1 Casting . . . . . . . . . . . . . . . . . . .
2.8.2 Operatoren bei Zahlen . . . . . . . . . .
2.8.3 Operatoren bei Strings . . . . . . . . . .
2.8.4 Der Modulo-Operator . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6
6
7
8
13
13
13
13
14
16
16
18
19
23
25
30
31
31
31
32
34
34
36
36
36
37
38
40
42
42
47
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
47
47
48
48
49
49
50
50
51
52
52
53
56
56
58
58
59
61
62
62
63
Seite 4
Inhaltsverzeichnis
2.8.5 Auswertungsreihenfolge . . . . . .
2.8.6 Inkrement und Dekrement . . . . .
2.8.7 Anlegen von Objekten . . . . . . . .
2.8.8 Aufrufen von Methoden . . . . . . .
2.8.9 Rückgabe von Werten . . . . . . . .
2.8.10 Kopieren von Objekten . . . . . . .
2.8.11 Gültigkeitsbereich von Variablen . .
2.8.12 Standardwerte und der Wert null .
Die main-Methode . . . . . . . . . . . . . .
Konstruktoren . . . . . . . . . . . . . . . . .
2.10.1 Definition von Konstruktoren . . . .
2.10.2 Der Default-Konstruktor . . . . . . .
Statische Methoden . . . . . . . . . . . . .
2.11.1 Definition von statischen Methoden
2.11.2 Unterschied zu Instanzmethoden . .
Zusammenfassung . . . . . . . . . . . . . .
Beispiel . . . . . . . . . . . . . . . . . . . .
Übungen . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Studienbrief 3 Kontroll- und Datenstrukturen
3.1 Lernergebnisse . . . . . . . . . . . . . . . .
3.2 Advance Organizer . . . . . . . . . . . . . .
3.3 Pakete . . . . . . . . . . . . . . . . . . . . .
3.3.1 Pakete definieren . . . . . . . . . .
3.3.2 Pakete einbinden . . . . . . . . . .
3.3.3 Sichtbarkeiten . . . . . . . . . . . .
3.3.4 Framework und API . . . . . . . . .
3.3.5 Die Java-API . . . . . . . . . . . . .
3.4 Kontrollstrukturen . . . . . . . . . . . . . .
3.4.1 if-Statements . . . . . . . . . . . .
3.4.2 switch-Statements . . . . . . . . .
3.4.3 for-Schleife . . . . . . . . . . . . .
3.4.4 while-Schleife . . . . . . . . . . . .
3.5 Datenstrukturen . . . . . . . . . . . . . . .
3.5.1 Arrays . . . . . . . . . . . . . . . .
3.5.2 ArrayList . . . . . . . . . . . . . . .
3.5.3 HashMap . . . . . . . . . . . . . . .
3.6 Zusammenfassung . . . . . . . . . . . . . .
3.7 Beispiele . . . . . . . . . . . . . . . . . . .
3.8 Übungen . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Studienbrief 4 Vererbung, Polymorphie und Generics
4.1 Lernergebnisse . . . . . . . . . . . . . . . . . . . .
4.2 Advance Organizer . . . . . . . . . . . . . . . . . .
4.3 Vererbung . . . . . . . . . . . . . . . . . . . . . . .
4.3.1 Warum Vererbung? . . . . . . . . . . . . .
4.3.2 Oberklassen und Unterklassen . . . . . . .
4.3.3 Abstrakte Klassen . . . . . . . . . . . . . .
4.3.4 Überschreiben von Methoden . . . . . . . .
4.3.5 Polymorphie . . . . . . . . . . . . . . . . .
4.3.6 Mehrfachvererbung . . . . . . . . . . . . .
4.4 Interfaces . . . . . . . . . . . . . . . . . . . . . . .
4.4.1 Definition . . . . . . . . . . . . . . . . . . .
4.4.2 Einbinden von Interfaces . . . . . . . . . .
4.4.3 Beispielanwendungen . . . . . . . . . . . .
4.4.4 Vererbung vs. Interface . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2.9
2.10
2.11
2.12
2.13
2.14
63
64
65
65
66
68
69
70
71
72
73
74
76
76
77
78
78
80
85
85
85
85
86
87
87
92
92
92
93
99
101
103
104
104
109
112
114
115
116
121
121
121
121
121
122
125
126
129
132
132
132
132
133
135
Inhaltsverzeichnis
4.5
4.6
4.7
4.8
Seite 5
Generics . . . . . . . . . .
4.5.1 Definition . . . . .
4.5.2 Einschränkungen
Zusammenfassung . . . .
Beispiel . . . . . . . . . .
Übung . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Studienbrief 5 Test Driven Development
5.1 Lernergebnisse . . . . . . . . . . . .
5.2 Advance Organizer . . . . . . . . . .
5.3 Debugging und Refactoring . . . . .
5.4 Test Driven Development (TDD) . . .
5.5 JUnit . . . . . . . . . . . . . . . . . .
5.6 Zusammenfassung . . . . . . . . . .
5.7 Übungen . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
und Debugging
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Anhang
A.
Beispiel: User . . . . . . . . . . . . . . . . .
A.1
Anforderungen . . . . . . . . . . . .
A.2
Vorüberlegungen . . . . . . . . . .
A.3
Implementierung . . . . . . . . . .
B.
Beispiel: User (Fortsetzung) . . . . . . . . .
B.1
Anforderungen . . . . . . . . . . . .
B.2
Vorüberlegungen . . . . . . . . . .
B.3
Implementierung . . . . . . . . . .
C.
Beispiel: Summe aller Werte in einer Matrix
C.1
Anforderungen . . . . . . . . . . . .
C.2
Vorüberlegungen . . . . . . . . . .
C.3
Implementierung . . . . . . . . . .
D.
Beispiel: Verkaufsautomat . . . . . . . . . .
D.1
Anforderungen . . . . . . . . . . . .
D.2
Vorüberlegungen . . . . . . . . . .
D.3
Das User-Interface . . . . . . . . . .
D.4
Implementierung . . . . . . . . . .
D.5
Verbesserungen und Ausblick . . . .
E.
Beispiel: Eigene ArrayList-Klasse . . . . . .
E.1
Anforderung . . . . . . . . . . . . .
E.2
Vorüberlegungen . . . . . . . . . .
E.3
Implementierung . . . . . . . . . .
E.4
Verbesserungen . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
145
145
145
145
146
146
146
147
153
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Liste der Lösungen zu den Kontrollaufgaben
Verzeichnisse
I.
Abbildungen . .
II.
Beispiele . . . .
III.
Definitionen . . .
IV.
Exkurse . . . . .
V.
Kontrollaufgaben
VI.
Tabellen . . . . .
VII. Literatur . . . . .
136
136
138
139
140
141
154
154
155
156
159
159
159
160
165
165
165
165
167
167
167
171
172
178
179
179
179
179
182
183
187
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
187
187
187
188
188
189
189
Seite 6
Einleitung zu den Studienbriefen
Einleitung zu den Studienbriefen
I. Abkürzungen der Randsymbole und Farbkodierungen
Beispiel
B
Definition
D
Exkurs
E
Kontrollaufgabe
K
Quelltext
Q
Übung
Ü
Zu den Autoren
Seite 7
II. Zu den Autoren
Felix Freiling ist Inhaber des Lehrstuhls für IT-Sicherheitsinfrastrukturen an der
Friedrich-Alexander-Universität Erlangen-Nürnberg. Schwerpunkte seiner Arbeitsgruppe in Forschung und Lehre sind offensive Methoden der IT-Sicherheit, technische Aspekte der Cyberkriminalität sowie digitale Forensik.
Philipp Klein ist seit November 2013 wissenschaftlicher Mitarbeiter am Lehrstuhl
für IT-Sicherheitsinfrastrukturen unter der Leitung von Prof. Dr. Felix Freiling.
Im Oktober 2013 erhielt er seinen Abschluss Master of Science in Informatik an
der Friedrich-Alexander-Universität Erlangen-Nürnberg. Während des Masterstudiums legte er seinen Schwerpunkt auf das Thema IT-Sicherheit. Er besitzt
einen Bachelor-Abschluss im Fach Wirtschaftsinformatik der Georg-Simon-OhmHochschule Nürnberg.
Seite 8
Einleitung zu den Studienbriefen
III. Modullehrziele
In dieser Lehrveranstaltung lernen Sie, die Programmiersprache Java zu nutzen, um selbstständig Programme
zu schreiben. Nach Lektüre dieses Moduls sind Sie in der Lage, die meisten Programmieraufgaben, die an
Sie gestellt werden, zu lösen. Sollten Sie ein bestimmtes Konstrukt der Sprache noch nicht gelernt haben, so
können Sie es sich selbstständig in kurzer Zeit aneignen.
Darüber hinaus können Sie sich weitere Programmiersprachen selbstständig aneignen. Die Prinzipien und
Strukturen, die Sie in dieser Lehrveranstaltung erlernen, finden Sie in den meisten anderen Programmiersprachen wieder. Java bietet dabei einen guten Startpunkt, sowohl hardwarenähere Sprachen als auch
beispielsweise Skriptsprachen zu erlernen.
Programmieren ist etwas, das man weniger aus Büchern lernt, sondern anwenden und beherrschen muss.
Aus diesem Grund sind im Studienbrief viele Kontrollaufgaben, die Sie bearbeiten können. Die Lösungen
finden Sie am Ende des Studienbriefs. Darüber hinaus müssen Sie Übungsaufgaben bearbeiten, die Sie am
Ende jedes Studienbriefs finden. Das Bearbeiten dieser Aufgaben ist Pflicht, sodass Sie gezwungen sind,
wirklich zu programmieren. Gleichzeitig bietet das Abgabesystem aber genug Freiheit, um sich die Zeit
selbstständig einzuteilen.
Dieses Modul teilt sich in zwei Lehrveranstaltungen auf. In dieser Lehrveranstaltung erlernen Sie die Grundlagen von Java und des Programmierens. In der zweiten Lehrveranstaltung werden einzelne Aspekte von
Java genauer betrachtet sowie die Theorie hinter der Programmierung erklärt.
In Studienbrief 1 wird zunächst das Dualsystem, dass die Grundlage einer Programmiersprache darstellt,
betrachtet. Sie lernen, wie Zahlen im Dualsystem dargestellt und verrechnet werden können und welche
Sprache ein Computer spricht. Am Ende dieses Studienbriefs lernen Sie interaktiv die Programmiersprache
Java kennen.
In Studienbrief 2 werden Sie erstmals selbst Programmcode schreiben. Sie erlernen den allgemeinen Aufbau
von Klassen und Methoden.
Studienbrief 3 geht näher auf das Innenleben von Methoden ein. In diesem Studienbrief erlernen Sie Kontrollund Datenstrukturen, durch die Sie komplexen Code schreiben können. Nach diesem Studienbrief ist Ihre
„Grundausbildung“ im Programmieren abgeschlossen. In den folgenden Studienbriefen verfeinern Sie dann
Ihr Wissen.
In Studienbrief 4 lernen Sie wichtige Konzepte der objektorientierten Programmierung kennen. Mit Vererbung
können Sie Attribute und Methoden vererben. Über Interfaces können Sie versprechen geben, was Ihre Klasse
alles kann. Mittels Generics legen Sie sich nicht fest, was für Daten Ihre Klassen speichern können.
Der 5. Studienbrief bildet den Abschluss dieser Lehrveranstaltung. Dieser Studienbrief unterscheidet sich
stark von den vorherigen, da hier hauptsächlich theoretisches oder sehr spezielles Wissen vermittelt wird.
Aus diesem Grund lernen Sie den Großteil des Stoffs nicht aus diesem Studienbrief, sondern aus Videos.
Zusätzlich zu den Videos werden Zusammenfassungen des Stoffs angeboten, die Ihnen als Lernstütze helfen
sollen.
Dieser Studienbrief baut zu Beginn auf dem Buch Java lernen mit BlueJ von Barnes and Kölling [2013]
auf, entfernt sich dann aber immer mehr von dem Buch. Trotzdem kann dieses Buch, so wie viele andere
Bücher, anstelle dieses Studienbriefs genutzt werden, da alle dasselbe Wissen vermitteln. Nutzen Sie die
Materialien, mit denen Sie am besten zurechtkommen. Als Nachschlagewert kann das Buch Handbuch
der Java-Programmierung von Krüger and Stark [2009] empfohlen werden. Wenn Sie eine lockere, witzige
Herangehensweise an das Thema bevorzugen, können Sie das Buch Java von Kopf bis Fuss von Sierra and
Bates [2006] ausprobieren. Zu Test Driven Development in Java empfehlen wir das Buch Test Driven: Practical
TDD and Acceptance TDD for Java Developers von Koskela [2007].
Modullehrziele
Seite 9
Modulbeschreibung
Modulbezeichnung:
Grundlagen der Programmierung
Studiengang:
Bachelor IT-Sicherheit
Verwendbarkeit:
Dieses Modul ist verwendbar für
• Studierende der Informatik
• Studierende der Wirtschaftsinformatik
• Studierende der Mathematik und Informatik
auf Bachelorniveau. Dieses Modul kann nicht als Wahlpflichtmodul gewählt werden, sondern ist ein Pflichtmodul.
Lehrveranstaltungen und
Lehrformen:
Einführung in das Programmieren
Programmierkonzepte
Modulverantwortliche(r):
Prof. Dr. Felix Freiling
Lehrende:
Prof. Dr. Felix Freiling
Dauer:
2 Semester
Credits:
10 ECTS
Studien- und Prüfungsleistungen:
Schriftliche Prüfung: 120 Minuten
Um zur Prüfung zugelassen zu werden, müssen die bereitgestellten Übungsaufgaben in jeder Lehrveranstaltung zu mindestens
70% richtig bearbeitet werden.
Berechnung der Modulnote:
Notwendige Voraussetzungen:
Empfohlene Voraussetzungen:
Keine
Unterrichts- und Prüfungssprache:
Deutsch
Zuordnung des Moduls zu den
Fachgebieten des Curriculums:
Einordnung ins Fachsemester:
Ab Studiensemester 1
Generelle Zielsetzung des Moduls:
Modul zur Förderung und Verstärkung der Fachkompetenz
Seite 10
Arbeitsaufwand bzw.
Gesamtworkload:
Einleitung zu den Studienbriefen
Für dieses Modul:
Präsenzzeit: 60 h
• Vorlesungsteil: 20 h
• Übungsteil: 10 h
• Praktischer Teil: 20 h
• Prüfungsvorbereitungsveranstaltung: 8 h
• Prüfung: 2 h
Eigenstudium: 240 h
• Durcharbeiten der Studienbriefe: 100 h
• Wahrnehmen der Online Betreuung und Beratung: 20 h
• Ausarbeiten von Aufgaben: 100 h
• Individuelle Prüfungsvorbereitung der Studierenden: 20 h
Modullehrziele
Lerninhalt und Niveau:
Seite 11
Einführung in das Programmieren
Eine Einführung in die Programmiersprache Java. Mit Hilfe der
Entwicklungsumgebung BlueJ wird den Studierenden der Umgang mit Java und Objektorientierung vertraut gemacht. Themen
sind unter anderem:
• Ausdrücke und Algorithmische Kernsprache von Java
• Sprachbeschreibung und Objekttypen
• Eine Einführung in bereits existierende Methoden und Klassen in der Programmiersprache Java
• Testen und Test Driven Development mit JUnit
Darüber hinaus erhalten die Studierenden einen praktischen Einblick in die folgenden programmierrelevanten Technologien/Techniken:
• Versionsverwaltung mit Git
• Modellierung mit UML
Programmierkonzepte
Diese Lehrveranstaltung knüpft nahtlos an die Veranstaltung „Einführung in das Programmieren“ an. Die Studierenden lernen weitere Komponenten der Programmiersprache Java kennen, wie
beispielsweise:
• Exceptionhandling
• I/O-Verarbeitung
• Hauptspeichermanagement
• Krypto-/Security-Klassen
• Einbinden von Datenbanken
Neben diesen Inhalten lernen die Studierenden ebenso theoretische Grundlagen der Programmierung kennen, wie die Laufzeitanalyse und die Korrektheit von Algorithmen.
Das Niveau der Lerninhalte liegt gemessen am DQR-Niveau bei 6
(Bachelor)
Seite 12
Angestrebte Lernergebnisse:
Einleitung zu den Studienbriefen
Fachkompetenz: Die Studierenden können beliebige Programme
in Java erstellen. Sprachkomponenten, die Sie noch nicht kennen,
können Sie sich in kürzester Zeit aneignen. Zudem sind die Studierenden in der Lage, sich selbstständig neue Programmiersprachen
beizubringen. Sie schreiben sichere Programme und wissen, wo
potenzielle Schwachstellen in einem Programm zu finden sind.
Methodenkompetenz: Die Studierenden beherrschen den Umgang
mit beliebigen IDEs. Sie können fremde Programme untersuchen und den Kontrollfluss nachvollziehen. Sie sind in der Lage,
Schwachstellen und Fehler in einem Programm zu finden und zu
beseitigen.
Sozialkompetenz: Durch das gemeinsame Lösen von Aufgaben erlangen die Studierenden die Fähigkeit, eigene Handlungsziele
mit den Einstellungen und Werten einer Gruppe zu verknüpfen
und ihre Teamfähigkeit zu stärken. In der Präsenzphase erlangen
sie u. a. durch Pair-Programming die Kompetenz, eigene Ideen
gegenüber einem anderen Programmierer zu kommunizieren,
Kompromisse zu bilden und diese im Team umzusetzen.
Selbstkompetenz: Die Studierenden erlangen die Fähigkeit zur Bildung einer Meinung über eigene Programme und Programme
anderer. Darüber hinaus erlangen sie die Fähigkeit, in komplexen
Situationen zu handeln und eine Lösung für komplexe Probleme
zu finden.
Häufigkeit des Angebots:
Wintersemester
Anerkannte Module:
Anerkannte anderweitige Lernergebnisse / Lernleistungen:
Medienformen:
Literatur:
Studienbriefe in schriftlicher und elektronischer Form, Onlinematerial in Lernplattform, Übungen und Projekt über Lernplattform,
Online-Konferenzen, Chat und Forum, Präsenzveranstaltung mit
Rechner und Beamer
• IT-Sicherheit, Claudia Eckert, 2012
• Java lernen mit BlueJ, David J. Barnes, Michael Kölling, 2013
• Weitere Literatur wird in der Lehrveranstaltung bekannt
gegeben.
Studienbrief 1 Eine Einführung in Programmiersprachen
Studienbrief 1 Eine Einführung in Programmiersprachen
1.1 Lernergebnisse
Dieser Studienbrief gibt Ihnen einen Überblick darüber, wie man mithilfe einer
Programmiersprache mit einem Computer kommuniziert. Am Ende dieses Studienbriefs wissen Sie, was genau eine Programmiersprache ist. Sie sind mit verschiedenen Zahlensystemen vertraut und können demzufolge Zahlen und unterschiedliche Zahlensysteme darstellen und interpretieren. Sie kennen einige
Operationen, die auf binäre Zahlen angewandt werden können. Darüber hinaus
verstehen Sie, wie das Dualsystem mit Programmiersprachen zusammenhängt.
Des Weiteren haben Sie bereits erste Erfahrungen mit der Programmiersprache
Java sowie der IDE BlueJ gesammelt. Sie kennen bereits den Unterschied zwischen
Klassen und Objekten und wissen, was Methoden und Parameter sind.
1.2 Advance Organizer
Um zu verstehen, was eine Programmiersprache ist, muss zunächst verstanden
werden, wie ein Computer generell arbeitet. Aus diesem Grund betrachten wir in
diesem Studienbrief das Binärsystem detailliert. Das Grundwissen, dass in diesem
Studienbrief behandelt wird, hilft Ihnen, Programmiersprachen und speziell Java
besser zu verstehen. Das Wissen, das Sie erwerben, wird Sie in Ihrem gesamten
Informatik-Studium begleiten.
Bei objektorientierten Programmiersprachen ist es zudem wichtig, den Unterschied
zwischen einem Objekt und einer Klasse zu kennen. Durch ein interaktives Tutorial
am Ende dieses Studienbriefs werden Ihnen diese Kenntnisse vermittelt. Dies
dient der Vorbereitung auf den nächsten Studienbrief, in dem Sie selbst Quellcode
schreiben müssen.
1.3 Zahlensysteme
Ein Computer (oder besser: der Prozessor/die CPU) versteht keine normale
menschliche Sprache. Wenn Sie ihm sagen „Rechne 1+1“, passiert vermutlich
zunächst einmal gar nichts. Wenn Sie den Befehl in eine Datei schreiben, wird
ebenso nichts passieren.
Ein Computer versteht im Grunde nur 0en und 1en. Ein Befehl an den Computer
muss daher mit eben diesen 0en und 1en ausgedrückt werden. Diese Art von
Sprache wird auch Maschinensprache genannt. Sie basiert auf dem Binär- oder
Dualsystem, das wir auf den nächsten Seiten näher betrachten werden.
Im alltäglichen Leben rechnen wir im Dezimalsystem. Um sich vor Augen zu führen,
was das genau bedeutet, betrachten wir die Zahl 109 (Einhundertneun). Diese Zahl
besteht aus 3 Dezimalstellen: Einer, Zehner und Hunderter. Jede Dezimalstelle
kann 10 verschiedene Werte annehmen: Die Werte von 0 bis 9. Aus diesem Grund
bezeichnen wir dieses System als Dezimalsystem. Die Zahl 10 wird auch als Basis
bezeichnet. Die Basis kann bei einer Zahl abgesetzt dahinter geschrieben werden:
10910 . Eine weitere gängige Kennzeichnung einer Dezimalzahl ist ein abgesetztes
„d“ hinter der Zahl: 109d .
Neben dem Dezimalsystem gibt es aber theoretisch unendlich viele andere Zahlensysteme, die eine andere Basis besitzen. Relevant sind lediglich einige Wenige: Das
Seite 13
Seite 14
Studienbrief 1 Eine Einführung in Programmiersprachen
Zahlensystem zur Basis 2 (auch Binärsystem oder Dualsystem), das System zur Basis
8 (Oktalsystem), zur Basis 10 (Dezimalsystem) und zur Basis 16 (Hexadezimalsystem).
D
Definition 1.1: Zahlensysteme
Ein Zahlensystem zur Basis n kann pro Stelle die Zahlen 0 bis n − 1 darstellen.
Bei den Zahlensystemen, mit denen wir uns beschäftigen, handelt es sich um
polyadische Zahlensysteme. In einem polyadischen Zahlensystem hängt der Wert
einer Ziffer von seiner Position bzw. Stelle ab. Was das bedeutet, wird deutlich,
wenn wir uns wiederum die Zahl 109 ansehen. Obwohl die 1 an der zweiten Stelle
(wir beginnen rechts mit Null zu zählen) vom Betrag her eindeutig kleiner ist als
die 9 an der nullten Stelle, ist ihr Wert jedoch höher. Um den Wert w der gesamten
Zahl zu erhalten, müssten wir Folgendes tun:
w(109) = 1 · 102 + 0 · 101 + 9 · 100 = 109
Im Dezimalsystem ist dies natürlich trivial, da wir die Zahl, wenn wir sie sehen,
sofort mit der korrekten Wertigkeit aussprechen. Theoretisch müsste man obere Zeile so lesen: „Der Wert der Zahl Eins-Null-Neun ist Einhundertneun“. Die
obere Formel lässt sich verallgemeinert auf jedes Zahlensystem anwenden, wie
Definition 1.2 zeigt.
D
Definition 1.2: Wertigkeit einer Zahl
Der Wert einer Zahl
an . . . a2 a1 a0
zur Basis b, wobei an die Ziffer mit dem Wert a an der n-ten Stelle der Zahl
ist, wird folgendermaßen berechnet:
w(an . . . a2 a1 a0 ) = an · bn + · · · + a2 · b2 + a1 · b1 + a0 · b0
1.3.1 Was passiert bei einer Addition?
Um zu verdeutlichen, wie eine Zahl in einem anderen Zahlensystem (speziell im
Binärsystem) ausgedrückt wird, betrachten wir zunächst, was bei einer Addition
im Dezimalsystem passiert.
Wenn wir die Zahl 109 um eins erhöhen, passiert folgendes: Da die maximal
darstellbare Zahl im Dezimalsystem die 9 ist, wird diese Zahl auf 0 gesetzt. Dafür
wird die nächsthöhere Dezimalstelle um eins erhöht. Wir sprechen auch von einem
sogenannten „Übertrag“. Das Ergebnis ist die Zahl 110.
Wie verhält es sich nun, wenn wir nicht zur Basis 10, sondern zur Basis 2 rechnen?
Wir können nur die Ziffern 0 und 1 pro Binärstelle darstellen. Wir nennen eine
Binärstelle auch „Bit“. Betrachten wir folgende binäre Zahl: 02 . Die binäre Null
entspricht der dezimalen Null. Wenn wir zu dieser Zahl eins hinzuaddieren, ist das
Ergebnis 12 . Wenn wir diese Zahl wiederum um eins erhöhen, passiert Folgendes:
Da das nullte Bit (wie bei Dezimalzahlen steht die niederwertigste Ziffer ganz
rechts) bereits den Wert eins hat, kommt es zu einem Überlauf. Das nullte Bit hat
nun wieder den Wert 0, das erste Bit wird durch Übertrag um eins erhöht. Das
1.3 Zahlensysteme
Seite 15
Ergebnis ist also: 102 . Dies entspricht der Dezimalzahl 2, da 1 + 1 = 2. Bei weiterer
Addition von 1 ist das Ergebnis 112 , darauf folgt 1002 usw.
Wie ist nun bspw. der dezimale Wert der Zahl 01102 ? Ganz offensichtlich kann es
sich nicht um die Zahl Einhundertzehn handeln. Zur Umrechnung benutzen wir
die Formel, die wir in Definition 1.2 kennengelernt haben.
01102 = 0 · 23 + 1 · 22 + 1 · 21 + 0 · 20 = 410 + 210 = 610
Die binäre Zahl 01102 entspricht also dem dezimalen Wert 5. In Tabelle 1.1 können
Sie für die Dezimalzahlen 0 bis 7 die entsprechenden Zahlen im Dualsystem
betrachten.
Dezimal
0
1
2
3
4
5
6
7
Binär
0000
0001
0010
0011
0100
0101
0110
0111
Kontrollaufgabe 1.1: Umrechnung ins Dezimalsystem
Rechnen Sie folgende binäre Zahlen ins Dezimalsystem um:
• 11001100
Tabelle 1.1: Dezimalzahlen und ihre Entsprechung im Binärsystem
K
• 11111111
• 00000001
• 10000000
Kontrollaufgabe 1.2: Oktalsystem
Rechnen Sie folgende Zahlen, die sich im Oktalsystem (Basis 8) befinden,
ins Dezimalsystem um:
• 0010
K
• 7777
• 4706
• 6403
Kontrollaufgabe 1.3: Zweierpotenzen
Prägen sie sich die Zweierpotenzen von 20 bis 210 ein. Sie werden sie häufig
brauchen.
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024
K
Seite 16
Studienbrief 1 Eine Einführung in Programmiersprachen
1.3.2 Umrechnung ins Binärsystem
Wir sind nun also in der Lage, Zahlen aus dem Binärsystem ins Dezimalsystem
umzurechnen. Wir sieht es andersherum aus? Wir wollen die Zahl 11010 im Binärsystem darstellen. Dazu teilen wir diese Zahl durch die Basis (in unserem Fall 2),
bis wir als Ergebnis 0 erhalten. Dabei verwenden wir die ganzzahlige Division mit
Rest. Und genau diese Reste werden, wie sie in Abbildung 1.1 sehen, die gesuchte
Binärzahl ergeben.
Abb. 1.1: Umrechnung vom Dezimalins Binärsystem am
Beispiel von 110.
Wir teilen zu Beginn die Zahl 110 durch 2. Das Ergebnis ist 55 mit einem Rest von
0. Diese 0 ist das niederwertigste Bit (auch least significant bit) unserer gesuchten
Binärzahl. Da das Ergebnis ungleich 0 ist, teilen wir es wiederum durch 2. Diesmal
ist das Ergebnis 27 mit einem Rest von 1. Diese 1 ist das zweit-niederwertigste
Bit. Da 27 immer noch größer als 0 ist, teilen wir wieder durch 2. Das Ganze
wiederholen wir so lange, bis das Ergebnis 0 ist. Anhand der Reste erhalten wir
die gesuchte Binärzahl: 11010 = 11011102 .
In diesem Beispiel haben wir durch die Zahl 2 geteilt, da wir ins Binärsystem
umrechnen wollten. Analog können wir auch bspw. durch 8 teilen, um ins Oktalsystem zu konvertieren. Die Umrechnung von Zahlen können Sie mit der folgenden
Kontrollaufgabe üben.
K
Kontrollaufgabe 1.4: Zahlenkonvertierung
Konvertieren Sie die folgenden Zahlen ins Binär- und Oktalsystem:
• 102310
• 59810
• 97610
1.3.3 Bits und Bytes
In der Informatik treffen wir nicht nur auf den Begriff Bit, sondern auch auf
den Begriff Byte. Ein Byte sind 8 Bit. Bei der Größe von Datenträgern stoßen wir
zudem auf Größen wie „100 Gigabyte“ oder „1 Terabyte“. Bei der Umrechnung in
Bit ist aber Vorsicht geboten: Hier muss u. a. zwischen Binär- und Dezimalpräfix
unterschieden werden.
Dezimalpräfixe benutzen wir im alltäglichen Leben bspw. bei Längen- oder Gewichtsangaben. So ist ein Zentimeter ein hundertstel Meter, ein Kilometer sind
1000 Meter. Die Umrechnungszahl ist eine Zehnerpotenz, was naheliegend ist, da
wir im Dezimalsystem rechnen. Bei einem Kilobyte würde es sich demzufolge um
1000 Byte handeln. Richtig? Falsch? Kommt darauf an.
Da der Computer im Binärsystem rechnet, ist eine Zehnerpotenz für die Umrechnung ungünstig. Eine Zweierpotenz würde mehr Sinn machen. Bis zum Jahr 1996
1.3 Zahlensysteme
Seite 17
gab es keine Einheitenvorsätze, sodass bspw. für das Dezimalpräfix „Kilo“ die
Umrechnungszahl 1024 genutzt wurde. Es wurde aber ebenso gerne eine Zehnerpotenz genutzt (in diesem Fall 1000). Teilweise treten sogar Mischformen auf, wie
bspw. bei der Größe einer 3,5-Zoll-Diskette (siehe Exkurs 1.1). Wenn man also
die Größenangabe „10 Kilobyte“ hört, kann man nicht genau wissen, ob es sich
10 · 1024 Byte oder nur um 10 · 1000 Byte handelt. Aus diesem Grund schlug die
IEC neue Einheitenvorsätze vor, die Binärpräfixe verwenden.
Für die Binärpräfixe nehmen wir das Dezimalpräfix, entfernen die zweite Silbe,
und setzen stattdessen „bi“ ein. Aus „Kilo“ wird „Kibi“, aus „Mega“ „Mebi“,
aus „Tera“ „Tebi“ usw. Bei den Binärpräfixen ist die Umrechnungszahl stets eine
Zweierpotenz, sodass keine Unklarheiten entstehen können. Aus Tabelle 1.2 können
Sie noch einmal gesondert Präfixe und Umrechnungszahlen entnehmen.
Dezimalpräfix
Kürzel
Umrechung
Binärprefix
Kürzel
Umrechnung
Kilo
kB
oder
KB
1kB = 103 Bytes
oder
210 Bytes
Kibi
KiB
1KiB = 210 Bytes
Mega
MB
1MB = 106 Bytes
oder
220 Bytes
Mebi
MiB
1MiB = 220 Bytes
Giga
GB
1GB = 109 Bytes
oder
230 Bytes
Gibi
GiB
1GiB = 230 Bytes
Tera
TB
1TB = 1012 Bytes
oder
240 Bytes
Tebi
TiB
1TiB = 240 Bytes
Exkurs 1.1: 3,5-Zoll-Disketten
Die Größe von 3,5-Zoll-Disketten wurde mit 1,4 MB angegeben. Wieviel
Speicherplatz war also auf solch einer Diskette vorhanden? Zwei Lösungen
würden Sinn machen:
1. 1, 4 · 1000 · 1000 = 1.400.000 Byte
2. 1, 4 · 1024 · 1024 = 1.468.006 Byte
Tatsächlich ist keine der beiden Antworten richtig. Bei der Umrechnung von
Mega- in Kilobyte wird die Zahl 1000 genutzt, bei der Umrechnung von Kiloin Byte die Zahl 1024. Es standen also
1, 4 · 1000 · 1024 = 1.433.600 Byte
Speicherplatz zur Verfügung.
Tabelle 1.2: Binär- und
Dezimalpräfixe im Vergleich. Die Kürzel beziehen sich auf die ByteSchreibweise.
E
Seite 18
Studienbrief 1 Eine Einführung in Programmiersprachen
Exkurs 1.2: Einheitliches Format
E
Man könnte meinen, durch die Einführung der Binärpräfixe wüsste man
ganz genau, wie viel Speicherplatz ein Medium hat. Leider ist das nicht
der Fall, da so gut wie jeder weiterhin auf Dezimalpräfixe zurückgreift.
Hinzu kommt, dass bspw. Festplattenhersteller gerne eine Zehnerpotenz
als Umrechnungszahl verwenden.
Wenn Sie also eine 1-TB-Festplatte kaufen, müssen Sie sich in Zukunft nicht
wundern, wenn ihr Betriebssystem nur eine Festplattenkapazität von rund
0.9 TB erkennt. Das Betriebssystem rechnet in Zweierpotenzen (benutzt aber
zur Anzeige dennoch Dezimalpräfixe . . . ).
K
K
Kontrollaufgabe 1.5: Downloadgeschwindigkeit
Ihr Internetprovider bietet Ihnen „DSL 16.000“ an. Finden Sie heraus, was
das bedeutet und wie die Provider gewöhnlich umrechnen. Geben Sie im
Anschluss die maximale Downloadgeschwindigkeit in MiB/s an.
Kontrollaufgabe 1.6: Speicherplatz einer DVD
Auf eine DVD passen 4, 7 GB. Recherchieren Sie, ob die Hersteller mit Zweieroder Zehnerpotenzen rechnen. Falls sie Zehnerpotenzen nutzen: Wie viel
GiB stehen tatsächlich zur Verfügung? Wie hoch ist der prozentuale Unterschied?
1.3.4 Hexadezimalsystem
Neben dem Binärsystem spielt in der Informatik das Hexadezimalsystem (System
zur Basis 16) eine große Rolle. Zahlen im Hexadezimalsystem kann man mit einem
0x vor der Zahl kennzeichnen. Wenn die Zahl 0x9 im Hexadezimalsystem um eins
erhöht wird, ist das Ergebnis 0xa oder auch 0xA. Dies entspricht dem dezimalen
Wert 10. Bei weiterer Addition werden die Buchstaben gemäß Alphabet fortgesetzt.
Nach der Zahl 0xf kommt es zum gewohnten Übertrag.
Tabelle 1.3: Hexadezimalzahlen und
ihre Entsprechung
im Dezimalsystem.
Dezimal
9
10
11
12
13
14
15
16
Hexadezimal
0x09
0x0a
0x0b
0x0c
0x0d
0x0e
0x0f
0x10
Alle Rechenregeln, die wir kennengelernt haben (sprich das Umrechnen vom
Dezimal- ins Binärsystem und umgekehrt), gelten auch im Hexadezimalsystem.
Der Grund dafür, dass das Hexadezimalsystem in der Informatik eine große Rolle
spielt, ist folgender: 4 Bit lassen sich zu einer einstelligen Hexadezimalzahl zusammenfassen, zwei Hexadezimalziffern ergeben ein Byte. Dadurch lässt sich viel
Schreibarbeit ersparen, Zahlen können kompakter dargestellt werden. Zudem
1.3 Zahlensysteme
Seite 19
können Binärzahlen in Viererblöcke unterteilt und einzeln in Hexadezimalzahlen umgewandelt werden, wodurch sich Zahlen deutlich schneller umrechnen
lassen.
Beispiel 1.1: Hexadezimalzahlen
B
01102 → 0x06
1111 11112 → 0x f f
0101 0101 1010 1010 → 0x55aa
1.3.5 Operatoren
Die Grundrechenarten (Addition, Subtraktion, Multiplikation, Division) können
auch im Dualsystem benutzt werden. Wir beschränken uns in diesem Modul auf
die Addition und Subtraktion, die im Folgenden erläutert werden.
Addition
Bei der Addition zweier Binärzahlen gehen wir genau so vor, wie wir auch im
Dezimalsystem vorgehen würden. Wir beginnen beim least significant bit. Wenn
wir zwei Einsen addieren, kommt es zu einem Übertrag auf die nächsthöhere
Binärstelle. Das Ergebnis von 12 + 12 ist also 02 mit einem Übertrag von 12 . In
Gleichung 1.1 ist eine Beispielrechnung gezeigt, in der die Zahlen 101 11102 und
10112 addiert werden.
+
1011110
1011
1101001
(1.1)
An der dritten Stelle haben wir sowohl die Addition von 12 und 12 als auch einen
Übertrag von der vorherigen Stelle. Das Ergebis ist 12 mit einem Übertrag von 12 .
Ansonsten gibt es bei dieser Additionsaufgabe nichts zu beachten.
Kontrollaufgabe 1.7: Addition
Lösen Sie die folgenden Aufgaben im Binärsystem. Rechnen Sie im Anschluss die Zahlen ins Dezimalsystem um und prüfen Sie Ihre Ergebnisse.
• 10102 + 11112
• 1010 10102 + 1010 10102
• 11 00112 + 11002
• 1 11112 + 12
Subtraktion
Die Subtraktion zweier Binärzahlen ist ebenso simpel wie die Addition, da sie genauso funktioniert wie im Dezimalsystem. Es wird wieder beim least significant bit
begonnen. Die untere/hintere Zahl (der Subtrahend) wird vom Minuenden abgezogen. Sollte das Ergebnis negativ sein (wenn wir bspw. 02 − 12 rechnen), entsteht
ein Übertrag. Dieser wird an der nächsten Binärstelle zusätzlich vom Minuenden
abgezogen. Zur Verdeutlichung ist in Gleichung 1.2 ein Beispiel gezeigt.
K
Seite 20
Studienbrief 1 Eine Einführung in Programmiersprachen
−
1011110
1011
1010011
(1.2)
Wenn wir rechts beginnen, rechnen wir zunächst 02 − 12 . Das Ergebnis ist −1. Wir
schreiben also in diese Stelle eine 1 und nehmen, da das Ergebnis negativ ist, einen
Übertrag mit zur nächsten Binärstelle. Hier rechnen wir zunächst 12 − 12 , Das
Ergebnis ist 02 . Da wir aber noch den Übertrag haben, müssen wir von diesem
Ergebnis wiederum 12 abziehen. Das Ergebnis ist −1, was bedeutet, dass wir auch
an diese Stelle eine 12 schreiben und einen Übertrag mitnehmen. Der Rest der
Aufgabe wird analog gelöst.
K
Kontrollaufgabe 1.8: Subtraktion
Lösen Sie die folgenden Aufgaben im Binärsystem. Rechnen Sie im Anschluss die Zahlen ins Dezimalsystem um und prüfen Sie Ihre Ergebnisse.
• 11112 − 11012
• 101010112 − 101010102
• 1100112 − 0011002
• 111112 − 101012
Shifting
Wir haben zwar geschrieben, dass wir nur auf die Addition und Subtraktion eingehen, aber wir wollen an dieser Stelle trotzdem auf eine Besonderheit hinweisen,
die uns zu einer weiteren binären Operation führt. Im Dezimalsystem fällt uns die
Multiplikation und Division mit Zehnerpotenzen besonders leicht. Wir wissen,
dass, wenn wir eine ganze Zahl mit 10 multiplizieren, wir nur eine Null hinten an
die Zahl anfügen müssen. Analog verschieben wir bei der Division durch 10 das
Komma um eine Stelle nach links. Dieser Verhalten tritt in jedem Zahlensystem
auf, wenn wir mit einer Potenz der Basis multiplizieren oder dividieren.
Im Binärsystem bedeutet das: Wenn wir eine Zahl mit bspw. 2 = 21 multiplizieren,
so müssen wir an die Binärzahl nur eine 0 anfügen, um das Ergebnis zu erhalten.
Wenn wir sie mit 4 = 22 multiplizieren, werden zwei Nullen angefügt. Wenn wir
durch 2 dividieren, schneiden wir einfach das least significant bit ab. (Dies gilt nur
für die ganzzahlige Division)
Der Shift- oder auch Verschiebeoperator arbeitet auf ähnliche Weise. Mit diesem
Operator können wir angeben, um wie viel Stellen eine Binärzahl nach links oder
rechts verschoben werden soll. Der Shiftoperator wird mit << (Verschiebung nach
links) bzw. >> (Verschiebung nach rechts) ausgedrückt. Hinter dem Operator
steht die Anzahl der Stellen, um die verschoben wird.
Sie müssen beachten, dass die Anzahl der Stellen beim Verschieben oftmals gleich
bleibt. In der Informatik werden für Zahlen eine bestimmte Anzahl an Bits reserviert, bspw. 32 Bit. Diese Bitzahl ist fest. Wir können also Zahlen links und rechts
„herausschieben“. Ob beim Verschieben mit Nullen oder Einsen aufgefüllt wird,
1.3 Zahlensysteme
Seite 21
hängt von der Programmiersprache und der Tatsache ab, ob die Zahl positiv oder
negativ ist (mehr dazu später). Im Beispiel 1.2 füllen wir bspw. mit Nullen auf.
Beispiel 1.2: Bitshifting
Wir wollen die Zahl 110 10102 (7 Bit fest) um zwei Stellen nach links verschieben. Dies wird folgendermaßen ausgedrückt:
B
110 10102 << 2
Das Ergebnis ist:
010 10002 .
Die beiden höchstwertigsten Bits wurden links herausgeschoben, dafür
wurden rechts zwei Nullen hineingeschoben.
Kontrollaufgabe 1.9: Bitshifting
Lösen Sie die folgenden Aufgaben. Die Bitzahl ist fest. Füllen Sie mit Nullen
auf.
• 10 10112 >> 4
• 00 11002 >> 2
• 11 11112 << 6
• (11 00112 << 2) >> 2
Bitweise Verknüpfungen
Neben dem Bitshifting gibt es binäre Verknüpfungen, die bitweise auf zwei Operanden angewendet werden. Es gibt die AND-, die OR sowie die XOR-Verknüpfung.
Bei der AND-Verknüpfung müssen beide Operanden gleich 1 sein, damit das Ergebnis ebenfalls 1 ist. Ansonsten ist das Ergebnis dieser Verknüpfung 0. In Gleichung 1.3 ist ein Beispiel zu sehen. Beachten Sie, dass der Operator bitweise angewendet wird. Dies bedeutet, dass das niederwertigste Bit der ersten Zahl mit dem
niederwertigsten Bit der zweiten Zahl verundet wird, das nächsthöhere der ersten
Zahl mit dem nächsthöheren der zweiten Zahl usw. Anstelle des Wortes AND wird
in Programmiersprachen häufig das Et-Zeichen (&) genutzt.
AND
11011
01001
01001
(1.3)
Bei der OR-Verknüpfung ist das Ergebnis gleich 1, wenn der eine, der andere oder
beide Operanden gleich 1 sind. Im Umkehrschluss bedeutet dies, dass das Ergebnis
der OR-Verknüpfung nur 0 sein kann, wenn beide Operanden gleich 0 sind. In
Gleichung 1.4 sehen Sie ein Beispiel. Anstelle des Wortes OR wird in Programmiersprachen häufig ein einzelner senkrechter Strich (|) genutzt.
K
Seite 22
Studienbrief 1 Eine Einführung in Programmiersprachen
OR
11011
01001
11011
(1.4)
Die XOR-Verknüpfung entspricht dem, was wir im normalen Sprachgebrauch als
„oder“ benutzen: „Das eine oder das andere, aber nicht beides“. Demzufolge ist das
Ergebnis von XOR (es steht nebenbei bemerkt für „eXclusive OR“) gleich 1, wenn
genau ein Operand gleich 1 ist. Ansonsten ist das Ergebnis 0, wie in Gleichung 1.5
zu sehen ist. Anstelle des Wortes XOR wird in Programmiersprachen häufig ein
Zirkumflex (ˆ) benutzt.
11011
XOR 01001
10010
(1.5)
In Tabelle 1.4 sehen sie die drei vorgestellen Operatoren noch einmal zusammengefasst.
Tabelle 1.4: Binäre
Verknüpfungen
AND
OR
XOR
0
0
0
0
0
0
1
0
1
1
1
0
0
1
1
1
1
1
1
0
Der NOT-Operator
Der letzte Operator, dem wir uns zuwenden, ist der NOT-Operator. Dieser wird,
im Gegensatz zu den vorher genannten, nur auf eine Zahl angewendet. Er negiert
bitweise, d. h. er macht auf einer 1 eine 0 und aus einer 0 eine 1. In Gleichung 1.6
sehen Sie ein Beispiel. In Programmiersprachen wir für das binäre NOT oftmals
auch eine Tilde (~) benutzt. Mathematisch können wir das NOT mit einem Strich
über der Zahl oder dem Symbol ¬ darstellen.
NOT
K
01001
10110
(1.6)
Kontrollaufgabe 1.10: Binäre Operatoren
Lösen Sie die folgende Aufgaben. Achten Sie auf das Zahlensystem. Verändern sie nicht die Anzahl der Bits.
• 11002 & 00112
• (111100002 >> 4) XOR 111111112
• 10012 | 01102
• NOT (710 )
• 101100002 XOR 16410
• (101100002 OR 23210 ) XOR 0x f 0
1.3 Zahlensysteme
Seite 23
Kontrollaufgabe 1.11: Kombination von Operatoren
K
Kombinieren Sie die bekannten binären Operatoren so, dass folgende Ergebnisse herauskommen:
Zahl x
0
0
1
1
Zahl y
0
1
0
1
bsp)
1
0
0
0
a)
1
0
0
1
b)
1
1
1
0
c)
0
0
1
0
bsp) Das Beispiel ist die negierte OR-Verknüpfung. Die Lösung ist also:
NOT ( x OR y)
1.3.6 Negative Zahlen
Bisher haben wir uns nur mit positiven ganzen Zahlen beschäftigt, die wir in
verschiedene Zahlensysteme konvertiert und auf denen wir Operationen ausgeführt haben. Aber es ist natürlich auch möglich, negative und gebrochene Zahlen
darzustellen. Dafür gibt es mehrere Möglichkeiten, die wir Ihnen im Folgenden
aufzeigen werden.
Vorzeichen-Betrags-Darstellung
Angenommen, wir haben für eine Zahl 8 Bit zur Verfügung. Das heißt, wir können
die Zahlen von 0 bis einschließlich 511 darstellen. Wir könnten nun sagen, dass
das höchstwertigste Bit angibt, ob es eine positive (0) oder negative(1) Zahl ist. Die
anderen sieben Bit geben also den Wert der Zahl, das vorderste Bit das Vorzeichen
an. Die Zahl −1 würde man nach dieser Methode folgendermaßen darstellen:
100000012 . Dies nennt man Vorzeichen-Betrags-Darstellung.
Diese Methode hat aber einige Nachteile: Die Null hat zwei verschiedene Darstellungsarten (10000002 und 000000002 ), was die maximale Anzahl an darstellbaren
Zahlen um eins reduziert. Zudem schlägt die Addition fehl, wenn wir negative
Zahlen auf diese Weise darstellen, wie Gleichung 1.7 zeigt.
1010 (−2)
+ 0011
(3)
1101 (−5)
(1.7)
Es muss also eine andere Lösung gefunden werden, um negative Zahlen darzustellen.
Einerkomplement
Bei der Einerkomplement-Darstellung wird ebenfalls das höchstwertigste Bit als
Vorzeichenbit genutzt. Um den absoluten Wert der Zahl zu bekommen, muss,
sofern die Zahl negativ ist, die ganze Zahl mit dem NOT-Operator invertiert werden.
Die Zahl 10012 bspw. ist eine negative Zahl (wegen der führenden Eins). Um den
Wert zu erhalten, invertieren wir sie und erhalten 01102 , was dem Dezimalwert 6
entspricht. Die Zahl 10012 steht also für den Wert −6.
Seite 24
Studienbrief 1 Eine Einführung in Programmiersprachen
Bei der Einerkomplement-Darstellung haben wir wiederum das Problem, dass es
zwei verschiedene Darstellungen der Null gibt. Dafür funktioniert die Addition ohne zusätzlichen Aufwand, sofern die Null nicht durchschritten wird. Gleichung 1.8
zeigt dafür ein Beispiel.
1010 (−5)
+ 0011
(3)
1101 (−2)
(1.8)
Wenn jedoch bei der Addition die Null durchschritten wird, stimmt das Ergebnis
zunächst nicht, wie Gleichung 1.9 zeigt.
1110 (−1)
+ 0011
(3)
(1)0001 (1)
(1.9)
Die führende Eins in der Gleichung ist eingeklammert, da es sich um den letzten
Übertrag handelt. Da wir nur mit 4 Bit gerechnet haben, würde dieser Übertrag
nicht mehr berücksichtigt werden und verfallen. Aber genau dieser Übertrag ist
es, den wir auf das Ergebnis aufaddieren müssen, um das korrekte Ergebnis zu
erhalten! Wir addieren also auf das bisherige Ergebnis 1 den Übertrag auf und
erhalten so das korrekte Ergebnis: 2. Dies gilt für alle Additionen, bei denen die
Null durchschritten wird.
Da es relativ umständlich und aufwendig ist, das Einerkomplement zu nutzen,
wird es kaum verwendet. Stattdessen verwenden die meisten Computer das Zweierkomplement zur internen Darstellung von negativen Zahlen.
Zweierkomplement
Bei der Zweierkomplement-Darstellung wird wiederum das höchstwertigste Bit
der Zahl dazu genutzt, um das Vorzeichen zu bestimmen. Positive Zahlen haben
als führendes Bit die 0, negative Zahlen die 1. Positive Zahlen können wie gewohnt dargestellt werden, d. h. die Zahl 01002 entspricht der Dezimalzahl 4. Zur
Darstellung von negativen Zahlen wird folgendermaßen vorgegangen:
1. Stellen Sie die Zahl zunächst als positive binäre Zahl dar; z. B. 310 = 00112
2. Negieren Sie diese Zahl: NOT (00112 ) = 11002
3. Addieren Sie zu dieser Zahl eins dazu: 11002 + 12 = 11012
Analog kann man, um aus der Binärdarstellung einer negativen Zahl wieder die
Dezimaldarstellung zu gewinnen, eins abziehen und dann invertieren. Heraus
kommt der absolute Wert der negativen Zahl.
Der Vorteil der Zweierkomplementdarstellung ist einerseits, dass es nur eine Darstellung der Zahl 0 gibt. Andererseits funktioniert die Addition ohne Einschränkung, wie in Gleichung 1.10 zu sehen ist.
1111 (−1)
+ 0011
(3)
(1)0010 (2)
(1.10)
1.3 Zahlensysteme
Seite 25
Der letzte Übertrag verfällt wieder, da wir nur 4 Bit für die Zahlen zur Verfügung
haben. Sollten wir zwei Zahlen addieren oder subtrahieren wollen, die unterschiedlich viele Binärstellen haben, so müssen wir eine der beiden Zahlen von links mit
dem Vorzeichenbit auffüllen. Am Wert der Zahl ändert dies nichts.
Zahlen werden mit dem
Vorzeichenbit aufgefüllt.
In Tabelle 1.5 sind noch einmal die drei verschiedenen Darstellungsweisen gegenübergestellt. Hauptsächlich wird die Zweierkomplement-Darstellung genutzt.
Bits
Vorzeichen-Betrag
Einerkompl.
Zweierkompl.
000
0
0
0
001
1
1
1
010
2
2
2
011
3
3
3
100
−0
−3
−4
101
−1
−2
−3
110
−2
−1
−2
111
−3
−0
−1
Tabelle 1.5: Darstellung
negativer Zahlen im
Dualsystem.
1.3.7 Darstellung gebrochener Zahlen
Bei der Darstellung gebrochener Zahlen müssen wir zwei verschiedene Arten von
Darstellungen berücksichtigen: Die Gleitkomma- und Festkommadarstellung.
Festkommadarstellung
Bei der Festkommadarstellung wird von vornherein festgelegt, dass eine bestimmte
Anzahl an Bits für die Zahl nach dem Komma und eine bestimmte Anzahl an Bits
für die Zahl vor dem Komma zur Verfügung steht. Bei einer 8-Bit-Zahl könnten
wir festlegen: die ersten 4 Bit stehen für die Zahl vor dem Komma, die letzten 4 Bit
für die Zahl nach dem Komma zur Verfügung. Wie aber wird die Zahl nach dem
Komma berechnet? Hierzu sehen wir uns Abbildung 1.2 an.
Abb. 1.2: Umwandlung in die binäre
Festkommadarstellung
In der Abbildung wurde die Zahl 6,625 in eine 8-Bit-Festkommazahl umgewandelt, wobei 4 Bits für die Nachkommastelle vorgesehen sind. Der linke Teil der
Abbildung, der die Umwandlung des ganzzahligen Anteils beschreibt, ist Ihnen
bereits bekannt. Um die Bitfolge für die Nachkommazahl zu errechnen, wird der
Nachkommateil mit 2 multipliziert. Sollte das Ergebnis größer oder gleich 1 sein,
Seite 26
Studienbrief 1 Eine Einführung in Programmiersprachen
kommt an die betreffende Binärstelle eine 1 (beginnend mit der ersten Stelle nach
dem Komma). Wenn das Ergebnis kleiner als 1 ist, kommt eine 0 an die Stelle.
Sofern das Ergebnis nicht gleich 1, 0 war, wird der Nachkommateil erneut mit 2
multipliziert. Dies wird so lange wiederholt, bis das Ergebnis gleich 1 ist oder wir
keine weiteren Bits zur Darstellung zur Verfügung haben.
Genau wie bei ganzen Zahlen entsprechen gesetzte Bits einem bestimmten Zahlenwert, wie sie in Abbildung 1.3 sehen können. Indem die gesetzten Zahlenwerte
aufaddiert werden, kann aus einer Binärzahl wieder eine Dezimalzahl errechnet
werden.
Abb. 1.3: Zuordnung von
Nachkommabit zu Wert.
Diese Festkommadarstellung bringt einige Probleme mit sich. Zunächst einmal
kann es passieren, dass wir nicht genügend Bit zur Verfügung haben, um die
Nachkommazahl darzustellen. Wenn wir bspw. 4 Bit für die Nachkommastellen
1
zur Verfügung haben, ist die kleinste darstellbare Zahl 2−4 = 16
= 0.0625. Diese
Zahl ist zudem die maximale Abweichung, die entstehen kann, wenn wir eine Zahl
umwandeln.
Ein Komma an einer festen Position führt darüber hinaus dazu, dass Bits oft
ungenutzt bleiben. Nehmen wir als Beispiel die Zahl 25, 5. Wir gehen wieder von
einer 8-Bit-Zahl aus, wobei 4 Bit für den Nachkommabereich gedacht sind. Dadurch
ist es uns nicht möglich, die Zahl 25 darzustellen, da 4 Bit dafür nicht ausreichen.
Gleichzeitig würden wir aber für die Darstellung der 0, 5 nur 1 Bit benötigen,
haben aber 4 reserviert. Kurz gesagt: Die pure Anzahl an Bits würde theoretisch
ausreichen, aber durch das Komma an einer festen Position verschenken wir ggf.
Speicherplatz.
Die oben beschriebenen Probleme lassen sich durch eine Gleitkommadarstellung
lösen. Dazu schauen wir uns (nach einer Kontrollaufgabe) den IEEE-754-Standard
zur Darstellung von Gleitkommazahlen genauer an.
K
Kontrollaufgabe 1.12: Festkommadarstellung
Stellen Sie die folgenden Zahlen in einer 16-Bit-Festkommadarstellung dar.
Benutzen Sie 8 Bit für den Nachkommaanteil. Sollten Sie die Zahl nicht
exakt darstellen können, berechnen Sie den absoluten Unterschied.
• 84, 55
• 255, 97
• 8, 015625
Der IEEE-754-Standard
Im Dezimalsystem lassen sich Zahlen, neben der normalen Schreibweise, in der
Exponent-Mantissen-Schreibweise darstellen. Für die Zahl 305,47 bedeutet dies
bspw. Folgendes:
Exponent
305, 47 = 3, 0547 ·|{z}
10
| {z }
Mantisse Basis
z}|{
2
1.3 Zahlensysteme
Seite 27
Die Mantisse hat stets nur eine Stelle vor dem Komma. Die Anzahl der Stellen, um
die das Komma verschoben werden muss, wird mit dem Exponenten angegeben.
Ein Exponent von 2 bedeutet eine Verschiebung um zwei Stellen nach rechts.
Im Dualsystem kann diese Schreibweise ebenfalls verwendet werden. Der Exponent
wird so gewählt, dass immer eine 1 vor dem Komma steht. Wenn wir also die Zahl
010110, 012 in der Exponent-Mantissen-Schreibweise darstellen wollen, kommt
Folgendes dabei heraus:
010110, 01 = 1, 011001 · 24
Indem wir eine Zahl im Dualsystem auf diese Weise darstellen, legen wir nicht fest,
an welcher Stelle sich das Komma befindet. Man spricht auch von einer Gleitkommadarstellung. Wenn wir eine hohe Zahl vor dem Komma haben, ist der Exponent
entsprechend hoch, bei vielen Stellen nach dem Komma entsprechend niedrig.
Außerdem machen wir uns den Umstand zu nutze, dass immer eine 1 vor dem
Komma steht. Dieses hidden bit wird bei der Darstellung der Zahl weggelassen.
Dadurch verdoppelt sich der darstellbare Zahlenbereich oder die Präzision.
Exponent
010110, 01 =
1 , 011001
|{z}
| {z } ·2
z}|{
4
hidden bit Mantisse
Der IEEE-754-Standard gibt verschiedene Bitzahlen zur Darstellung einer Zahl vor.
Wir werden uns in diesem Modul nur mit der single precision-Darstellung beschäftigen. Hier werden für eine Zahl 32 Bit benutzt, die folgendermaßen aufgeteilt
sind:
• 1 Bit Vorzeichen
• 8 Bit Exponent
• 23 Bit Mantisse
Die Mantisse sowie das Vorzeichen können direkt genutzt werden. Das hidden
bit wird, wie bereits erwähnt, weggelassen. Beachten Sie ebenfalls, dass für negative Zahlen kein Einer- oder Zweierkomplement angewandt wird - es wird die
Vorzeichen-Betrags-Darstellung genutzt.
Der Exponent wird nicht direkt genutzt, sondern auf einen so genannten Bias
aufaddiert. Im Anschluss wird die Summe eingetragen. Dadurch wird bei einem
negativen Exponenten die Darstellung des Vorzeichens vermieden. Der Bias berechnet sich folgendermaßen:
Bias = 2#Bits für Exponent−1 − 1
In unserem Fall haben wir 8 Bit für den Exponenten. Der Bias beträgt also 127.
Dieser Bias wird nun auf den Exponenten (im oberen Beispiel 4) aufaddiert. Die
Summe tragen wir in unsere binäre Zahl ein und erhalten so die Gleitkommadarstellung nach IEEE 754:
010110, 01 = 1, 011001 · 24 =
0
|{z}
01000011
| {z } 0110010
|
{z · · · 0}
Vorzeichen Exponent
+ Bias
Mantisse
Wir haben nun also am Beispiel der Zahl 010110, 012 = 22, 2510 gezeigt, wie eine
Zahl in die IEEE-754-Darstellung für Gleitkommazahlen überführt wird. Um die
Seite 28
Studienbrief 1 Eine Einführung in Programmiersprachen
einzelnen Schritte gebündelt noch einmal zusammenzufassen, hier das Vorgehen,
um eine Dezimalzahl umzuwandeln:
1. Die Dezimalzahl in die entsprechende Binärzahl umwandeln. Das Vorzeichen
wird an dieser Stelle ignoriert.
2. Zuerst den ganzzahligen Anteil umwandeln, dann die Nachkommastellen.
Sollte der Nachkommaanteil nicht endlich sein, die verfügbaren Bits für die
Mantisse beachten.
3. Den Exponenten und die Mantisse berechnen, indem das Komma der Zahl
so verschoben wird, dass vor dem Komma nur eine 1 steht
4. Bias ausrechnen und auf den Exponenten aufaddieren
5. Die Zahl folgendermaßen zusammenstellen
a) Vorzeichen
b) Bias + Exponent
c) Mantisse ohne hidden Bit
Um aus der Gleitkommadarstellung wieder die Dezimalzahl zu gewinnen, können die Schritte rückwärts ausgeführt werden. Zur Festigung des Stoffes folgen
1.3 Zahlensysteme
Seite 29
nun zwei Beispiele. Im Anschluss müssen Sie selbst in einigen Kontrollaufgaben
beweisen, dass Sie die Gleitkommadarstellung verstanden haben.
Beispiel 1.3: Von der Dezimalzahl in die Gleitkommadarstellung
Folgende Zahl soll in die Gleitkommadarstellung nach IEEE umgewandelt
werden:
567, 837
Zunächst die Darstellung der Zahl 567 in Bitschreibweise (Vorzeichen beachten!):
010 0011 0111
Die Zahl benötigt 10 Bit (das Vorzeichen zählt nicht mit). Da wir 23 Bit für
die Mantisse haben, haben wir noch 13+1 Bit für den Nachkommabereich
(das +1 kommt durch das hidden Bit. Der Nachkommabereich ist demnach:
11 0101 1001 0001
Die komplette Zahl lässt sich nun folgendermaßen darstellen:
010 0011 0111 , 11 0101 1001 0001
Um die Exponent-Mantissen-Schreibweise zu erhalten, müssen wir das Komma um 9 Stellen nach links verschieben, wodurch wir Folgendes erhalten:
1, 00011011111010110010001 · 29
Um die Gleitkommazahl jetzt korrekt zu schreiben, müssen wir noch den
Bias berechnen:
Bias= 27 − 1 = 127
und im Anschluss den Bias auf den Exponenten aufaddieren:
127 + 9 = 136.
Damit haben wir alle Komponenten zusammen, um die Zahl in Gleitkommadarstellung darzustellen:
0 10001000 00011011111010110010001
B
Seite 30
B
Studienbrief 1 Eine Einführung in Programmiersprachen
Beispiel 1.4: Von der Gleitkommadarstellung in die Dezimaldarstellung
Folgende IEEE-754-Zahl soll in die Dezimaldarstellung überführt werden:
1 10001010 00000110111100101000100
Für die Dezimaldarstellung müssen wir den Bias von der Zahl 1000 10102 =
138d abziehen. Dadurch erhalten wir den Exponenten für die ExponentMantissen-Schreibweise:
Exponent = 138 − 127 = 11
Die Exponent-Mantissen-Schreibweise ist also:
1, 00000110111100101000100 · 211
Beachten Sie das hidden Bit an erster Stelle. Das Vorzeichen haben wir noch
nicht beachtet. Indem wir das Komma um 11 Stellen nach rechts verschieben,
erhalten wir die Zahl, die wir ins Dezimalsystem umrechnen müssen:
1000 0011 0111 ,1001 0100 0100
Das Ergebnis ist 2103, 5791015625. Wenn wir nun noch das Vorzeichenbit aus der Gleitkommazahl berücksichtigen, erhalten wir das Ergebnis:
−2103, 5791015625.
K
Kontrollaufgabe 1.13: IEEE 754
Wandeln Sie folgende Zahlen in eine Gleitkommazahl nach IEEE 754 (32 Bit)
um:
a) 2745, 888
b) 2, 5668
1.3.8 Zusammenfassung
Ausgangspunkt für die Erläuterungen auf den letzten Seiten war die Frage, wie wir
einem Computer eine simple Aufgabe, wie bspw. „Rechne 1+1“, stellen können.
Das Problem ist, dass ein Computer keine Alltagssprache versteht, sondern nur
Anweisungen im Binärsystem. Auf den letzten Seiten haben wir gelernt:
• Wie Zahlen aus dem Dezimalsystem ins Binärsystem (und umgekehrt) umgerechnet werden
• Wie positive und negative Zahlen im Binärsystem dargestellt werden können
• Wie gebrochene Zahlen dargestellt werden
• Wie Operationen auf Zahlen im Dualsystem angewendet werden
Zudem haben Sie fundamentales Wissen erworben, um die Programmiersprache
Java besser verstehen zu können. Wenn wir also später darauf hinweisen, dass
1.4 Opcodes und Assembler
bspw. in einer integer-Variablen ein ganzzahliger Wert in 32 Bit in Zweierkomplementdarstellung gespeichert wird, wissen Sie genau, was dies bedeutet.
Um noch einmal auf den Ausgangspunkt dieses Studienbriefs zurückzukommen:
Wir möchten einem Computer folgende Anweisung geben: „Rechne 1+1“. Wir
wissen mittlerweile, wie wir Zahlen im Dualsystem darstellen. Aber wie vermittelt
man einem Computer, dass wir eine Addition der beiden Zahlen wünschen? Zu
diesem Zweck nutzen wir sogenannte Opcodes.
1.4 Opcodes und Assembler
Ein Prozessor versteht lediglich eine begrenzte Anzahl an Befehlen. Darunter sind
Befehle wie die Addition und das Speichern von Daten in Registern. Jeder dieser
Befehle hat eine spezielle binäre Nummer, den sogenannten Opcode.
In diesem Abschnitt erläutern wir kurz und vereinfacht, wie binäre Befehle aufgebaut sind und wie die Prozessorbefehle mit Assemblercode einfacher ausgedrückt
werden können als mit binärem Code.
1.4.1 Opcodes
Die Hauptarbeit eines Computers läuft im Prozessor ab. Hier werden Befehle
verarbeitet, um unterschiedliche Programme (wie das Betriebssystem, einen Browser oder ein Textverarbeitungsprogramm) ausführen zu können. Jeder Prozessor
hat eine Reihe von Befehlen, die er beherrscht. Dazu gehören u. a. grundlegende
Befehle wie die Grundrechenarten oder das Speichern von Daten. Diese Maschinenbefehle sind mit Zahlen codiert, d. h. es gibt zu jedem Befehl eine Nummer.
Diese „Nummer“ ist der sogenannte Opcode. Jeder Opcode hat eine gewisse Anzahl
von Parametern, die er benötigt, um korrekt ausgeführt zu werden. Diese werden
hinter den Opcode geschrieben.
Betrachten wir zur Verdeutlichung ein fiktives Beispiel:
Wir haben den fiktiven Prozessortypen PK87. Dieser beherrscht viele Operationen,
unter anderem natürlich auch die Addition. Die Addition hat den Opcode 0xA8.
Als Parameter bekommt der Opcode die zwei 8-Bit-Zahlen, die er addieren soll,
sowie die Nummer eines Registers, in der er das Ergebnis speichert. Um also
diesem Prozessor die Anweisung „Rechne 1+1“ zu geben, müssen wir Folgendes
schreiben:
A8 01 01 12
Mit diesem Befehl sagen wir: Addiere (0xA8) die Zahlen 1 (0x01) und 1 (0x01) und
schreibe das Ergebnis in Register 0x12. Binär ausgedrückt müssten wir schreiben:
10101000 00000001 00000001 00010010
Diese Art der Programmierung ist natürlich unnötig kompliziert, fehleranfällig
und langsam. Eine angenehmere Art, die Maschinenbefehle zu schreiben, ist das
Verwenden von Assemblersprache.
1.4.2 Vereinfachung durch Assemblersprache
Bei der Assemblersprache wird jedem Prozessorbefehl ein Mnemonic, also eine
sprachliche Entsprechung, zugeordnet. Anstatt den Opcode 0xA8 für die Addition
Seite 31
Seite 32
Studienbrief 1 Eine Einführung in Programmiersprachen
zu verwenden, wird bspw. der Befehl direkt mit dem Wort add ausgedrückt. Mittels
Assemblersprache können wir also schreiben:
add 010112,
Ein Assembler übersetzt Assemblersprache
in Maschinensprache
add 0x01 0x01 0x12
...
Assemblersprache
...
Abb. 1.4: Umwandlung
von Assemblersprache
in Maschinensprache
durch den Assembler.
um die Zahlen 1 und 1 zu addieren. Durch das Mnemonic ist der Befehl deutlich
einfacher zu interpretieren. Problematisch ist an dieser Stelle aber, dass der Prozessor mit dem Wort add nichts anfangen kann. Daher muss ein in Assemblersprache
geschriebenes Programm für den Prozessor übersetzt werden. Diese Übersetzung
übernimmt ein Assembler genanntes Programm. Abbildung 1.4 verdeutlicht den
Vorgang noch einmal.
Assembler
...
Maschinensprache
1010100000000001
0000000100010010
...
Assemblersprache ist eine hardwarenahe Programmiersprache. Das bedeutet, dass
die Sprache der Maschinensprache sehr nahe steht. Die Befehle werden meist 1 zu
1 umgesetzt, d. h. ein Befehl in der Assemblersprache entspricht einem Opcode
bzw. Prozessorbefehl.
Dem gegenüber stehen die sogenannten höheren Programmiersprachen, die deutlich abstraktere und mächtigere Befehle zur Verfügung stellen. Bei einer höheren
Programmiersprache entspricht ein Befehl mehreren, teilweise Hunderten Maschinenbefehlen.
1.5 Höhere Programmiersprachen
Im Gegensatz zur Assemblersprache sind höhere Programmiersprachen deutlich
abstrakter und losgelöster von den eigentlichen Maschinenbefehlen. Programmiersprachen (zu denen auch die Assemblersprache zählt) versuchen häufig, näher an
der menschlichen Sprache zu sein, um Anweisungen verständlicher formulieren
zu können. Wo bei Assembler aber hauptsächlich die Opcodes des Prozessors als
einzelnes Wort codiert wurden, gehen höhere Programmiersprachen deutlich weiter. Darüber hinaus kann eine Anweisung in einer höheren Programmiersprache
teilweise Hunderten oder Tausenden Zeilen Assemblercode entsprechen.
Um zu verdeutlichen, welchen Komfort gerade höhere Programmiersprachen
bieten, betrachten wir das wohl am häufigsten geschriebene Programm der Welt:
Hello World. Dies ist die Standardaufgabe jedes Programmierkurses, in der es darum
1.5 Höhere Programmiersprachen
Seite 33
geht, den Text „Hello World“ auszugeben. In der Assemblersprache MASM sieht so
ein Programm folgendermaßen aus1 :
Quelltext 1.1: Hello Word in Assembler
1
2
3
4
Q
DATA SEGMENT
Meldung db "Hello World"
db "$"
DATA ENDS
5
6
7
8
9
10
11
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
Anfang:
mov ax, DATA
mov ds, ax
mov dx, offset Meldung
12
13
14
15
16
17
18
mov ah, 09h
int 21h
mov ax, 4C00h
int 21h
CODE ENDS
END Anfang
Sie müssen den Code weder verstehen noch nachvollziehen können – es reicht,
wenn Sie feststellen, das er kompliziert ist. Betrachten Sie dagegen folgenden JavaCode:
Quelltext 1.2: Hello World in Java
1
2
3
4
Q
public static void main(String[] args)
{
System.out.println("Hello World");
}
Dieser Code ist deutlich kürzer und einfacher zu verstehen. Es geht aber noch
einfacher, wie bspw. die Sprache Python zeigt:
Quelltext 1.3: Hello World in Python
1
print("Hello World")
Sie sehen also: Höhere Programmiersprachen können das Programmieren sehr
vereinfachen. Es gibt aber immer noch ein Problem: Der Computer versteht diese
Sprachen nicht. Wie Sie am Anfang dieses Studienbriefs erfahren haben, versteht
ein Computer nur 0en und 1en. Hier kommt der sogenannte Compiler ins Spiel.
1 übernommen
12.08.2014
von Wikipedia: http://de.wikipedia.org/wiki/Assemblersprache, abgerufen am
Q
Seite 34
Studienbrief 1 Eine Einführung in Programmiersprachen
1.5.1 Compiler
Ein Compiler (dt.: Übersetzer) tut genau das, was der Name vermuten lässt: Er
übersetzt Programme einer Programmiersprache in eine andere. Sie haben bereits
einen Compiler kennengelernt: Den Assembler. Dieser hatte Assemblersprache in
Maschinensprache übersetzt, damit der Computer ein geschriebenes Programm
ausführen kann. Ein Compiler übersetzt ebenso eine Programmiersprache in Maschinensprache (oder eine andere Sprache), wie Abbildung 1.5 verdeutlicht.
Programmiersprache
...
Abb. 1.5: Ein Compiler übersetzt eine Programmiersprache in
eine andere Programmiersprache oder direkt
in Maschinensprache.
int i = 1 + 1;
...
Compiler
...
1010100000000001
0000000100010010
...
andere
Programmiersprache
oder
Maschinensprache
Wir belassen an dieser Stelle mit dieser simplen Erklärung eines Compilers. Im
Verlauf des Studiums werden Sie im Modul Compilerbau feststellen, dass doch
einiges mehr dazugehört, als wir an dieser Stelle geschrieben haben. Stattdessen
kommen wir nun zur Programmiersprache, mit der wir uns für den Rest dieses
Moduls beschäftigen werden: Java.
1.5.2 Java
Die Programmiersprache Java wurde im Auftrag von Sun Microsystems entwickelt
und erschien im Jahr 1995. Der Name geht auf eine Kaffee-Bohne, der Java-Bohne,
zurück. Der Kaffee dieser Bohne wurde von den Entwicklern bevorzugt getrunken,
wodurch die Sprache zu ihrem Namen kam.
Die Programmiersprache hat rasch Verbreitung gefunden. Im TIOBE-Index, einem
Ranking der verbreitetsten Programmiersprachen (gemessen an der Anzahl der
Kurse und Programmierer) belegt Java momentan Rang 2 nach der Programmiersprache C.2 Java ist zudem die Standard-Programmiersprache für Android-Apps.
Da laut Google mittlerweile über 1 Milliarde Android-Geräte aktiviert wurden,
haben Sie durch das Erlernen von Java eine riesige Zahl an Nutzern, die Ihre
Programme nutzen könnten.
Im Gegensatz zu Programmiersprachen wie C oder C++ bietet Java den Komfort,
sich nicht um das Reservieren und Freigeben von Speicher kümmern zu müssen. Gleichzeitig bietet die Sprache aber auch nicht zu viele Annehmlichkeiten.
Dadurch ist der „Schock“ nicht allzu groß, wenn man mit hardwarenaheren Programmiersprachen wie C konfrontiert wird. Aus diesem Grund bietet sich Java als
erste Programmiersprache an.
2 Stand:
August 2014
1.5 Höhere Programmiersprachen
Seite 35
Die Java Virtual Machine
Java muss, damit der Prozessor die geschriebenen Anweisungen verstehen kann,
kompiliert werden. Im Gegensatz zu der im Abschnitt 1.5.1 Compiler beschriebenen
Vorgehensweise wird Java-Code aber nicht direkt in Maschinencode kompiliert,
sondern in Bytecode.
Es gibt mit Maschinensprache nämlich ein Problem, das wir Ihnen bisher verschwiegen haben: Nahezu jeder Prozessortyp hat seine eigenen Maschineninstruktionen
und Opcodes. Wenn Sie also ein Programm für einen bestimmten Prozessortyp
kompilieren, kann das Programm höchstwahrscheinlich von einem anderen Prozessortypen nicht ausgeführt werden. Dies führt dazu, dass Programme nicht
portabel sind: Sie können nicht erwarten, dass ein von Ihnen geschriebenes und
kompiliertes Programm auf einem anderen Rechner läuft.
Da sich Assemblersprache an den Opcodes des Prozessors orientiert, gibt es natürlich auch verschiedene Assemblersprachen. Eine davon ist MASM, von der Sie auf
Seite 33 in Quelltext 1.1 bereits einen kleinen Ausschnitt gesehen haben.
Java umgeht dieses Problem mit dem Bytecode. Dieser Code ist sehr ähnlich
zur Assemblersprache. Er wird von der so genannten Java Virtual Machine (JVM)
ausgeführt. Diese übersetzt den Code zur Laufzeit in Maschinencode und führt ihn
aus. Dies hat einen gewaltigen Vorteil: Der kompilierte Java-Code funktioniert auf
verschiedenen Architekturen, sofern diese über eine JVM verfügen. Abbildung 1.6
verdeutlicht noch einmal den Ablauf.
...
Java
int c = 1 + 1;
...
Java-Compiler
...
Bytecode
iadd 1 1
...
JVM
...
Maschinensprache
1010100000000001
0000000100010010
...
Kompilieren von Code
Um Java-Code, den Sie in ganz normale Text-Dateien (mit der Endung .java)
schreiben können, zu kompilieren, wird der Java programming language compiler
javac genutzt. Angenommen, Sie haben ein Programm geschrieben und dieses in
der Datei Programm.java gespeichert. Um diese Datei zu kompilieren, könnten Sie
in einem Terminal den javac-Befehl aufrufen:
javac Programm.java
Abb. 1.6: Der JavaCompiler kompiliert
Java-Code nicht direkt
in Maschinensprache,
sondern in Java Bytecode.
Dieser wird in der JVM
zu Maschinensprache
übersetzt.
Seite 36
Studienbrief 1 Eine Einführung in Programmiersprachen
Sie erhalten eine Datei Programm.class. Diese enthält den Bytecode. Sie können
nun mit dem Befehl java die JVM starten und den Code ausführen lassen:
java Programm
Dieses Kompilieren im Terminal (oder Konsole/Shell/Eingabeaufforderrung etc.)
wird auch „von Hand kompilieren“ genannt. Es bedeutet, dass Sie keine Entwicklungsumgebungen benutzen, um Ihr Programm zu kompilieren, sondern den
Kompiliervorgang selbst steuern. Es gibt zahlreiche solcher Entwicklungsumgebungen, auf Englisch Integrated Development Environment (IDE), von denen wir mit
BlueJ auf den nächsten Seiten eine ausprobieren werden.
1.6 Objektorientierte Programmierung: Ein Beispiel
Zum Ende dieses Studienbriefs wollen wir Ihnen noch eine kleine, interaktive Einführung in Java geben. Mit Hilfe dieser Einführung sollen Sie die Begriffe Klasse,
Methode, Attribut, Objekt und Parameter spielerisch erlernen. Um das beschriebene
Beispiel selbst analog zum Studienbrief ausführen zu können, benötigen Sie das
Programm BlueJ sowie den Quellcode, den sie unter folgendem Link herunterladen können: http://www.bluej.org/objects-first/resources/projects.zip.
Sie benötigen das Projekt „figures“ aus dem Ordner „chapter01“.
Das Beispiel stammt aus dem Buch „Java lernen mit BlueJ“ von Barnes und Kölling.
Der Rest dieses Studienbriefs orientiert sich am ersten Kapitel dieses Buches. Auch
im darauf folgenden Studienbrief orientieren wir uns grob an dem Aufbau dieses
Buches, werden dann aber immer mehr davon abweichen.
1.6.1 Öffnen des Projekts
Laden Sie sich zunächst, wie oben beschrieben, das Programm BlueJ sowie den
gepackten Projektordner projects.zip herunter. Entpacken Sie die Datei und
starten Sie im Anschluss das Programm BlueJ. Nun wählen Sie links oben unter
„Project“ die Option „Open Project“. Navigieren Sie nun zu dem gerade entpackten
Ordner. Dort finden Sie unter projects/chapter01/ das Projekt figures. Wählen
Sie dieses aus. Es erscheint nun ein Diagramm, das die verschiedenen Klassen des
Programms zeigt.
1.6.2 Klassen
Nachdem Sie das Projekt geladen haben, sehen Sie ein Klassendiagramm wie
in Abbildung 1.7. Dies sind die verschiedenen Klassen des Projekts, die jeweils
verschiende Formen repräsentieren (Circle, Square, Triangle, Person). Die
Klasse Canvas repräsentiert die Leinwand, auf der die Formen später gezeichnet
werden. Der gestrichelte Pfeil zu dieser Klasse bedeutet, dass die Klasse Canvas
von den anderen Klassen genutzt wird.
Attribute beschreiben Eigenschaften einer Klasse.
Was kann man sich nun unter einer Klasse vorstellen? Eine Klasse ist so etwas
wie eine allgemeine Beschreibung von Objekten. In ihr sind die Eigenschaften
verzeichnet, die ein Objekt haben kann. Anhand dieser Beschreibung kann man
konkrete Objekte erstellen, die für diese Eigenschaften gewisse Werte aufweisen.
Wir alle wären bspw. Objekte der Klasse Mensch. Die Klasse Mensch hat Eigenschaften wie ein Alter, ein Geschlecht oder eine Haarfarbe. Hans Müller ist so gesehen
ein Objekt der Klasse Mensch, mit dem Alter „26“, Geschlecht „männlich“ und
Haarfarbe „blond“. Die Eigenschaften einer Klasse werden in Java als Attribute
bezeichnet.
1.6 Objektorientierte Programmierung: Ein Beispiel
Seite 37
Abb. 1.7: Die Klassen,
die im Project „Shapes“
verwendet werden.
In einer Klasse werden nur die Eigenschaften beschrieben, die für das Programm
wichtig sind. Die oben genannten Eigenschaften eines Menschen sind zum Beispiel
in einem Programm relevant, das Personal verwalten kann.
Um auf das BlueJ-Projekt zurückzukommen: Die Klassen, die Sie sehen, beschreiben also, wie bspw. ein Kreis oder ein Quadrat aussehen. Hauptaufgabe des Programmes ist das Zeichnen dieser Formen. In der Klasse sind also Attribute gespeichert, die notwendig sind, um bspw. einen Kreis zu zeichnen. Dazu gehören u. a.
eine Position und ein Durchmesser.
Es existieren bisher nur Klassen, aber noch keine konkreten Kreise oder Vierecke.
Dies wollen wir nun ändern. Indem wir einen Rechtsklick auf die Klasse Circle
machen und die Option newCircle auswählen, erstellen wir einen neuen Kreis.
Wir werden nun gefragt, wie wir die Instanz (auch Objekt genannt) nennen wollen.
Wir wollen einen blauen Kreis generieren und nennen es deshalb blueCircle.
Nachdem Sie auf okay geklickt haben, sehen Sie im unteren Bildschirmabschnitt
das von Ihnen erstellte Objekt. Abbildung 1.8 zeigt, was Sie am Bildschirm sehen
sollten.
Abb. 1.8: Das Objekt
blueCircle, eine Instanz
der Klasse Circle.
1.6.3 Methoden
Durch den Doppelpunkt beim Namen wird ausgedrückt: Das Objekt blueCircle
ist eine Instanz der Klasse Circle. Unsere Absicht war, einen blauen Kreis zu
erstellen. Aber es ist kein Kreis zu sehen. Der Grund ist einfach: Wir haben dem
Objekt nicht gesagt, dass es sichtbar sein soll. Durch einen Rechtsklick auf das
Objekt erscheint eine Liste mit Befehlen (und dem Wort void vor jedem Befehl –
dazu mehr im nächsten Studienbrief). Da wir das Objekt sehen wollen, erscheint
es nur logisch, dass wir makeVisible() auswählen. Und tatsächlich: Es wird ein
neues Fenster geöffnet, in dem ein blauer Kreis zu sehen ist. Sie sollten nun dasselbe
sehen wie in Abbildung 1.9.
Was wir gerade benutzt haben, um mit dem Objekt zu interagieren und ihm
eine Anweisung zu geben, wird Methode genannt. Methoden sind dazu da, die
Eigenschaften eines Objektes zu verändern oder mit ihm zu interagieren. Diese Methoden werden ebenfalls in der Klasse definiert, wie wir im nächsten Studienbrief
sehen werden. Die Methoden gelten für alle Instanzen einer Klasse. Das bedeutet, wenn wir einen weiteren Kreis anlegen, können wir ihn ebenfalls sichtbar
machen.
Methoden verändern Objekte oder lassen Objekte
Dinge tun. Sie werden in
der Klasse definiert.
Seite 38
Studienbrief 1 Eine Einführung in Programmiersprachen
Abb. 1.9: Das gezeichnete Objekt „blueCircle“.
Unser nächstes Ziel ist es, einen roten Kreis zu generieren, der unter dem blauen
Kreis angezeigt wird. Hierzu legen wir zunächst ein neues Kreis-Objekt an, indem
wir einen Rechtsklick auf die Klasse Circle machen, newCircle auswählen und
der Instanz den Namen redCircle geben. Nachdem wir dies getan haben, taucht
unser neues Objekt in der unteren Leiste auf. Mit einem Rechtsklick darauf und
der Auswahl von makeVisible() lassen wir den Kreis sichtbar werden.
1.6.4 Attributwerte
Ein Attributwert ist
ein konkreter Wert für
ein Attribut. Objekte
haben Attributwerte
für die in der Klasse
definierten Attribute.
Aber etwas scheint nicht richtig funktioniert zu haben: Wir sehen lediglich den
blauen Kreis, den wir vorher schon sichtbar gemacht haben. Wo ist also der rote
Kreis? Um dies herauszufinden, schauen wir uns die Attributwerte des Objekts
an. Hierzu machen wir einen Rechtsklick auf das Objekt redCircle und wählen
„Inspect“. Wir sehen nun, wie in Abbildung 1.10 zu sehen, die Attributwerte des
Objekts redCircle.
Abb. 1.10: Attribute des
Objekts „redCircle“.
Unser roter Kreis hat demnach einen Durchmesser von 68, eine xPosition von 230,
eine yPosition von 90 und die Farbe blue. Bei isVisible steht true, woraus wir
schließen, dass der Kreis sichtbar ist. Ein erster Fehler wird hier schon deutlich:
Unser Kreis, der eigentlich rot sein soll, ist blau. Rückblickend haben wir aber auch
nirgendwo festgelegt, welche Farbe der Kreis haben soll. Wir haben den Kreis zwar
redCircle genannt, aber dies ist – wie bei Menschen auch – nur ein Name. Die
Standardfarbe, die für einen neuen Kreis gewählt wird, scheint blau zu sein, sodass
wir für unseren ersten Kreis scheinbar Glück hatten.
Warum wird uns aber nur ein blauer Kreis angezeigt, wo wir doch zwei haben
sollten? Die Antwort darauf finden wir, wenn wir uns die Attributwerte des Objekts
blueCircle ansehen: Sie sind identisch mit denen des redCircle-Objektes. Wenn
1.6 Objektorientierte Programmierung: Ein Beispiel
Seite 39
auf einer zweidimensionalen Ebene zwei blaue Kreise mit demselben Durchmesser
und der selben Position gezeigt werden, ist es nicht verwunderlich, wenn wir nur
einen sehen.
Um unser Vorhaben, einen roten Kreis unter den blauen zu zeichnen, zu realisieren,
müssen wir die Eigenschaften des Objekts redCircle verändern. Dazu verwenden wir, wie vorher bereits erwähnt wurde, Methoden. Nach einen Rechtsklick
sehen wir die verschiedenen Methoden, die uns zur Auswahl stehen. Zunächst
sollte das Objekt redCircle rot gefärbt werden. Hierzu wählen wir die Methode
changeColor. Bei dieser Methode sehen wir eine weitere Eigenschaft von Methoden: Ihnen können Parameterübergeben werden. Die Parameter stehen in runden
Klammern hinter dem Namen der Methode.
Parameter sind notwendig, damit die Methode korrekt ausgeführt werden kann.
Damit bspw. eine Methode zwei Zahlen addieren kann, müssen diese Zahlen als
Parameter übergeben werden. Und um, wie in unserem Beispiel, eine Farbe zu
ändern, muss die Zielfarbe als Parameter übergeben werden.
Bei changeColor wird String newColor als Parameter übergeben. String ist dabei
der Datentyp und newColor der Name des Parameters. Der Datentyp String steht
für eine Zeichenkette. Wir müssen der Methode changeColor also eine Zeichenkette übergeben. Wenn wir die Methode auswählen, werden wir aufgefordert, die
Zeichenkette einzugeben.
Da wir einen roten Kreis erstellen wollen, wählen wir als Zeichenkette red - und
erhalten einen Fehler. Die Fehlerbeschreibung cannot find symbol - variable
red hilft Ihnen wahrscheinlich nicht weiter, weshalb wir an dieser Stelle einspringen: Zeichenketten müssen in Java immer mit doppelten Anführungszeichen
geschrieben werden. Das Programm erkennt also red nicht als Zeichenkette. Wenn
wir "red" eintragen, erscheint keine Fehlermeldung.
Zeichenketten werden in
doppelten Anführungszeichen geschrieben
Wenn wir nun die gezeichneten Kreise betrachten (ggf. das Fenster mit
makeVisible() wieder aufrufen), sehen wir einen roten Kreis. Der blaue Kreis
ist jedoch nicht mehr da. Der Grund ist einfach: Der rote Kreis wurde über den
blauen gezeichnet. Als nächstes müssen wir also das redCircle-Objekt nach unten
verschieben. Dazu nutzen wir die Methode moveDown(). Nach einmaliger Auswahl
sehen wir beide Kreise, wobei der rote den blauen immer noch überlagert. Die
Methode sollte daher noch einige Male mehr ausgeführt werden, bis der rote Kreis
unter dem blauen liegt, wie in Abbildung 1.11 zu sehen ist.
Abb. 1.11: Beide Objekte
haben nun verschiedene
Attributwerte.
Zum Abschluss setzen wir uns noch zum Ziel, ein grünes Quadrat rechts von den
Seite 40
Studienbrief 1 Eine Einführung in Programmiersprachen
Kreisen zu zeichnen. Hierzu erstellen wir eine neue Instanz der Klasse Square und
nennen sie greenSquare.
K
Kontrollaufgabe 1.14: Verändern von Attributwerten
Verändern Sie das Objekt greenSquare mit den zur Verfügung stehenden
Methoden so, sodass Sie am Ende ungefähr folgendes Bild erhalten:
Hinweis: Sie müssen ggf. Methoden verwenden, die einen Parameter vom
Typ int haben. Der Datentyp int steht für ganzzahlige positive und negative
Werte.
Mit der oberen Kontrollaufgabe beenden wir die interaktive Einführung und
diesen Studienbrief. Sie sollten nun in der Lage sein, die Begriffe Klasse und Objekt
voneinander zu unterscheiden. Welche Eigenschaften bzw. Attribute ein Objekt
allgemein haben kann, wird in der Klasse definiert. Sie wissen, dass Methoden dazu
da sind, Eigenschaften von Objekten zu verändern oder allgemein mit dem Objekt
zu interagieren. Methoden können Parameter übergeben werden. Jeder Parameter
hat einen Datentyp. Sie haben die Datentypen String für Zeichenketten und int für
ganzzahlige Werte kennengelernt.
E
Exkurs 1.3: Klasse oder Objekt?
Es ist bei einer Bezeichnung nicht immer klar, ob es sich um eine Bezeichnung für eine Klasse oder ein Objekt handelt. Nehmen wir als Beispiel die
Bezeichnung Spinne. Die Spinne könnte sowohl ein Objekt der Klasse Tier
als auch eine eigene Klasse sein, zu der wir dann konkrete Spinnen (z. B.
„Tarantel“ oder „Hans“, der zahme Weberknecht aus der Tierhandlung A)
generieren können.
Entscheidend für die Zuordnung ist unsere Anwendung: Wollen wir Tiere
wie die Spinne nur ganz allgemein abbilden, z. B. mit einer Bezeichnung und
einer maximalen Größe? Dann reicht eine grobe Klasse wie Tier. Wollen
wir aber die Lagerverwaltung eines Zoogeschäftes programmieren, kann es
Sinn machen, mehr ins Detail zu gehen.
1.7 Zusammenfassung
Computer verstehen keine menschliche Sprache. Sie verstehen lediglich eine Kombination aus 0en und 1en. Dies wird als Maschinensprache bezeichnet. Basis dafür
1.7 Zusammenfassung
ist das Binärsystem. Anders als im Dezimalsystem, in dem an einer Stelle die Zahlen von 0 bis 9 stehen können, können im Binärsystem an einer Stelle nur die
Zahlen 0 oder 1 stehen. Neben dem Binärsystem gibt es theoretisch noch unendlich
viele weitere Zahlensysteme, von denen hauptsächlich das Oktal-, Dezimal- und
Hexadezimalsystem relevant sind. Alle Zahlen eines Zahlensystems lassen sich
beliebig in einem anderen Zahlensystem darstellen.
Um einen Computer auf einfache Weise Anweisungen zu geben, gibt es Programmiersprachen. Diese Sprachen sind oftmals näher an der menschlichen Sprache
und bieten eine Syntax, im Rahmen derer es möglich ist, dem Computer Anweisungen zu geben. Ein Compiler sorgt dafür, dass die in einer Programmiersprache
verfassten Anweisungen in eine für den Computer verständliche Sprache übersetzt
werden.
Eine besondere Art von Compiler ist der Assembler. Dieser übersetzt Assemblersprache in Maschinensprache. Assemblersprache selbst bietet Mnemonics, welche
den Opcodes eines Prozessors entsprechen.
Die Programmiersprache Java ist eine objektorientierte Programmiersprache, mit
der wir uns im Rahmen dieses Moduls beschäftigen werden. Java-Code wird nicht
direkt in Maschinencode übersetzt, sondern in eine Zwischensprache, den sogenannten Bytecode. Dieser Bytecode wird von der Java Virtual Machine (JVM)
ausgeführt. Vorteil davon ist, dass Bytecode auf jedem Computer funktioniert,
unabhängig von der Architektur. Voraussetzung ist lediglich, dass eine JVM vorhanden ist.
Bei einer objektorientierten Programmiersprache werden Anweisungen mit Hilfe
von Objekten formuliert. In einer Klasse werden die allgemeinen Eigenschaften
von gleichartigen Objekten, auch Attribute genannt, zusammengefasst. Neben den
Attributen werden in einer Klasse noch Methoden definiert. Mittels Methoden
kann man Objekte verändern oder Anweisungen an Objekte geben. Falls eine
Methode zusätzliche Informationen benötigt, um ausgeführt werden zu können,
können diese als Parameter übergeben werden. Für die Attribute, die in einer
Klasse definiert wurden, haben Objekte konkrete Attributwerte. Objekte gehören
immer einer Klasse an und werden auch als Instanz dieser Klasse bezeichnet.
Seite 41
Seite 42
Studienbrief 1 Eine Einführung in Programmiersprachen
1.8 Übungen
1.8.1 Erläuterungen zum Übungsablauf
Dieses Modul besteht aus zwei Lehrveranstaltungen, die jeweils im 1. bzw. 2.
Studiensemester angeboten werden. Am Ende des zweiten Semesters schreiben Sie
eine Prüfung, die den Stoff der beiden Lehrveranstaltungen abfragt. Diese Prüfung
ist 10 ECTS wert.
Um zu der Prüfung zugelassen zu werden, ist es notwendig, dass Sie die Übungsaufgaben am Ende jedes Studienbriefs bearbeiten. Es gibt dabei zwei verschiedene
Arten von Übungsaufgaben: Bepunktete und nicht-bepunktete Übungsaufgaben.
Bei den Nicht-bepunkteten bleibt es Ihnen überlassen, ob Sie die Aufgaben erledigen. Die Lösungen zu diesen Aufgaben gibt es im Verlauf des Semesters.
Die bepunkteten Aufgaben müssen Sie bearbeiten und über ein Abgabesystem,
das in der ersten bepunkteten Aufgabe erläutert wird, einreichen. Sie müssen in
jeder Lehrveranstaltung mindestens 70 % der Punkte erreichen, um zu der Prüfung
zugelassen zu werden.
Die Punkte für diese Lehrveranstaltung sind dabei folgendermaßen aufgeteilt:
• SB1: 10 Punkte
• SB2: 20 Punkte
• SB3: 30 Punkte
• SB4: 40 Punkte
• SB5: 50 Punkte
Es gibt also insgesamt 150 Punkte, die Sie erreichen können. Sie müssen davon
mindestens 105 erreichen, um zu der Prüfung zugelassen zu werden.
Es gibt aber einige Dinge, die das Bearbeiten der Aufgaben erleichtern und Sie
zusätzlich motivieren sollen:
• Sie haben bis kurz vor Ende des Semesters (15. März 2015) Zeit, die Lösungen
einzureichen
• Sie haben beliebig viele Versuche
• Sie erfahren nach jeder Einreichung, wie viele Punkte Sie erreicht haben
• Wenn Sie die Aufgaben früher lösen, werden Ihnen die erreichten Punkte
als Bonuspunkte angerechnet
• Ab einer bestimmten Zahl an Bonuspunkten erhalten Sie einen Notenbonus
in der Klausur
Die genauen Zeitpunkte, bis wann Übungsaufgaben abgegeben werden müssen,
damit die Punkte als Bonuspunkte zählen, erfahren Sie am Anfang des Semesters.
Um das System besser zu verstehen, ein Beispiel:
Die Übungsaufgabe des Studienbriefs 1 soll bis zum 30. Oktober abgegeben werden, um Bonuspunkte zu erhalten. Sie reichen die Aufgabe am 29. Oktober ein
und erreichen 8 Punkte. Diese Punkte wandern auf Ihr Bonuskonto. Da Sie nachträglich einen Fehler entdeckt haben, reichen Sie am 1. November eine verbesserte
Version der Aufgabe ein. Diesmal erhalten Sie die vollen 10 Punkte. Da die Frist
für die Aufgabe abgelaufen ist, erhalten Sie die 2 zusätzlichen Punkte nicht als
1.8 Übungen
Seite 43
Bonuspunkte. Da Sie aber generell bis zum Ende des Semesters Zeit haben, die
Aufgaben zu bearbeiten, zählen die zwei zusätzlichen Punkte natürlich zu Ihrem
Gesamtpunktestand, der für die Zulassung zur Prüfung wichtig ist, hinzu.
Sie haben also insgesamt bereits 10 Punkte erreicht, davon sind 8 Punkte Bonuspunkte.
Folgende Anzahl an Bonuspunkten müssen Sie erreichen, um die entsprechende
Notenverbesserung zu erhalten:
• 128 Punkte: Verbesserung um 0,3 Notenpunkte
• 142 Punkte: Verbesserung um 0,7 Notenpunkte
• 150 Punkte: Verbesserung um 1,0 Notenpunkte
Sie sehen also: Wenn Sie die Aufgaben frühzeitig bearbeiten, wirkt sich dies positiv
auf Ihre Note aus. Aber selbst, wenn Sie die Aufgaben nicht rechtzeitig bearbeiten
können, können Sie in der Klausur trotzdem noch eine 1,0 erreichen.
In der zweiten Lehrveranstaltung dieses Moduls können Sie ebenfalls Bonuspunkte
erreichen. Bei der Verbesserung des Notenschnittes wird aber der Durchschnitt aus
beiden Semestern berechnet, um die tatsächliche Verbesserung zu berechnen.
Angenommen, Sie haben im ersten Semester eine Verbesserung um 1,0 Notenpunkte erreicht, im zweiten Semester aber nur eine Verbesserung von 0,3. Dies ergibt
insgesamt eine Verbesserung von 0,7 Notenpunkten. Falls der Durchschnittswert
genau mittig zwischen zwei Notenpunkten steht, entscheidet die Verbesserung der
zweiten Lehrveranstaltung, da diese schwieriger ist. Wenn Sie also im ersten Semester eine Verbesserung von 0,7 und im zweiten Semester eine Verbesserung von
0,3 haben, erhalten Sie insgesamt nur eine Verbesserung von 0,3 Notenpunkten.
Die Verbesserung kann nur angerechnet werden, wenn die Klausur bestanden
wird. Sie müssen also in der Klausur mindestens die Note 4.0 erreichen.
Übung 1.1: Begriffe
Füllen Sie das Kreuzworträtsel aus.
Ü
Seite 44
Studienbrief 1 Eine Einführung in Programmiersprachen
Ü
:DDJHUHFKW
'DWHQW\SI¾UJDQ]]DKOLJH
:HUWH
/¦VVW2EMHNWH'LQJHWXQ
,QLKUZHUGHQ0HWKRGHQ
XQG$WWULEXWHGHILQLHUW
.DQQ0HWKRGHQ
¾EHUJHEHQZHUGHQ
%HLGHU'DUVWHOOXQJLVW
GDV.RPPDIHVW
KDUGZDUHQDKH
3URJUDPPLHUVSUDFKH
,QLKUODXIHQ
-DYD3URJUDPPH
(LJHQVFKDIWHLQHV
2EMHNWHV
'DWHQW\SI¾U=HLFKHQNHWWH
+DQVLVWHLQGHU.ODVVH
0HQVFK
(LQ=DKOHQV\VWHP
6\VWHP
9HUVFKLHEHQYRQ%LWV
6HQNUHFKW
1XPPHUQI¾U
0DVFKLQHQEHIHKOH
,(((LVWHLQH
'DUVWHOOXQJ
'DULQZLUGSURJUDPPLHUW
(LQ2EMHNWLVWHLQHHLQHU
.ODVVH
&RPSXWHUYHUVWHKHQQXU
$QZHLVXQJHQLP
žEHUVHW]W
$VVHPEOHUVVSUDFKH
žEHUVHW]W
3URJUDPPLHUVSUDFKHQLQ
DQGHUH
:HUWHLQHU(LJHQVFKDIW
HLQHV2EMHNWHV
.DQQQXURGHUVHLQ
:RUWHQWVSUHFKXQJHQYRQ
0DVFKLQHQEHIHKOHQ
(LQH3URJUDPPLHUVSUDFKH
%LW
Übung 1.2: IEEE-754
Wandeln Sie folgende Zahlen in die Gleitkommadarstellung nach IEEE-754
(32 Bit) um:
a) 4444,4444
b) -85,8875
c) 2209,87
1.8 Übungen
Übung 1.3: Einer- und Zweierkomplement
Stellen Sie folgende Zahlen im Einer- und Zweierkomplement dar:
Seite 45
Ü
a) -523
b) -5242
c) -127
Übung 1.4: Abgabesystem (10 Punkte)
Diese Aufgabe dient dazu, das Abgabesystem, das wir in dieser Lehrveranstaltung nutzen, kennenzulernen. Viele der Schritte, die Sie in dieser Aufgabe
durchführen, sind einmalig und müssen daher nicht für jede Übungsabgabe
wiederholt werden.
Die Aufgabe unterteilt sich grob in 4 Schritte:
• Ein Schlüsselpaar zur Authentifizierung generieren
• Ihren public-key auf der Webseite hochladen, um ihr Git-repository
zu generieren
• sich mit Git vertraut machen
• Ein Hello-World-Programm in das repository und in den richtigen
Ordner comitten.
Die einzelnen Schritte werden in Videos behandelt, die speziell für diese
Lehrveranstaltung aufgezeichnet wurden. Wenn sie analog zu den Video
mitarbeiten, haben Sie die Aufgabe bereits erfüllt.
Wichtig ist, dass Sie sich bei dieser und den kommenden Übungsabgaben
genau an die Vorgaben halten, was Ordnerstruktur, Dateinamen, Methodennamen und die Reihenfolge von Parametern betrifft. Nur so können Ihre
Aufgaben automatisiert korrigiert werden. Sofern nichts anderes gefordert
ist, sollen immer nur die .java-Dateien hochgeladen werden. Falls Sie andere
Dateien, wie zum Beispiel kompilierte Dateien oder Eclipse-Projekt-Dateien
hochladen, erhalten Sie einen Punktabzug.
Der folgende Code soll in einer Datei Hello.java gespeichert werden:
1
2
3
4
5
6
7
public class Hello
{
public static void main(String[] args)
{
System.out.println("Hello world");
}
}
Die Datei sollte sich in einem Order namens SB1 befinden, wenn Sie die
Datei ins Repository hochladen. Die Videos gehen noch einmal gesondert
auf diese Dinge ein.
Ü
Anhang
Anhang
Seite 153
Liste der Lösungen zu den Kontrollaufgaben
Liste der Lösungen zu den Kontrollaufgaben
Lösung zu Kontrollaufgabe 1.1 auf Seite 15
110011002 = 27 + 26 + 23 + 22 = 128 + 64 + 8 + 4 = 204
111111112 = 27 + · · · + 21 + 20 = 255 = 28 − 1
00000001 = 20 = 1
10000000 = 27 = 128
Lösung zu Kontrollaufgabe 1.2 auf Seite 15
00108 = 81 = 8
77778 = 7 · 83 + 7 · 82 + 7 · 81 + 7 · 80 = 84 − 1 = 4095
47068 = 4 · 83 + 7 · 82 + 6 · 80 = 2502
64038 = 6 · 83 + 4 · 82 + 3 · 80 = 3331
Lösung zu Kontrollaufgabe 1.4 auf Seite 16
102310 = 11 1111 1111 = 17778
59810 = 10 0101 0110 = 11268
97610 = 11 1101 0000 = 17208
Lösung zu Kontrollaufgabe 1.5 auf Seite 18
Bei den Internetprovidern entspricht DSL 16.000 meist einer Downloadrate von 16
MBit/s (Umrechnungszahl 1000 - also Zehnerpotenz). Dies entspricht 2MiB/s.
Lösung zu Kontrollaufgabe 1.6 auf Seite 18
Die Hersteller geben die Kapazität dezimal an. 4, 7GB entsprechen also 4, 7 · 109
Bytes. Wenn wir diese Zahl durch 23 0 teilen, erhalten wie die tatsächliche Kapazität
in GiB: 4, 377GiB. Dies entspricht einer prozentualen Abweichung von rund 7, 37
Prozent.
Lösung zu Kontrollaufgabe 1.7 auf Seite 19
10102 + 11112 = 110012
1010 10102 + 1010 10102 = 1 0101 01002
11 00112 + 11002 = 11 11112
1 11112 + 12 = 10 0000
Beachten Sie, dass in der Informatik eine bestimme Anzahl an Bits für eine Zahl
reserviert wird. So kann es passieren, dass bei einer Addition (oder Subtraktion)
die höchstwertigsten Bits verfallen und das Ergebnis so nicht korrekt ist. Dies
Seite 183
Seite 184
Liste der Lösungen zu den Kontrollaufgaben
passiert, wenn bei der Addition die maximal darstellbare Zahl durchschritten wird.
Wir sprechen auch von einem overflow.
Lösung zu Kontrollaufgabe 1.8 auf Seite 20
11112 − 11012 = 00102
1010 10112 − 1010 10102 = 0000 00012
11 00112 − 00 11002 = 10 01112
1 11112 − 1 01012 = 0 10102
Lösung zu Kontrollaufgabe 1.9 auf Seite 21
10 10112 >> 4 = 00 00102
00 11002 >> 2 = 00 00112
11 11112 << 6 = 00 0000
(11 00112 << 2) >> 2 = 00 00112
Lösung zu Kontrollaufgabe 1.10 auf Seite 22
11002 & 00112 = 00002
(1111 00002 >> 4) XOR 1111 11112 = 1111 00002
10012 | 01102 = 11112
NOT (710 ) = NOT (1112 ) = 0002
1011 00002 XOR 16410 = 1011 00002 XOR 1010 01002 = 0001 0100
(1011 00002 OR 23210 ) XOR 0x f 0
= (1011 00002 OR 1110 10002 ) XOR 1111 00002
= 1111 10002 XOR 1111 00002
= 0000 10002
Lösung zu Kontrollaufgabe 1.12 auf Seite 26
84, 55 = 0101 0100 1000 1100 = 84, 546875
Differenz: 0,003125
255, 97 = 1111 1111 1111 1000 = 255, 96875
Differenz: 0,00125
8, 015625 = 0000 1000 0000 0100
Differenz: 0
Liste der Lösungen zu den Kontrollaufgaben
Lösung zu Kontrollaufgabe 1.13 auf Seite 30
a)
2745, 888 = 0 10001010 01010111001111000110101
b)
2, 5668 = 0 1000 0000 01001000100011001110100
Seite 185
Verzeichnisse
Seite 187
Verzeichnisse
I. Abbildungen
Abb.
Abb.
Abb.
Abb.
Abb.
1.1:
1.2:
1.3:
1.4:
1.5:
Umrechnung vom Dezimal- ins Binärsystem am Beispiel von 110. . . . . . . . . . . . . . . .
Umwandlung in die binäre Festkommadarstellung . . . . . . . . . . . . . . . . . . . . . . . .
Zuordnung von Nachkommabit zu Wert. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Umwandlung von Assemblersprache in Maschinensprache durch den Assembler. . . . . . .
Ein Compiler übersetzt eine Programmiersprache in eine andere Programmiersprache oder
direkt in Maschinensprache. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Abb. 1.6: Der Java-Compiler kompiliert Java-Code nicht direkt in Maschinensprache, sondern in Java
Bytecode. Dieser wird in der JVM zu Maschinensprache übersetzt. . . . . . . . . . . . . . . .
Abb. 1.7: Die Klassen, die im Project „Shapes“ verwendet werden. . . . . . . . . . . . . . . . . . . . .
Abb. 1.8: Das Objekt blueCircle, eine Instanz der Klasse Circle. . . . . . . . . . . . . . . . . . . . .
Abb. 1.9: Das gezeichnete Objekt „blueCircle“. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Abb. 1.10: Attribute des Objekts „redCircle“. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Abb. 1.11: Beide Objekte haben nun verschiedene Attributwerte. . . . . . . . . . . . . . . . . . . . . .
Abb. 2.1: Die Bestandteile einer Klasse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Abb. 2.2: Defintion von der Klasse sowie von Attributen. . . . . . . . . . . . . . . . . . . . . . . . . . .
Abb. 2.3: Die Definition von Instanzmethoden. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Abb. 2.4: Eine Methode unterteilt sich in einen Methodenkopf und einen Methodenrumpf. . . . . . . .
Abb. 2.5: Beide Variablen zeigen auf denselben Platz im Hauptspeicher. . . . . . . . . . . . . . . . . .
Abb. 2.6: Gültigkeitsbereiche von Variablen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
25
26
32
34
35
37
37
38
38
39
47
51
56
56
69
70
II. Beispiele
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
Beispiel
1.1:
1.2:
1.3:
1.4:
2.1:
2.2:
2.3:
2.4:
2.5:
2.6:
2.7:
2.8:
2.9:
2.10:
2.11:
2.12:
2.13:
3.1:
3.2:
3.3:
3.4:
Hexadezimalzahlen . . . . . . . . . . . . . . . . . . . . . .
Bitshifting . . . . . . . . . . . . . . . . . . . . . . . . . . .
Von der Dezimalzahl in die Gleitkommadarstellung . . . .
Von der Gleitkommadarstellung in die Dezimaldarstellung
Shortcuts und Funktionen in Eclipse . . . . . . . . . . . . .
Mehrzeilige Kommentare . . . . . . . . . . . . . . . . . . .
mixedCase . . . . . . . . . . . . . . . . . . . . . . . . . .
Methodenkopf . . . . . . . . . . . . . . . . . . . . . . . .
System.out.println() . . . . . . . . . . . . . . . . . . .
Rückgabe mit return . . . . . . . . . . . . . . . . . . . .
Babyautos . . . . . . . . . . . . . . . . . . . . . . . . . . .
Eine ausführbare Klasse . . . . . . . . . . . . . . . . . . .
Konstruktor . . . . . . . . . . . . . . . . . . . . . . . . . .
this . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Default-Konstruktor 1 . . . . . . . . . . . . . . . . . . . .
Default-Konstruktor 2 . . . . . . . . . . . . . . . . . . . .
Statische Methoden 1 . . . . . . . . . . . . . . . . . . . .
Sichtbarkeiten . . . . . . . . . . . . . . . . . . . . . . . .
Klasse Human mit Sichtbarkeiten . . . . . . . . . . . . . .
Gerade oder ungerade? . . . . . . . . . . . . . . . . . . .
Zählen von 1 bis 10 mit while . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
19
21
29
30
50
52
55
57
59
66
68
72
73
74
75
75
77
89
91
98
103
III. Definitionen
Definition 1.1: Zahlensysteme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Definition 1.2: Wertigkeit einer Zahl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
14
Seite 188
Verzeichnisse
IV. Exkurse
Exkurs
Exkurs
Exkurs
Exkurs
Exkurs
Exkurs
Exkurs
Exkurs
Exkurs
Exkurs
Exkurs
Exkurs
Exkurs
1.1:
1.2:
1.3:
2.1:
2.2:
2.3:
3.1:
3.2:
3.3:
3.4:
4.1:
D.1:
D.2:
3,5-Zoll-Disketten . . . . . . . . . . .
Einheitliches Format . . . . . . . . .
Klasse oder Objekt? . . . . . . . . . .
Modularisierung . . . . . . . . . . . .
Overflow . . . . . . . . . . . . . . . .
Ganzzahlige Division . . . . . . . . .
Usereingaben . . . . . . . . . . . . .
fill-Methode . . . . . . . . . . . . .
foreach-Schleife . . . . . . . . . . . .
Immutable . . . . . . . . . . . . . . .
Die Klasse Object . . . . . . . . . . .
Label . . . . . . . . . . . . . . . . . .
Zwei verschiedene Vorgehensweisen
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
17
18
40
51
54
62
98
105
108
112
125
171
176
Umrechnung ins Dezimalsystem . .
Oktalsystem . . . . . . . . . . . . .
Zweierpotenzen . . . . . . . . . . .
Zahlenkonvertierung . . . . . . . .
Downloadgeschwindigkeit . . . . .
Speicherplatz einer DVD . . . . . .
Addition . . . . . . . . . . . . . . .
Subtraktion . . . . . . . . . . . . . .
Bitshifting . . . . . . . . . . . . . .
Binäre Operatoren . . . . . . . . . .
Kombination von Operatoren . . . .
Festkommadarstellung . . . . . . .
IEEE 754 . . . . . . . . . . . . . . .
Verändern von Attributwerten . . .
IDEs . . . . . . . . . . . . . . . . . .
Texteditoren . . . . . . . . . . . . .
Konventionen bei Attributen . . . .
Klassen . . . . . . . . . . . . . . . .
Methodenköpfe . . . . . . . . . . .
Anlegen von Variablen . . . . . . . .
Gerade und ungerade Zahlen . . . .
Variablenwert . . . . . . . . . . . .
Inkrement . . . . . . . . . . . . . .
Kopieren von Objekten . . . . . . .
Konstruktoren . . . . . . . . . . . .
String-API . . . . . . . . . . . . . . .
Random . . . . . . . . . . . . . . .
Wird der Code ausgeführt? . . . . .
if-Statements . . . . . . . . . . . .
Gerade Zahlen zwischen 0 und 1000
Zählen von 1 bis 10 mit do-while .
Kopf- oder fußgesteuert? . . . . . .
Wrapperklassen . . . . . . . . . . .
MyTwitter . . . . . . . . . . . . . . .
Die Klasse Dog . . . . . . . . . . . .
Gemeinsamkeiten . . . . . . . . . .
Annotations . . . . . . . . . . . . .
Code reduzieren . . . . . . . . . . .
Comparable . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
15
15
15
16
18
18
19
20
21
22
23
26
30
40
49
50
55
56
58
61
63
65
65
69
76
92
92
96
99
102
104
104
112
114
124
124
128
129
135
V. Kontrollaufgaben
Kontrollaufgabe 1.1:
Kontrollaufgabe 1.2:
Kontrollaufgabe 1.3:
Kontrollaufgabe 1.4:
Kontrollaufgabe 1.5:
Kontrollaufgabe 1.6:
Kontrollaufgabe 1.7:
Kontrollaufgabe 1.8:
Kontrollaufgabe 1.9:
Kontrollaufgabe 1.10:
Kontrollaufgabe 1.11:
Kontrollaufgabe 1.12:
Kontrollaufgabe 1.13:
Kontrollaufgabe 1.14:
Kontrollaufgabe 2.1:
Kontrollaufgabe 2.2:
Kontrollaufgabe 2.3:
Kontrollaufgabe 2.4:
Kontrollaufgabe 2.5:
Kontrollaufgabe 2.6:
Kontrollaufgabe 2.7:
Kontrollaufgabe 2.8:
Kontrollaufgabe 2.9:
Kontrollaufgabe 2.10:
Kontrollaufgabe 2.11:
Kontrollaufgabe 3.1:
Kontrollaufgabe 3.2:
Kontrollaufgabe 3.3:
Kontrollaufgabe 3.4:
Kontrollaufgabe 3.5:
Kontrollaufgabe 3.6:
Kontrollaufgabe 3.7:
Kontrollaufgabe 3.8:
Kontrollaufgabe 3.9:
Kontrollaufgabe 4.1:
Kontrollaufgabe 4.2:
Kontrollaufgabe 4.3:
Kontrollaufgabe 4.4:
Kontrollaufgabe 4.5:
Tabellen
Seite 189
VI. Tabellen
Tabelle
Tabelle
Tabelle
Tabelle
Tabelle
Tabelle
Tabelle
1.1:
1.2:
1.3:
1.4:
1.5:
2.1:
3.1:
Dezimalzahlen und ihre Entsprechung im Binärsystem . . . . .
Binär- und Dezimalpräfixe im Vergleich. Die Kürzel beziehen sich
Hexadezimalzahlen und ihre Entsprechung im Dezimalsystem. .
Binäre Verknüpfungen . . . . . . . . . . . . . . . . . . . . . . .
Darstellung negativer Zahlen im Dualsystem. . . . . . . . . . .
Primitive Datentypen in Java . . . . . . . . . . . . . . . . . . . .
Binäre Verknüpfungen . . . . . . . . . . . . . . . . . . . . . . .
. .
auf
. .
. .
. .
. .
. .
. .
die
. .
. .
. .
. .
. .
. . . . . . . . . . .
Byte-Schreibweise.
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
15
17
18
22
25
53
96
VII. Literatur
David J Barnes and Michael Kölling. Java lernen mit BlueJ. Pearson, 2013.
Lasse Koskela. Test Driven: Practical TDD and Acceptance TDD for Java Developers. Manning Pubn, 2007.
Guido Krüger and Thomas Stark. Handbuch der Java-Programmierung: Standard Edition Version 6. AddisonWesley, 2009.
Kathy Sierra and Bert Bates. Java von Kopf bis Fuss. O Reilly, 2006.
Herunterladen