Vorlesungsscript gesamte Vorlesung

Werbung
Kurs
PPG
Prozedurale
Programmierung
© 2008
Prof. Dr. Hans-Peter Hutter
Zürcher Hochschule für Angewandte Wissenschaften
Mitglied der Fachhochschule Zürich
Version 1.7
Inhaltsverzeichnis
1 Grundlagen .......................................................................................................................... 1
1.1 Ziele .......................................................................................................................... 1
1.2 Was ist ein Computer? .............................................................................................. 1
1.3 Personal Computer (PC) ........................................................................................... 2
1.4 Arbeitsweise eines Computers .................................................................................. 2
1.5 Programme ................................................................................................................ 5
1.6 Dateien ...................................................................................................................... 7
1.7 Geschichte des Computers ...................................................................................... 10
2 Einführung in Java ............................................................................................................ 12
2.1 Ziele ........................................................................................................................ 12
2.2 Objektorientierte Programmierung: Einführung .................................................... 12
2.2.1 Motivation ........................................................................................................ 12
2.2.2 OO-Pogrammierung und Prozedurale Programmierung .................................. 12
2.2.3 Wichtige Begriffe der OOP .............................................................................. 15
2.3 Was ist eine Programmiersprache .......................................................................... 19
2.4 Übersicht über Java ................................................................................................ 20
2.5 Ein erstes Java-Programm ...................................................................................... 22
2.5.1 Anwendungen und Applets .............................................................................. 22
2.5.2 Das erste Applet ............................................................................................... 22
2.5.3 Entwicklung eines lauffähigen Applet-Programms ......................................... 24
2.6 Programmierfallen .................................................................................................. 27
2.7 Integrierte Entwicklungsumgebungen .................................................................... 27
3 Einfache Grafiken ............................................................................................................. 28
3.1 Ziele ........................................................................................................................ 28
3.2 Anweisung .............................................................................................................. 28
3.3 Methodenaufruf ...................................................................................................... 28
3.4 Der grafische Bildschirm ........................................................................................ 30
3.5 Ein erstes Bild ......................................................................................................... 30
3.6 Die Methode paint .............................................................................................. 32
3.7 Weitere Methoden zum Zeichnen ........................................................................... 32
3.8 Farben ..................................................................................................................... 33
3.9 Gefüllte Formen ...................................................................................................... 34
3.10 Die Befehlssequenz ................................................................................................ 35
3.11 Kommentare ........................................................................................................... 35
4 Variablen und Berechnungen ............................................................................................ 36
4.1 Ziele ........................................................................................................................ 36
4.2 Einführung .............................................................................................................. 36
4.3 Interne Darstellung von Daten im Computer ......................................................... 36
4.3.1 Das Binärsystem ............................................................................................... 36
4.3.2 Das Hexadezimalsystem .................................................................................. 39
4.3.3 Darstellung von Zeichen .................................................................................. 40
4.4 Datentypen für ganze und reelle Zahlen ................................................................. 42
4.5 Zahlendarstellung in Java ....................................................................................... 43
4.6 Variablen ................................................................................................................ 44
4.6.1 Einführung ........................................................................................................ 44
4.6.2 Java-Konventionen ........................................................................................... 45
4.6.3 Variablendeklaration ........................................................................................ 46
4.6.4 Allgemeine Beschreibung von Syntaxregeln ................................................... 47
4.7 Zuweisung (assignment) ......................................................................................... 48
4.8 Ausdruck (expression) ............................................................................................ 49
4.9 Arithmetische Operatoren ....................................................................................... 49
4.10 Darstellung von Variablen ...................................................................................... 50
4.11 Typkonversion (type cast) ...................................................................................... 51
PPG.1.7IVZ.fm
2
Inhaltsverzeichnis
5
6
7
8
9
4.12 Programmierfallen .................................................................................................. 51
Entscheidungen ................................................................................................................. 52
5.1 Ziele ........................................................................................................................ 52
5.2 Ablaufstrukturen ..................................................................................................... 52
5.2.1 Block ................................................................................................................ 52
5.2.2 Sequenz ............................................................................................................ 53
5.2.3 Zusätzliche Ablaufstrukturen ........................................................................... 54
5.3 Auswahlanweisungen ............................................................................................. 55
5.3.1 Einfache Auswahl ............................................................................................ 55
5.3.2 Mehrfachauswahl ............................................................................................. 59
5.4 Vergleichsoperatoren .............................................................................................. 61
5.5 Logische Operatoren ............................................................................................... 62
5.6 Logische Variablen ................................................................................................. 64
Wiederholungen ................................................................................................................ 65
6.1 Ziele ........................................................................................................................ 65
6.2 Einführung .............................................................................................................. 65
6.3 Schleifen in Java ..................................................................................................... 68
6.3.1 while–Schleife (1) ......................................................................................... 68
6.3.2 do ... while-Schleife (2) ......................................................................... 70
6.3.3 for-Schleife (3) ............................................................................................... 72
6.4 Verschachtelte Schleifen ........................................................................................ 74
6.5 Kombinierte Ablaufstrukturen ................................................................................ 76
Methoden .......................................................................................................................... 79
7.1 Ziele ........................................................................................................................ 79
7.2 Motivation .............................................................................................................. 79
7.3 Eine erste eigene Methode ...................................................................................... 80
7.4 Lokale Variablen .................................................................................................... 82
7.5 Methodendeklaration .............................................................................................. 82
7.6 Entwicklung einer Methode .................................................................................... 83
7.7 Aufruf einer Methode ............................................................................................. 85
7.8 Parameterübergabe ................................................................................................. 85
7.9 Rückgabe der Resultate .......................................................................................... 87
7.10 Programmierfallen .................................................................................................. 89
Ereignisse .......................................................................................................................... 90
8.1 Ziele ........................................................................................................................ 90
8.2 Einführung .............................................................................................................. 90
8.3 Ereignisse in Java (Event) ...................................................................................... 92
8.4 Java-Ereignis-Modell (ab Version 1.1) .................................................................. 93
8.5 Ereignisklassen ....................................................................................................... 93
8.6 Button (Schaltfläche) .............................................................................................. 94
8.7 Instanzvariablen ...................................................................................................... 99
8.8 Textzeile (TextField) ............................................................................................ 100
8.9 Schieberegler (Scrollbar) ...................................................................................... 102
8.10 Labels .................................................................................................................... 104
8.11 Skalierung des Schiebereglerwertes ..................................................................... 106
8.12 Aufbauen von Grafiken ........................................................................................ 108
Datentypen ...................................................................................................................... 110
9.1 Ziele ...................................................................................................................... 110
9.2 Einführung ............................................................................................................ 110
9.3 Einfache Datentypen ............................................................................................. 110
9.3.1 Ganze Zahlen .................................................................................................. 110
9.3.2 Logische Werte .............................................................................................. 111
PPG.1.7IVZ.fm
3
Inhaltsverzeichnis
9.3.3 Zeichen (Character) ........................................................................................ 111
9.3.4 Implizite Umwandlung von einfachen Datentypen ........................................ 113
9.3.5 Ein- und Ausgabe ........................................................................................... 113
9.3.6 Ausnahmebedingungen .................................................................................. 115
9.4 Referenzdatentypen .............................................................................................. 116
9.5 Bibliothek der math. Funktionen .......................................................................... 118
10 Array ............................................................................................................................... 119
10.1 Ziele ...................................................................................................................... 119
10.2 Einführung ............................................................................................................ 119
10.3 Arrays in Java ....................................................................................................... 120
10.4 Umgang mit Array-Elementen ............................................................................. 122
10.5 Umgang mit dem Array als Ganzem .................................................................... 122
10.6 Arrays von Objekten ............................................................................................. 124
10.7 Programmierfallen ................................................................................................ 126
11 Zweidimensionale Arrays ............................................................................................... 127
11.1 Ziele ...................................................................................................................... 127
11.2 Einführung ............................................................................................................ 127
11.3 Zweidimensionale Arrays in Java ......................................................................... 127
11.4 Deklaration und Erzeugung .................................................................................. 128
11.5 Initialisierung ........................................................................................................ 129
11.6 Umgang mit Array-Elementen ............................................................................. 130
11.7 Übergabe von Arrays als Parameter ..................................................................... 130
11.8 Beispielprogramm Sales ....................................................................................... 131
11.9 Aufgabe ................................................................................................................ 135
12 Zeichenketten (Strings) ................................................................................................... 136
12.1 Ziele ...................................................................................................................... 136
12.2 Einführung ............................................................................................................ 136
12.3 Strings ................................................................................................................... 136
12.4 Rekapitulation zur String-Klasse ..................................................................... 137
12.5 Methoden der Klasse String ........................................................................... 138
12.6 Reguläre Ausdrücke ............................................................................................. 140
12.7 Klasse StringTokenizer ............................................................................... 142
12.8 String als Parameter .............................................................................................. 142
12.9 Beispiel: replace-Methode .............................................................................. 143
PPG.1.7IVZ.fm
4
1
Grundlagen
1.1
Ziele
•
•
•
•
Sie können das Wesen eines Computers erklären.
Sie können die Arbeitsweise eines Computers anhand des EVA-Schemas abstrahieren.
Sie können den Unterschied zwischen Daten und Programmen erklären.
Sie können den Unterschied zwischen einem Programm und einem Prozess in eigenen Worten
erklären.
• Sie können das Dateisystem und die wichtigsten Befehle dazu anhand einer Zeichnung erklären.
1.2
Was ist ein Computer?
• Tragen Sie hier eine Liste von Geräten ein, die Sie als Computer bezeichnen würden:
..................................................................................................................................................
..................................................................................................................................................
..................................................................................................................................................
..................................................................................................................................................
..................................................................................................................................................
• Lernaufgabe in 2er-Gruppen: Was machen diese Computer eigentlich?
Wählen Sie ein Beispiel eines Computers von vorher aus. Überlegen Sie sich: Was macht der
Computer nachdem er einmal eingeschalten ist? Schreiben Sie Ihre Überlegungen in Stichworten
auf:
..................................................................................................................................................
..................................................................................................................................................
..................................................................................................................................................
..................................................................................................................................................
..................................................................................................................................................
• Wesen eines Computers:
• Hauptaktivitäten eines Computers:
• Eingabe: Der Computer wartet auf die Eingabe von Daten in irgend einer Form.
• Tastatur, Maus
• Signal von externer Leitung (Ethernet, Modem, etc.)
• Zeitsignal von einer Uhr
• Geld, Waren, etc.
• Verarbeitung: Er verarbeitet die Eingabedaten (eventuell zusammen mit internen Daten).
• selbständig (Rechenschieber ist noch kein Computer)
• mehr als nur Grundoperationen (Einfacher Rechner, Schreibmaschine sind noch keine
Computer)
• Ausgabe: Er gibt Resultat (ebenfalls Daten) aus der Verarbeitung in irgend einer Form zurück.
• Bildschirm, Drucker, akustisch
• Geld, Kaffee, Sandwich
1.3
Personal Computer (PC)
• Ein PC ist ein Computer, der für verschiedenste Aufgaben eingesetzt werden kann:
• Bearbeiten von Texten, Zeichnungen, Bildern, Musik
• Terminkalender
• E-Mail
• Internet-Zugang
• uam.
• Was braucht es dazu?
• Eine Komponente für die Datenverarbeitung: Prozessor.
• Komponenten für Datenspeicherung: Arbeitsspeicher, Harddisk, CD-Rom, etc.
• Komponenten für Dateneingabe: Tastatur, Maus, Modem
• Komponenten für Datenausgabe: Bildschirm, Drucker, Modem
• Programme für die verschiedenen Aufgaben
1.4
Arbeitsweise eines Computers
• Obwohl ein Computer die unterschiedlichsten Aufgaben erledigen kann, beruht seine Arbeitsweise
auf einem einfachen Prinzip.
• Dieses kann mit folgender Analogie umschrieben werden:
Ein Computer gleicht einem Mann (oder einer Frau) mit einem Taschenrechner und zwei Stapeln
von Rechnungen: Auf dem einen sind die unerledigten, auf dem anderen die erledigten. Der Mann
nimmt eine Rechnung nach der anderen, und schaut, was er berechnen muss. Dann tippt er die
Zahlen auf dem Blatt in den Rechner und gibt nacheinander die auszuführenden Operationen ein.
Hin und wieder schreibt er sich ein Zwischenresultat auf einen Zettel. Schliesslich schreibt er das
Ergebnis vom Display des Rechners ab und trägt es an der richtigen Stelle im Formular ein.
• Ein Computer setzt dieses Prinzip technisch um. Die Computer wurden im Verlauf der Geschichte
stetig optimiert und stellen heute hochkomplexe technische Systeme dar.
PPG.1.7.fm
2
• Nichtsdestotrotz kann die Arbeitsweise eines Computers auch heute noch für die meisten
Programmieraufgaben mit dem einfachen Schema in Abbildung 1 abstrahiert werden.
Prozessor
Rechenwerk
Steuerwerk
Operanden
Ergebnis
Befehle
Arbeitsspeicher
Eingabe
Ausgabe
Figur 1: EVA-Schema eines Computers
• Das sogenannte EVA-Schema (EVA: Eingabe-Verarbeitung-Ausgabe) besteht aus dem Prozessor,
dem Arbeitsspeicher sowie einer Eingabe und einer Ausgabe.
• Die einzelnen Komponenten in diesem Schema haben folgende Aufgaben:
• Prozessor
• Der Prozessor ist das Herz des Computers. Er arbeitet eng mit dem Arbeitsspeicher
zusammen.
• Er hat einen fixen Befehlssatz (Grundoperationen, Transportbefehle, Sprünge).
• Beispiel einer typischen Operation:
– Der Prozessor holt zwei Zahlen aus dem Arbeitsspeicher, addiert sie, und schreibt das
Resultat in den Arbeitspreicher zurück.
• Der Prozessor kann in zwei weitere Einheiten unterteilt werden:
– Rechenwerk
– Das Rechenwerk entspricht dem Taschenrechner von vorher.
– Es führt die Grundrechenarten + – * / auf den Eingabewerten (Operanden) aus und
berechnet daraus das Ergebnis.
– Steuerwerk:
– Das Steuerwek entspricht dem Mann, der den Taschenrechner bedient.
– Es steuert den Ablauf der Berechnungen.
– Dazu holt es einen Befehl nach dem andern vom Arbeitspeicher und interpretiert den
Befehl.
– Es sagt dem Rechenwerk, welche Operation als nächstes auszuführen ist und stellt die
Operanden für das Rechenwerk bereit.
– Es sorgt dafür, dass das Ergebnis wieder in den Arbeitsspeicher abgelegt wird.
– Schliesslich koordiniert es auch das Schreiben und Lesen des Arbeitsspeichers (sowohl
vom Prozessor als auch von den E/A-Geräten).
PPG.1.7.fm
3
• Arbeitsspeicher
• Der Arbeitspeicher speichert alle Daten, die der Prozessor im Moment braucht.
• Er speichert zudem auch die Befehle (Instruktionen), die dem Prozessor sagen, was er machen
muss.
• Man nennt eine solche Prozessorarchitektur, bei der Befehle und Daten im gleichen
Arbeitsspeicher liegen, Von-Neumann-Struktur.
• Der Arbeitsspeicher besteht aus einer grossen Anzahl einzeln ansprechbarer Speicherzellen.
• Eigenschaften einer Speicherzelle
– Sie kann entweder ein Datum (Zahl, Zeichen, etc.) oder einen Befehl für den Prozessor
enthalten. Sie hat eine fixe Länge 8, 16, 32 oder 64 Binärstellen (Bits)
– Eine Binärstelle wird als Bit (Binary Digit oder deutsch Binärziffer) bezeichnet. Ein Bit
kann nur zwei mögliche Werte annehmen: 0 oder 1.
– 8 Bit werden häufig zu einem Byte zusammengefasst. Mit einem Byte sind dementsprechend 256 (= 28 ) verschiedene Werte darstellbar.
• Jede Speicherzelle hat eine eindeutige Adresse (0..MaxSpeicher), mit der sie angesprochen
wird.
• Der Adressraum, d.h. die maximal addressierbare Anzahl Speicherzellen eines Prozessors
sind durch seine Anzahl Adressleitungen, in der Regel 32 (manchmal sogar 64), gegeben. Er
beträgt somit 232 = 4G (Giga = Milliarden) addressierbare Speicherplätze.
• Eine Speicherzelle wird als Ganzes gelesen und geschrieben.
• Wird ein neuer Wert in eine Speicherzelle geschrieben, so geht der alte Wert verloren.
• Beim Ausschalten gehen alle Daten im Arbeitsspeicher verloren.
• Das Steuerwerk des Prozessors legt genau fest, wann Daten in den Arbeitsspeicher
geschrieben bzw. herausgelesen werden dürfen (synchroner Ablauf). Eine Speicherzelle darf
nicht gleichzeitig beschrieben und ausgelesen werden.
• Dank der synchronen Arbeitsweise des Prozessors ist der Ablauf eines korrekten Programms
vollständig reproduzierbar, d.h. es gibt immer das gleiche Resultat.
• Eingabe
• Die Eingabe bezeichnet Komponenten, die Daten von extern in den Arbeitsspeicher
schreiben.
• Beispiele für solche Komponenten sind die Tastatur, die Harddisk, das Modem etc.
• In der Analogie im obigen Beispiel entspricht dies dem Stapel unerledigter Rechnungen.
• Ausgabe
• Die Ausgabe bezeichnet Komponenten, die Daten vom Speicher abholen und sie nach aussen
geben.
• Beispiele für Ausgabekomponenten sind der Bildschirm, der Drucker, das Modem etc.
• In der Analogie im obigen Beispiel entspricht dies dem Stapel mit erledigten Rechnungen.
• Befehlszyklus:
Der Prozessor in Abbildung 1 führt immer denselben sogenannten Befehlszyklus aus:
1. Nächsten Befehl vom Arbeitsspeicher holen und interpretieren
2. Operanden vom Arbeitsspeicher holen
3. Berechnung ausführen
4. Ergebnis in den Arbeitsspeicher ablegen
Der gesamte Befehlszyklus und alle Lese- und Schreiboperationen auf dem Arbeitsspeicher laufen
synchron zum Prozessortakt ab.
PPG.1.7.fm
4
1.5
Programme
• Woher kommen die Befehle, die dem Prozessor sagen, was er tun muss?
• Die Befehle für den Prozessor stehen in den sogenannten Programmen. Sie sagen dem Prozessor,
welche Befehle er der Reihe nach ausführen muss.
• Man nennt die Programme häufig auch Software, im Gegensatz zur Hardware (Computer,
Bildschirm, Tastatur, etc.)
• Programm
• Programme kann man kaufen, kopieren oder auch selber programmieren.
• Ein Programm ist normalerweise auf HD, CDROM etc. gespeichert.
• Es muss zuerst in Arbeitsspeicher geladen werden.
• Sodann muss der Prozessor wissen, wo der 1. Befehl des Programms steht (Einstiegspunkt).
• Nun führt der Prozessor die Befehle des Programms einen nach dem andern aus.
• Ein Programm ist also nichts anderes als eine Abfolge (Sequenz) von Prozessorbefehlen, den
sogenannten Maschinenbefehlen.
• Der Prozessor holt die Befehle der Reihe nach aus dem Arbeitsspeicher und arbeitet einen Befehl
nach dem anderen ab.
• Der Prozessor weiss immer nur gerade, wo der nächste Befehl steht.
• Der Befehlssatz des Prozessors ist fix vorgegeben. Das Programm bestimmt nur, welche Befehle
und in welcher Reihenfolge sie ausgeführt werden (Sprungbefehle).
• Arten von Programmen
Die folgenden Liste zählt verschiedene Arten von Programmen beispielhaft auf:
• Monitorprogramm (Startprogramm des Computers)
• Betriebssystem
• Verwaltet Prozesse, Dateien, Ein-/Ausgabegeräte
• Stellt Benutzerschnittstellen zur Verfügung
– Graphische Benutzeroberfläche
– interpretiert Benützer-Eingaben über die Tastatur und über die Maus
– Kommandozeile (Kommando-Interpreter)
– interpretiert nur Befehle, die der Benützer über die Tastatur eingibt
– Diese Benützerbefehle werden direkt in die entsprechende Maschinenbefehle
umgesetzt und ausgeführt.
• Hilfsprogramme
• Treiber für Drucker, Bildschirm, Harddisk etc.
• Anti-Virus-Programme
• Standardsoftware
• Textverarbeitung
• Grafikprogramme
• Datenbanken
• Internet-Browser
• Mail
• Tabellenkalkulationsprogramme
• Mathematik, Statistik
• Compiler für Programmiersprachen
• Die Maschinenbefehle sind prozessorabhängig.
• Ein Programm wird heute nur noch äusserst selten direkt in Maschinenbefehlen geschrieben,
da dies sehr mühsam und unübersichtlich ist.
PPG.1.7.fm
5
• Stattdessen werden Programme in einer höheren Programmiersprache geschrieben und dann
von sogenannten Compilern in die Maschinensprache des Prozessors übersetzt.
• Höhere Programmiersprachen erlauben die effiziente Entwicklung von Software.
• Diese Programmiersprachen sind möglichst unabhängig vom Prozessor, auf dem das
Programm schliesslich laufen soll.
• Anwenderprogramme
• Alle Programme, die von den Anwendern geschrieben wurden.
• Beispiele:
– Spiele
– Flugreservationssystem
– Stundenplan
– Simulator
• Prozess
• Ein Prozess ist ein Programm, das gerade vom Prozessor (sequentiell) abgearbeitet wird.
• Heutige Prozessoren können quasi gleichzeitig mehrere Prozesse abarbeiten.
• Bsp.: Betriebssystem, Textverarbeitung und Browser laufen (scheinbar) gleichzeitig.
• Der Prozessor schaltet dazu blitzschnell zwischen den Prozessen hin und her und führt dabei
jeweils eine kleine Anzahl Befehle jedes Prozesses aus.
• Für den Benützer scheinen die Programm dann parallel abzulaufen.
• Die einzelnen Programme laufen umso langsamer, je mehr Prozesse gleichzeitig laufen.
• Ein Prozess entspricht einem simulierten Computer (siehe Figur 2):
• Er arbeitet nach dem gleichen EVA-Schema wie der Computer.
• Jeder Prozess hat einen eigenen Arbeitsspeicherbereich mit Daten und Befehlen (Programm).
• Der Prozessor arbeitet die Befehle des Prozesses in der gewünschten Reihenfolge ab.
• Der Prozess besitzt ebenfalls Ein-/Ausgabekomponenten, um Daten aus seinem
Arbeitsspeicher nach aussen zu geben oder von aussen in den Arbeitsspeicher zu holen.
• Prozesse können auch gegenseitig Daten austauschen.
• Die Prozesse merken normalerweise nichts voneinander, ausser wenn sie Daten austauschen.
Dann tritt der eine Prozess als Eingabekomponente des anderen auf und/oder umgekehrt.
Prozessor
Operanden
Ergebnis
Befehle
ProzessArbeitsspeicher
Eingabe
Ausgabe
Figur 2: EVA-Schema eines Prozesses
PPG.1.7.fm
6
1.6
Dateien
• Daten, die der Computer erzeugt, werden häufig für die spätere Wiederverwendung auf externen
Speichern abgelegt in einer sogenannten Datei.
• Datei (engl. file)
• ist nichts anderes als sequentiell abgespeicherte binäre Daten (z.B. auf einer Harddisk).
• Die Interpretation der Daten ist Sache der Programme.
• Nur das entsprechende Programm kann die Daten in einer Datei richtig interpretieren.
• Das Lesen (und Schreiben) von Daten von einer Harddisk dauert im Vergleich zum Lesen der
Daten aus dem Arbeitsspeicher ca. 1 Million Mal länger!
• Es existieren verschiedenste Dateien auf einem Computer:
• Textdateien
• Programmdateien (Binärdateien)
• Bilder
• Sounds
• Anwendungsspezifische Dateien (Word, Excel, FrameMaker)
• Wie findet Benützer/Computer die Daten wieder?
• Dateien werden über ihren Namen angesprochen.
• Der Name einer Datei kann vom Benützer beliebig gewählt und geändert werden.
• Das Betriebssystem übersetzt den Dateinamen in die entsprechende Zylindernummer,
Sektornummer und Lesekopfnummer auf der HD.
• Eine Datei enthält neben den eigentlichen Daten weitere Informationen:
• Länge der Datei
• Zugriffsrechte: Lesen, Schreiben, Ausführen
• Weitere Attribute: Archive, Hidden, Directory
• Besitzer der Datei
• Information zur Interpretation der Daten. Diese ist bei Windows NT in der File-Extension
enthalten.
• File-Name-Extension (Dateinamen-Erweiterung):
• bezeichnet die Zeichenfolge nach dem letzten Punkt (".") im Dateinamen.
• Sie gibt dem Benutzer und dem Betriebssystem einen Hinweis auf das Programm, mit dem die
Datei erstellt worden ist oder gelesen werden kann:
• .doc
Word-Datei
• .exe
Ausführbare Datei (maschinenlesbar)
• .gif
Bitmap-Datei (Bilder)
• .wav
Sound-Datei (Sound = Geräusch, Laut, Ton, Klang)
• .java
Java-Programme (Java-Quellcode)
PPG.1.7.fm
7
• Dateisystem (Filesystem)
• Dateien werden in einem sogenannten Dateisystem (Filesystem) verwaltet
• Das Dateisystem verwaltet die Dateien in einer baumartige Anordnung:
Figur 3: Dateisystem
• Directory oder Folder (Dateiverzeichnis oder Ordner)
• Mehrere Dateien können in einem Directory zusammengefasst werden.
• Das Directory selbst ist ebenfalls eine Datei:
– Es enthält die Information, wo sich die Files dieses Directories auf der HD befinden.
– Directories können neben normalen Files auch selbst wieder Directories enthalten.
Diese heissen Subdirectories (Unterverzeichnisse)
PPG.1.7.fm
8
• Laufwerk (engl. drive)
– Bezeichnet ein Wurzelverzeichnis auf einem Speichermedium (HD, CDROM, Floppy)
– wird bei Windows mit einem Buchstaben bezeichnet A:\, B:\, ..., Z:\
• Wie spezifiziert man ein File eindeutig:
– entweder durch die Angabe des Filenamens und des absoluten Pfades
– Laufwerk:\dir1\subdir1\subdir2\...\filename
– Bsp.: D:\MeineDaten\Finanzen\Steuern.xls
– oder durch die Angabe des relativen Pfades
– Der relative Pfad bezieht sich auf das aktuelle Verzeichnis (Arbeitsverzeichnis)
– .
bezeichnet das aktuelle Verzeichnis
.. bezeichnet das nächst übergeordnete Verzeichnis (Parent direcotry)
– Beispiel:
Das aktuelle Directory sei: D:\MeineDaten\Finanzen
Mit folgenden Angaben werden die Dateien „Steuern.xls“, Brief1.doc“ und
„Adressen.xls“ angesprochen:
Steuern.xls
.\Steuern.xls
..\Briefe\Brief1.doc
..\Adressen.xls
• Directories auf anderen Rechnern
– Um Directories auf anderen Rechnern anzusprechen, muss zusätzlich zum lokalen Pfad
auf der betreffenden Maschine der Maschinenname selbst angegeben werden.
– Unter Windows existiert dazu eine universelle Namenskonvention (universal naming
convention (UNC)). Dabei wird eine beliebige Datei eindeutig spezifiziert durch die
Angabe des Computer gefolgt vom lokalen Pfad auf diesem Computer:
\\servername\freigabename\dir1\subdir1\...\filename
– Bsp.:
Die Datei „java.doc“ auf dem Computer „mustang“ im lokalen Verzeichnis
„users\staff\hutter\public“ kann folgendermassen referenziert werden:
\\mustang\users\staff\hutter\public\java.doc
– Directories auf anderen Rechnern können auch als logisches Laufwerk angebunden und
dann angesprochen werden:
– Bsp.: Das Laufwerk M: auf den Praktikums-Rechnern entspricht dem Directory
\\mustang\username auf dem Server „mustang“.
• Navigieren im Dateibaum mit der Maus:
– Doppelklicken auf ein Directory-Symbol öffnet entsprechendes Verzeichnis
– Mit Windows-Explorer (rechte Maustaste auf MyComputer-Icon drücken)
– Auf der linken Seite wird der Verzeichnisbaum dargestellt.
– Auf der rechten Seite der Inhalt des ausgewählten Directories.
– Erzeugen und löschen von Directories
– Im Directory, in dem ein neues Verzeichnis erzeugt werden soll, rechte Maustaste
drücken.
– Es erscheint eine Auswahl
– Menupunkt "Neu – Ordner" auswählen
– Datei verschieben File in neues Directory ziehen:
Linke Maustaste über File-Icon drücken, auf Zielordner hin ziehen, loslassen
PPG.1.7.fm
9
– Datei kopieren:
– gleich wie bei Datei verschieben, aber mit rechter Maustaste
– dann "Hierher kopieren" auswählen.
• Navigieren von der Kommandozeile aus:
– Command Prompt (bzw. Eingabeaufforderung) unter StartMenu anwählen.
– Beachten Sie: Gross-/Kleinschreibung wird unter Windows nicht unterschieden
– Die zwei wichtigsten Kommandi der Kommandozeile:
– cd (change directory):
cd pfad wechselt aktuelles Directory zu Pfad pfad
(absolut oder relativer Pfad)
Bsp:
cd d:\MeineDaten
cd ..\Briefe
– dir (directory):
dir pfad\directoryname
Inhalt eines Directory anzeigen
dir pfad\directoryname\filename File anzeigen
Beispiele:
dir d:\MeineDaten
dir ..\Briefe\Brief1.doc
1.7
Geschichte des Computers
17. Jh.
Erste mechanische Rechenmaschinen mit den 4 Grundrechenarten (Wilhelm Schickard,
Blaise Pascal, G. W. Leibnitz)
1805
J.-M. Jacquard erfindet programmierbaren Webstuhl (gelochte Holzplättchen)
1822
Charles Babbage entwirft Analytical Machine: Programmierbarer Allzweckrechner,
Programm auf Lochkarten, Trennung von Speicher (store) und Rechenwerk (mill). Rechnet
im Dezimalsystem. Bereits bedingte Sprünge vorgesehen. Wurde nie gebaut. Nur eine
Komponente, die Differenzmaschine, wurde realisiert.
1938
Konrad Zuse (Bauingenieur), Z1: 1. funktionierender programmgesteuerter Rechenautomat.
4 Grundrechenoperationen + Wurzel. Verwendet Dualzahlen. Gleitkommadarstellung. Programm auf 35mm-Film gelocht. Voll mechanisch.
1941
Z3. wie Z1 aber mit elektormechanischen Relais.
1946
J.P. Eckert, J.W. Mauchly: ENIAC(Electronic Numerical Integrator and Computer):
1. voll elektronischer Rechner (18000 Röhren).
John Von Neumann schlägt vor: Programm im Arbeitsspeicher abzulegen.
1949
EDSAC: (Electronic Delay Storage Automatic Computer) erster universeller Digitalrechner
mit gespeichertem Programm. Verwendete Ultraschall-Verzögerungsleitungen als Speicher.
Seit 1950 :
Industrielle Rechnerproduktion
• Man unterscheidet normalerweise 5 Computer-Generationen:
• bis Ende 50er:
Elektronenröhren, Speicher wenige 100 Maschinenwörter, Programmierung in Maschinencode
PPG.1.7.fm
10
• bis Ende 60er:
Transistoren als Schaltelemente, Ferritkernspeicher (1k), Magnetbänder. Erste Compiler.
Programme als Lochkartenstapel.
• seit Mitte 60er:
Teilweise integrierte Schaltkreise. Time-Sharing, Ein-/Ausgabe über eine Art Schreibmaschine
(Teletypewriter), später Bildschirme mit Tastatur
• seit Anfang 70er: Mikroprozessoren, 8 Bit, PC
• seit Anfang 80er: Mehrprozessorsysteme, 16-32-64-Bit-Architekturen, PC-Netzwerke
• 90er-Jahre:
Portable Computer und PDAs (Personal Digital Assistant), globale Vernetzung durch Internet
• Parallel zur Entwicklung der Computer wurden unzählige Programmiersprachen entwickelt. Diese
lassen sich ebenfalls in Generationen einteilen. Die unten stehende Figur 4 gibt einen kleinen
Überblick über die wichtigsten Programmiersprachen.
Generation
1950
1955
0
1
2
3
Assembler
Fortran
Algol 58
1960
1965
Cobol
BASIC
Algol 60
Fortran
66
LISP
PL/1
Algol 68
1970
C
1975
1980
PASCAL
PROLOG
Fortran
77
Modula
Ada
Modula-2
ML
Smalltalk
1985
1990
1995
Fortan
90
Ada
95
SML
TCL
C++
Perl
C#
2000
Figur 4: Übersicht über die wichtigsten Programmiersprachen
PPG.1.7.fm
Java
11
2
Einführung in Java
2.1
Ziele
•
•
•
•
Sie kennen die Begriffe Objekt, Methode und Klasse.
Sie können selbständig ein einfaches Java-Programm erstellen.
Sie kennen den Unterschied zwischen einem Applet und einer Applikation.
Sie kennen die verschiedenen Tools, die zum Erzeugen eines Java-Progamms nötig sind.
2.2
2.2.1
Objektorientierte Programmierung: Einführung
Motivation
• Hauptproblem der Softwareentwicklung
• Mit zunehmender Computerleistung konnten immer komplexere Programme entwickelt werden.
• Z.B. hat ein heutiges Textverarbeitungsprogramm ca. 400 000 Programmzeilen. Es stecken
zudem Hunderte von Personenjahren Arbeit in solchen Programmen.
• Dadurch entstehen folgende Probleme:
• Wie bekommt und behält man den Überblick bei solch komplexen Programmen.
• Wie testet man ein solches Programm.
• Wie wartet man das Programm (Fehlerbehebung, Erweiterung).
• Wie kann bestehende Software wiederverwendet werden.
• Höhere Programmiersprachen:
• Im Verlaufe der Entwicklung sind neben den maschinennahen Sprachen sogenannte höhere
Programmiersprachen entstanden, die versuchen, die oben genannten Probleme in den Griff zu
bekommen.
• Diese stellen Konzepte zur Verfügung, um Progamme zu strukturieren:
• Strukturierung des Ablaufs:
Das gesamte Programm wird in eine Hierarchie von Unterprogrammen aufgeteilt. Die
Unterprogramme lösen ein genau definiertes Teilproblem. Sie können somit an verschiedenen
Orten wiederverwendet werden.
• Strukturierung der Daten
Komplexe Datenstrukturen werden aus einfacheren Datenstrukturen aufgebaut. Die
komplexen Datenstrukturen können sodann als Ganzes verarbeitet werden.
• Vorteile:
• Reduktion der Komplexität
• Einfacher zu testen
• Einfacher zu warten
• Besser wiederzuverwenden
2.2.2
OO-Pogrammierung und Prozedurale Programmierung
Bei der Programmierung mit höheren Programmiersprachen werden heute hauptsächlich zwei Ansätze
verfolgt: Die prozedurale und die objektorientierte Programmierung.
• Prozedurale Programmierung
• Die Daten werden an einem zentralen Ort gespeichert. Sie sind strukturiert.
• Die gesamte Verarbeitung der Daten wird in verschiedene Schritte aufgeteilt.
• Die einzelnen Schritte werden an separate Einheiten (Prozeduren) delegiert.
• Ein Hauptprogramm steuert den ganzen Ablauf.
PPG.1.7.fm
12
• Objektorientierte Programmierung (OOP)
• Die Daten und die Verarbeitung derselben werden an separate Einheiten (Objekte) delegiert.
• Das gewünschte Verhalten des Programms entsteht durch das Zusammenspiel dieser Objekte.
• Der Unterschied dieser zwei Ansätze soll am Beispiel eines einfachen Textverarbeitungsprogramms
veranschaulicht werden:
• Prozeduraler Ansatz für ein Textverarbeitungsprogramm:
• Daten (zentral verwaltet)
Dokument
=
Menge von Seiten;
Seite
=
Kopfzeile;
Menge von Paragraphen;
Fusszeile;
Paragraph
=
Menge von Zeilen;
Zeile
=
Menge von Woertern;
Wort
=
Menge von Zeichen;
• Programm (strukturiert in Unterprogramme)
Hauptprogramm:
Dokument oeffnen;
while (nicht fertig) do
Dokument bearbeiten;
end;
Dokument schliessen.
Unterprogramme:
Dokument bearbeiten:
while (nicht fertig){
Seite auswaehlen;
Seite bearbeiten;
};
Seite bearbeiten:
while (nicht fertig) do
Je nach Wunsch do
KopfZeile bearbeiten; oder
FussZeile bearbeiten; oder
Paragraph bearbeiten;
end;
end;
Parapraph bearbeiten: ...
Kopfzeile bearbeiten: ...
...
– Das Hauptprogramm und alle Prozeduren greifen direkt auf die zentralen Daten
Dokument, Seite, Paragraph etc. zu.
– Der Programmablauf wird vom Hauptprogramm aus gesteuert.
PPG.1.7.fm
13
• Objektorientierter Ansatz:
– Objekte
Wort:
Daten:
Menge von Buchstaben;
Operationen: erzeugen;
loeschen;
bearbeiten;
darstellen;
Zeile:
Daten:
Menge von Woertern;
Operationen: erzeugen;
loeschen;
bearbeiten;
darstellen;
Paragraph:
Daten:
Menge von Zeilen;
Operationen: erzeugen;
loeschen;
bearbeiten;
darstellen;
Seite:
Daten:
Kopfzeile;
Menge von Paragraphen;
Fusszeile;
Operationen: erzeugen;
loeschen;
bearbeiten;
darstellen;
Dokument:
Daten:
Menge von Seiten;
Operationen: erzeugen;
loeschen;
bearbeiten;
darstellen;
– Programm
Hauptprogramm:
Dokument.erzeugen;
Dokument.bearbeiten;
– Die Gesamtheit der Daten ist auf einzelne Objekte verteilt. Jedes Objekt verwaltet seine
Daten selbständig. Es stellt Methoden zur Verfügung, um die Daten zu manipulieren.
Andere Objekte haben keinen direkten Zugriff auf die Objektdaten, sondern nur via die
Methoden des Objekts
PPG.1.7.fm
14
2.2.3
Wichtige Begriffe der OOP
• Objekt
• Wir kennen Objekte aus der realen Welt: Bsp. Auto, Hammer, Bank, Kunde.
• Diese haben verschiedene Eigenschaften,
z.B. hat ein Auto unter anderem die Eigenschaften:
– Farbe
– Anzahl Türen
– Anzahl Gänge
– Anzahl Sitzplätze
• Objekte haben auch einen Zustand, der sich mit der Zeit ändern kann.
Bsp. Auto:
– Geschwindigkeit
– Tankinhalt
– aktueller Gang
– Postition Steuerrad
– Postition Gaspedal
• Schliesslich haben Objekte auch ein Verhalten.
Bsp. Auto:
– es fährt, beschleunigt, bremst, etc.
• Objekte in der objektorientierten Programmierung sind ganz analog zu realen Objekten
aufgebaut.
• Objekte in der Objektorientierten Programmierung bestehen aus
• Daten (auch Attribute genannt, engl. attributes, oder Eigenschaften, engl. properties)
Diese speichern die Eigenschaften und den Zustand des Objekts
Bsp. Simuliertes Auto:
– Farbe, Geschwindigkeit, Tankinhalt, Postition auf Bildschirm
• Methoden (auch Operationen genannt, engl. operations)
– mit ihnen können die Daten abgefragt und verändert werden.
– Sie bestimmen das Verhalten des Objekts
– Bsp. Simuliertes Auto:
– Beschleunigen
– Bremsen
– Tanken
– links, rechts
• Jedes Objekt hat zudem eine eindeutige Identität (z.B. Nummer). Damit können zwei
verschiedene Objekte voneinander unterschieden werden, auch wenn alle ihre Attribute
gleich sind.
PPG.1.7.fm
15
• Beispiel: Auto-Objekte
Objekt 1:
Rotes Auto
links
beschleunigen
rechts
Farbe:
Position:
Geschw.:
Tankinhalt:
tanken
bremsen
Objekt 2:
Blaues Auto
links
beschleunigen
Farbe:
Position:
Geschw.:
Tankinhalt:
bremsen
rechts
tanken
Figur 5: Objekte der Klasse Auto
• Sofwareobjekte können reale Objekte aber auch abstrakte Konzepte modellieren.
• Beispiele für mögliche Objekte in verschiedenen Programmen:
– Textverarbeitungssystem: Wörter, Zeilen, Paragraphen, Seiten
– Flugreservationssystem: Flüge, Sitze, Destinationen, Zeiten
– Schachspiel: Schachbrett, Schachfiguren, Spiel, Zug
PPG.1.7.fm
16
• OO-Programm
– besteht aus einer Anzahl Objekten, die sinnvoll zusammenarbeiten.
– Mit diesen Objekten simuliert das Programm eine reale Problemstellung möglichst
realitätsnah.
– Bsp.: Simulation eines Autorennens
– Jedes Auto ist ein eigenes Objekt mit bestimmten Eigenschaften und einem Zustand
(Farbe, Position, Geschwindigkeit, Tankinhalt).
– Der Zustand jedes Objekts kann durch seine Methoden verändert werden (beschleunigen, bremsen, tanken)
• Klasse
• Objekte werden je nach Bedarf im Verlaufe des Programmablaufs erzeugt.
• Um ein Objekt erzeugen zu können, brauchen wir eine Beschreibung davon.
• Eine Klasse ist eine Vorlage oder ein Bauplan für Objekte.
• Beispiel Auto:
links
beschleunigen
Farbe:
Position:
Geschw.:
Tankinhalt:
bremsen
rechts
tanken
Figur 6: Klasse Auto
• Eine Klasse ist für ein Objekt, was der Bauplan für ein Haus oder die Konstruktionszeichnung
für ein Auto ist. Sie beschreibt, wie das Objekt aufgebaut werden soll. Sie selber ist aber noch
nicht das Objekt.
• Eine Klasse beschreibt insbesondere:
– Die Daten (Variablennamen und Datentyp) der Objekte.
– Die Methoden, die Objekte dieser Klasse besitzen. Damit bestimmt die Klasse das
Verhalten der Objekte.
• Der einzige formale Unterschied zwischen einer Klasse und seinem Objekt ist, dass bei der
Klasse die Werte der Variablen noch nicht festgelegt sind, sondern nur die Namen und der
Typ.
• Jede Klasse hat einen eigenen Namen (z.B. Klasse "Auto"), der eindeutig sein muss.
PPG.1.7.fm
17
• Aus einer Klasse können bliebig viele Objekte mit identischem Verhalten erzeugt werden
• Bevor ein Objekt verwendet werden kann, muss es anhand der Klasse erzeugt werden. Man
sagt auch: „Es wird ein Objekt der Klasse instanziert“.
• Ein Objekt wird deshalb auch als Instanz einer Klasse bezeichnet.
• Jedes erzeugte Objekt hat ebenfalls einen eigenen eindeutigen Namen (z.B. "meinAuto")
• Objekte der gleichen Klasse unterscheiden sich nur in den Daten, nicht aber in den Methoden,
d.h. in ihrem Verhalten.
• OO-Programmierung besteht im Wesentlichen aus dem Schreiben von Klassen, aus denen
dann zur Laufzeit die benötigten Objekte erzeugt werden.
• Vererbung (inheritance)
• Beim Schreiben einer Klasse kann man bereits bestehende Klassen wiederverwenden.
• Alle Daten und Methoden der bestehenden Klasse werden an die neue Klasse vererbt
– Superklasse oder Oberklasse:
Klasse, von der geerbt wird
– Subklasse oder Unterklasse:
Klasse, die erbt
• Subklasse kann
– zusätzliche Daten oder Methoden definieren
– geerbte Daten oder Methoden überschreiben
• Beispiel Fahrzeuge:
Superklasse
Fahrzeug
farbe
position
geschwindigkeit
beschleunigen
bremsen
links
rechts
Klassenname
Attribute
Methoden
Subklasse
MotorFahrzeug
ElektroFahrzeug
tankinhalt
batterieLadung
tanken
rueckwaerts
laden
entladen
Personenwagen
anzTueren
Fahrrad
anzGaenge
schalten
beschleunigen
Lastwagen
ladegewicht
laden
entladen
Figur 7: Klassendiagramm mit Vererbungshierarchie
PPG.1.7.fm
18
• Die Klassen MotorFahrzeug, ElektroFahrzeug und Fahrrad erben alle Daten
und Methoden von der Superklasse Fahrzeug.
• Sie definieren zusätzliche Daten und Methoden, z.B. tankinhalt und rueckwaerts
• Subklassen können auch geerbte Methoden überschreiben, wie z.B. die Methode
beschleunigen in der Subklasse Fahrrad.
2.3
Was ist eine Programmiersprache
• Programmiersprache
• ist eine Sprache, um Programme zu schreiben.
• Wir können damit dem Computer sagen, was er tun soll.
• Was muss eine Programmiersprache festlegen:
• Syntax: Grammatikregeln
– Was sind gültige Buchstaben, Wörter, Sätze
– "Ich sehen Frau mit das blauen Fahrrad" ist kein gültiger deutscher Satz.
• Semantik: Was bedeuten die Wörter und Sätze.
– "Gelbe Ideen schlafen fürchterlich" macht im normalen Sprachgebrauch keinen Sinn.
• Anforderungen an eine Programmiersprache:
• mächtig:
Alles ausdrückbar, was ich dem Computer beibringen will.
• verständlich :
Der Programmierer und Prozessor müssen die Sprache verstehen.
• eindeutig:
Ein bestimmter Satz darf nicht mehrere Bedeutungen haben.
• kompakt:
möglichst wenige Befehle
• Was soll als Programmiersprache verwendet werden?
• Maschinensprache:
• war früher die einzige Programmiermöglichkeit
• ist eindeutig
• Es kann damit alles beschrieben werden, was der Prozessor kann.
• Prozessor versteht sie direkt
• ist schwierig verständlich für Menschen
• Menschliche Sprache
• Alles ausdrückbar
• Menschen verstehen sie gut.
• Es braucht eine automatische Übersetzung in die Maschinensprache des Prozessors.
• Problem:
Die natürliche Sprache ist häufig nicht eindeutig (ein Satz kann verschiedene Bedeutungen
haben)
– Bsp. "Schliessen Sie die Datei mit der Maus".
Heisst das „Eine Datei mit dem Bild einer Maus“ schliessen, oder ein bestimmte Datei per
Mausklick schliessen?
• Kompromiss:
• Wir definieren eine eigene künstliche Sprache Programmiersprache
• Programmiersprachen
• sind künstliche Sprachen, um mit dem Computer zu kommunizieren.
• Eine Programmiersprache ist definiert durch:
• Satz von Symbolen (Buchstaben, Zahlen, Zeichen):Welche Zeichen sind erlaubt?
• Syntax (Grammatikregeln):
Wie ist eine Anweisung aufgebaut?
• Semantik (Bedeutung):
Was bedeutet jede Anweisung?
PPG.1.7.fm
19
• Eine Programmiersprache muss automatisch in die Maschinensprache des Prozessors übersetzt
(compiliert) werden können.
• Es gibt Tausende von Programmiersprachen. Figur 4 auf Seite 11 gibt einen kleinen Überblick
über die wichtigsten von ihnen.
• Java
• ist eine sehr moderne Programmiersprache mit allen Eigenschaften einer höheren Programmiersprache.
• ist von der Syntax her ähnlich wie C.
• ist rein objektorientiert.
2.4
Übersicht über Java
• Entstehung
• Java wurde von einem Team um James Gosling von Sun Microsystems in den Jahren 1990–1995
entwickelt.
• Die Sprache war ursprünglich für Heimgeräte gedacht (Video, Telephon, Ofen).
• Die Anforderungen an die Sprache waren entsprechend:
• klein
• zuverlässig
• plattformunabhängig
• Der ursprüngliche Name "Oak", war schon rechtlich geschützt.
• Bei einem Kaffee an der Ecke entschlossen sich die Entwickler für den Namen "Java", das heisst
im US-Slang soviel wie "heisser Kaffee".
• Mit dem rasanten Aufschwung des WWW und des Internet wurde die Nachfrage nach einer
Sprache, die plattformunabhängig und sicher ist, immer lauter. Java schien für diesen Zweck
ideal geeignet.
• Java erlebte deshalb eine rasante Verbreitung, wie sie noch keine andere Sprache erlebt hatte.
• Sie wird heute lange nicht mehr nur für Internetanwendungen, sondern immer mehr auch für
andere Anwendungen eingesetzt.
• Java wird zur Zeit immer noch weiterentwickelt.
• Die Eigenschaften von Java können in folgenden Stichworten zusammengefasst werden:
• klein aber mächtig:
• Es existieren nur die nötigsten Konstrukte.
• Java ist deshalb leicht erlernbar.
• Java ist ähnlich zu C und C++, wobei einige für den Programmierer gefährliche Konstrukte
weggelassen wurden.
• Die Möglichkeiten von Java entsprechen weitgehend denen von C++.
• plattformunabhängig, da interpretiert
• Problem: jeder Prozessor hat seine eigene Maschinensprache.
• Ein Programm muss für jeden Prozessor wieder neu in die entsprechende Maschinensprache
übersetzt (compiliert) werden.
• Java simuliert einen Prozessor mit einem kleinen Program, der sogenannten "Java Virtual
Machine" (JVM)
• Die JVM ist ein Prozess, der einen normalen Prozessor mit einer genau spezifizierten
Maschinensprache simuliert.
• Machinensprache des JVM ist der sogenannte "Bytecode".
– Java-Programme werden in diesen Bytecode übersetzt.
PPG.1.7.fm
20
– Der Bytecode kann beliebig zwischen Computern ausgetauscht werden.
– Er ist direkt auf jeder JVM auf irgendeinem anderen Computer lauffähig.
– Die JVM interpretiert die Befehle im Bytecode und setzt sie dynamisch in die
Machinenbefehle des entsprechenden Prozessors um, der sie dann ausführt.
• Die JVM ist für alle wichtigen Prozessoren erhältlich.
• Mit diesem Konzept wurde versucht, das Motto "Write once, run anywhere" (Schreib ein
Programm einmal und lass es dann überall laufen) in die Tat umzusetzen:
Maschinenbefehle
für PC
PC
Mac
Sun
Bytecode
JVM
(PC)
PC
JVM
(Mac)
JVM
(Sun)
Mac
Sun
Figur 8: Java-Virtual-Machine
• robust
• Java führt ähnlich wie Pascal eine strenge Überprüfung der Datentypen durch. (sog. strong
typing)
• Java erlaubte ursprünglich nicht, dass ein Programm, das aus dem Internet geladen und
ausgeführt wurde, direkt auf den Arbeitsspeicher des Prozessors zugreifen konnte. Stattdessen
lief es in einer Art Sandkasten (sandbox), den das Programm nicht verlassen konnte. In der
neusten Version wurde diese sehr restriktive Sicherheitspolitik durch eine flexiblere Strategie
ersetzt. Mit der neuen Strategie kann nun eine JVM für jedes Programm, je nach seiner
Herkunft, die Berechtigung für den Zugriff auf den Arbeitsspeicher und andere kritische
Ressourcen festlegen.
• Der heruntergeladene Bytecode wird vor der Ausführung nochmals auf Fehler geprüft.
• objektorientiert
• Java ist im Gegensatz zu C++ eine rein objektorientierte Sprache. In Java gibt es nur Klassen
und Objekte.
• langsam?
• Java lief am Anfang seiner Enwicklung etwa um den Faktor 10 langsamer als das gleiche
PPG.1.7.fm
21
Programm in C++, wenn der Bytecode direkt interpretiert wurde.
• Heutige JVM verfügen über einen Just-In-Time-Compiler (JIT). Dieser übersetzt den
Bytecode einer Klasse vor der erster Ausführung in Maschinencode. Bei jeder weiteren
Verwendung der Klasse laufen die Methoden dann direkt im Maschinencode, d.h. gleich
schnell, wie wenn sie compiliert worden wären. Der Performancevorteil von C++ liegt
deshalb heute noch etwa im Bereich von 30%.
2.5
2.5.1
Ein erstes Java-Programm
Anwendungen und Applets
• Mit Java kann man sowohl Applikationen als auch Applets programmieren:
• Applikationen
• sind eigenständige Programme
• brauchen keine anderen Programme, um laufen zu können
• können mit irgendeiner Programmiersprache programmiert werden, auch mit Java
• können direkt durch Doppelclick oder Kommandoaufruf gestartet werden.
• Applets
• sind nicht eigenständig sondern Bestandteil einer Web-Seite
• laufen innerhalb von einem Web-Browser oder Applet-Viewer
• Applets werden bei Bedarf geladen und laufen gelassen.
• Ein Applet kann irgendwo auf dem Internet als class-Datei gespeichert sein.
• Applets sind bis jetzt nur mit Java programmierbar.
• Die Unterschiede in der Programmierung zu Applikationen sind klein.
• Wir werden vor allem Applets programmieren. Später werden wir sehen, wie man aus einem
Applet eine Applikation machen kann und umgekehrt.
2.5.2
Das erste Applet
• Der Text in Figur 9 stellt bereits ein vollständiges Applet-Programm dar. Dieser Text steht in einer
Datei mit dem Namen Greeting.java
import java.awt.*;
import java.applet.Applet;
public class Greeting extends Applet {
public void paint (Graphics g) {
g.drawString ("Hello",50,50);
}
}
• .
Figur 9: Applet Greeting.java
• Erklärungen zu den einzelnen Programmzeilen:
• public void paint(Graphics g)
• Diese Zeile definiert eine Methode (d.h. ein Teilprogramm) mit dem Namen paint in der
Klasse Greeting.
• Diese Methode wird (vom Browser) aufgerufen, um das Applet zu zeichnen.
• Die eigentlicheN Zeichnungs-Befehle stehen in der Methode und zwar innerhalb der
PPG.1.7.fm
22
geschweiften Klammern{... } (engl. curly brackets).
• Beachten Sie: ausführbare Anweisungen stehen in Java immer innerhalb einer Methode.
• In diesem Beispiel steht zwischen den geschweiften Klammern nur der eine Befehl (auch
Anweisung genannt): g.drawString("Hello",50,50);
• Beachten Sie: Eine Anweisung endet mit einem Strichpunkt „;“ (Semicolon)
• drawString(...);
• heisst soviel wie „Zeichne Zeichenkette“
• Die Zeichenkette wird mit Anführungs- und Schlusszeichen "..." gekennzeichnet (double
quotes)
• Dies ist der wichtigste Befehl in diesem Programm.
• Er gibt die Anweisung, die Zeichenkette "Hello" auf den Bildschirm zu schreiben.
• Die Zahlen dahinter geben den Ort (x und y Koordinate in Pixel ) an, wo der Text
hingeschrieben werden soll.
• import java.awt.*;
import java.applet.Applet;
• Mit diesen Anweisungen werden die benötigten Bibliotheksklassen (Programmkomponenten)
importiert.
– AWT (Abstract Window Toolkit) Grafikklassen
– Applet Applet-Klasse
• public class Greeting extends Applet {...}
• Das ganze Programm ist eine Klasse mit Namen Greeting.
• Die Klasse Greeting ist von der Klasse Applet abgeleitet. D.h., sie erbt alle Daten und
Methoden der Klasse Applet.
• Innerhalb der geschweiften Klammern steht die eigentliche Definition der Klasse
Greeting, d.h., das eigentliche Programm.
• Lernaufgabe: Programm Feriengrüsse
Schreiben Sie ein Programm Feriengruesse. Es soll den Text "Grüsse aus den Ferien" an der
Stelle (100,120) auf den Bildschirm schreiben.
PPG.1.7.fm
23
2.5.3
Entwicklung eines lauffähigen Applet-Programms
• Das Applet-Programm von Figur 9 auf Seite 22 kann nicht direkt laufen gelassen werden. Es muss
vorher in ein Format übersetzt werden, das der Prozessor oder in unserem Fall die JVM versteht.
• Die einzelnen Verarbeitungsschritte vom Quelltext eines Java-Applets bis zum lauffähigen Applet
sind in folgender Übersicht dargestellt:
Editor
Greeting.java
Compiler
Greeting.html
Greeting.class
JVM
javac Greeting.java
Weitere
Klassen
appletviewer Greeting.html
Browser (Applet Viewer)
JVM Java Virtual Machine
Figur 10: Entwicklung eines Java-Programms
2.5.3.1 Erstellung des Quelltextes
• Quelltext (engl. source text, source file oder source program)
• enthält das vom Programmierer geschriebene Programm, d.h. die Anweisungen in Java.
• Ist eine Textdatei: Man kann sie von der Kommandozeile aus mit type oder more darstellen.
• Beispiel eines Java-Quelltextes: Programm Greeting von Figur 9.
• Beachten Sie:
Der Filename des Quelltextes muss gleich sein wie der Programmname (Name nach public
class), in diesem Fall also Greeting.java.
• Editor
• Wozu:
• Für das interaktive Erstellen und Ändern von Quelltexten.
• Welche Fähigkeiten braucht ein Editor unbedingt:
• Erstellen und ändern von (Text-)Files:
– Neue Textdatei erstellen
PPG.1.7.fm
24
– Existierende Datei laden (inkl. Navigieren im Dateisystem)
– Text einfügen, löschen, verändern, verschieben
• Datei drucken
• Datei abspeichern
• Zusätzlich wünschbar sind:
• Text suchen, ersetzen
• Mehrere Dateien gleichzeitig bearbeitbar
• Formatierungshilfen
• Beispiel eines Editors: PFE-Editor (Programmers File-Editor)
• Warum nicht Word?
• Word erzeugt normalerweise kein Textfile (haufenweise Formatierungsbefehle im Text).
• 99% der Funktionen braucht es nicht für das Programmieren.
2.5.3.2 Das Compilieren
• Compiler
• Ist ein Programm, das normalerweise eine höhere Programmiersprache (Quellsprache) in die
Maschinensprache eines Prozessors (Zielsprache) übersetzt.
• Es braucht für jede Sprache und jeden Prozessor einen separaten Compiler.
• Compilerbau ist eine Wissenschaft für sich (Teilgebiet der Informatik).
• Die Übersetzung geschieht von einer höheren in eine tiefere (maschinennähere)
Programmiersprache.
• Die Umkehrung ist normalerweise nicht mehr möglich, da beim Compilieren Information
verloren geht.
• Beim Compilieren ändert die Sprache, die Bedeutung des Programms sollte jedoch gleich
bleiben.
• Der Java-Compiler übersetzt Java-Befehle in die Maschinensprache der JVM, d.h. in Bytecode.
Quelllprogramm
(source code)
Greeting.java
Compiler
(Übersetzer)
Zielprogramm
Greeting.class
Figur 11: Compiler
• 1. Schritt: Der Compiler kontrolliert die Korrektheit (Syntax) des Java-Quelltextes.
• Das Java-Programm ist eine Folge von Zeichen (Textdatei).
• Der Compiler liest ein Zeichen nach dem andern ein.
• Dann versucht er anhand der Syntaxregeln, die gelesenen Zeichen zu Wörtern, die Wörter zu
Ausdrücken und die Ausdrücke zu Anweisungen zusammen zu setzen.
PPG.1.7.fm
25
• Falls eine Syntaxregel verletzt wird, erzeugt der Compiler eine Fehlermeldung.
• Der Quelltext muss peinlich genau stimmen. Solange beim Compilieren noch Fehler
auftreten, wird kein Bytecode erzeugt.
• Bei einem Fehler zeigt der Compiler die ungefähre Position (Zeilennummer) des Fehlers an.
• Der Compiler findet alle syntaktischen Fehler. Fehler in der Bedeutung des Programms findet
er jedoch in der Regel nicht.
• 2. Schritt: Der Compiler interpretiert die Java-Anweisungen
• Er übersetzt die Java-Anweisungen in die Zielsprache hier Bytecode.
• Der Compiler erzeugt dabei Files mit Extension ".class".
• Diese enthalten den Byte-Code für das entsprechende Java-Programm: Z.B.
Greeting.class enthält den Bytecode des compilierten Programms Greeting.java
• Aufruf des Compilers:
javac Programmname.java
• Beispiel:
Um das Programm Greeting.java in Bytecode zu übersetzen, muss man folgenden Befehl
auf der Kommandozeile eingeben:
javac Greeting.java
• Häufige Fehler im Quelltext (Diese werden vom Compiler meistens entdeckt):
• Strichpunkt fehlt oder ist am falschen Ort.
• Klammern fehlen oder sind falsch gesetzt.
• Einfache (') anstatt doppelte (") Anführungszeichen.
• O statt 0.
• Geduld! Ein Programm compiliert praktisch nie beim ersten Mal fehlerlos.
• Behandeln Sie immer nur den ersten Compiler-Fehler und finden Sie ihn. Die weiteren Fehler sind
häufig Folgefehler des ersten und verschwinden oft, wenn der erste Fehler korrigiert ist.
2.5.3.3 Lader (Linker)
• Vorgefertigte Programm-Komponenten (compilierte Klassen) werden in sogenannten
Klassenbibliotheken gespeichert.
• Die meisten Programme benötigen einige dieser Komponenten, z.B., um etwas auf den Bildschirm
zu schreiben.
• Nachdem ein Programm compiliert ist, muss es mit diesen zusätzlichen Komponenten
zusammengehängt (ge-linkt, Linker) werden.
• Der Compiler überprüft dabei, ob die notwendigen Komponenten existieren.
• Aufgaben des Linker-Laders
• Notwendige Komponenten, die das Programm braucht, zusammensuchen.
• Komponenten in den Arbeitsspeicher laden.
• Referenzen zwischen den einzelnen Komponenten verbinden. Diese Referenzen können nicht
vorher festgelegt werden, da der endgültige Ort des Programms im Arbeitsspeicher erst beim
Laden festgelegt wird.
• Programmzeiger des Prozessors an den Anfang des Programms setzen.
• In Java:
• Der Klassenlader lädt die benötigten Klassen erst während der Lauftzeit des Programms
PPG.1.7.fm
26
(sogenannt spätes Binden).
• Er lädt nicht alle benötigten Klassen auf einmal, sondern jede Klasse erst, wenn sie das erste Mal
benötigt wird.
• Klassen können vom lokalen Computer oder von irgendwo im Internet geladen werden.
• Um zu verhindern, dass eine vom Internet geladene Klasse Schaden am Computer anrichtet,
werden die Klassen beim Laden geprüft und die Berechtigungen festgelegt.
2.5.3.4 Browser und Applet-Viewer
• Um ein Applet laufen zu lassen, braucht es eine Web-Seite, die das Applet enthält. Beim Laden der
Web-Seite in einen Browser wird dann das Applet automatisch gestartet.
• Beispiel einer HTML-Seite Greeting.html, die das Applet Greeting.class enthält:
<title> Web-Seite mit einem Applet </title>
<applet code = Greeting.class
width = 300 height = 200> </applet>
• Browser:
• zeigt die Web-Seite mit dem enthaltenen Applet an.
• Übliche Browser: Netscape, Internet Explorer. Diese müssen Java-fähig sein, um Applets
darstellen zu können.
• Das Applet läuft dabei in einer geschützten Umgebung (Sandbox) mit eingeschränkten
Berechtigungen.
• Alternative zu den üblichen Browsern: Applet-Viewer
• Das ist ein Programm des jdk (java development kit), um Applets auszutesten.
• Aufruf:
appletviewer Greeting.html
2.6
Programmierfallen
• Beim Editieren sollten Sie das Programm regelmässig abspeichern. Falls der Computer abstürzt, ist
alles, was Sie nicht abgespeichert haben, verloren.
• Tippen Sie den Text peinlich genau ein samt Anführungszeichen, Strichpunkten, etc.
• Der Filename des Programms muss genau gleich sein wie der Klassenname (Gross- und
Kleinschreibung beachten).
• Lassen Sie sich nicht frustrieren von Fehlermeldungen des Compilers.
2.7
Integrierte Entwicklungsumgebungen
• Es gibt spezielle Softwarepakete, um Programme (z.B. in Java) zu entwickeln. Sie umfassen im
allgemeinen
• Editor, Compiler, Linker, Applet Viewer, Debugger, Graphischen Layouter
• Es gibt verschiedene käufliche Produkte:
• Visual Cafe, PowerJ, JBuilder, Visual Age, Visual J++, JCreator
• Wir werden mit JCreator arbeiten.
PPG.1.7.fm
27
3
Einfache Grafiken
3.1
Ziele
•
•
•
•
Sie können die Begriffe Methode und Argument erläutern.
Sie können die wichtigsten Methoden, um einfache Grafiken zu zeichnen, richtig anwenden.
Sie können mit diesen Methoden selbständig einfache Grafiken erstellen.
Sie können die Begriffe "Anweisung" und "Befehlssequenz" erklären.
3.2
Anweisung
• Um dem Computer zu sagen, was er der Reihe nach machen soll, müssen wir ihm eine Folge von
Befehlen in der gewählten Programmiersprache geben.
• Damit wir diese Befehle nicht jedesmal wieder von Hand eingeben müssen, schreiben wir sie in eine
Datei, das sogenannte Programm.
• Einen einzelnen Befehl in einer Programmiersprache nennt man eine Anweisung (engl. statement)
• In Java: Jede Anweisung in Java muss mit einem ";" enden.
• Beispiel
g.drawString("Hello",10,20);
• Diese Java-Anweisung schreibt "Hello" an der Stelle (10,20) in das Appletfenster auf dem
Bildschirm:
• Für den Font und die Grösse werden die Standardwerte verwendet.
• Man kann auch mehrere Strings zusammenhängen (concatenate) mit dem Zeichen "+"
• Beispiel:
g.drawString("Hallo " + "zusammen", 20, 20);
"Hallo zusammen"
• Diese Anweisung besteht aus einem einzigen Methodenaufruf der Methode drawString.
• Es gibt noch etliche andere Arten von Anweisungen, wie wir später noch sehen werden.
• Eine Anweisung kann auch leer sein: ; // Dies ist eine Leeranweisung
3.3
Die Befehlssequenz
• Eine Folge von Anweisungen, die nacheinander abgearbeitet werden, bezeichnet man als
Befehlssequenz.
• Diese Anweisungen werden in Java wie in jeder normalen Programmiersprache der Reihe nach von
links nach rechts und oben nach unten abgearbeitet.
• Beispiel: Programm HelloYouThere
import java.awt.*;
import java.applet.Applet;
public class Viereck extends Applet {
public void paint(Graphics g){
g.drawString("Hello", 10, 20);
g.drawString("you", 10, 40); ;
g.drawString("there", 10, 60);
}
}
Programm 1 : HelloYourThere
PPG.1.7.fm
28
• Das Programm HelloYouThere erzeugt auf dem Bildschrirm der Reihe nach folgende Zeilen:
Hello
you
there
• Zwischen der zweiten und der dritten Zeile wird die Leeranweisung ausgeführt.
3.4
Methodenaufruf
• Eine Methode ist ein Teilprogramm, das eine bestimmte Aufgabe erfüllt.
• Jede Methode hat einen Namen.
• Bsp.: g.drawString(...)
• ist eine Methode mit dem Namen drawString, die einen Text an der gewünschten
Stelle auf den Bildschirm zeichnet.
• Sie gehört zum Graphics-Objekt g.
• g ist das Grafikobjekt, das die Zeichenumgebung des Applets verwaltet.
• Das Graphikobjekt g stellt verschiedene Methoden zur Verfügung, mit denen wir zeichnen
können.
• g wird von der Java-Umgebung an die paint-Methode übergeben.
• Alle Zeichnungsanweisungen, die mit "g." beginnen, zeichnen in das Grafikobjekt g, d.h.
in das Appletfenster.
• Um eine Methode ausführen zu lassen, muss man nur ihren Namen als eine Anweisung schreiben.
• In der objektorientierten Programmierung gehört eine Methode immer zu einem Objekt (oder zu
einer Klasse). In unserem Beispiel ist es das Graphics-Objekt g.
• Deshalb muss bei jedem Methodenaufruf das entsprechende Objekt angegeben werden.
• In unserem Beispiel ist es das Objekt g, deshalb der Aufruf: g.drawString(...)
• Die Methode eines Objekts greift in der Regel auf die internen Daten des Objekts zu.
• Wie eine Methode intern realisiert ist, braucht man für die Verwendung der Methode nicht zu
wissen. Das einzige, was wir wissen müssen, ist, wie die Methode heisst und welche Informationen
wir der Methode beim Aufruf übergeben müssen.
• Beim Aufruf einer Methode können ihr Informationen mitgegeben werden in der sogenannten
Argumentliste.
• Argumentliste
• ist eine Liste von Angaben, die einer Methode beim Aufruf mitgegeben werden.
• Die Argumentliste steht jeweils in runden Klammern nach dem Methodennamen.
• Die einzelnen Argumente sind durch Kommas getrennt.
• Jede Methode legt fest:
• in welcher Reihenfolge die Argumente übergeben werden müssen.
• von welchem Datentyp die Argumente sein müssen.
• wie die Angaben interpretiert werden.
• Bsp.:
g.drawString("Hello",20,50);
• 1. Argument:
• 2. Argument:
• 3. Argument:
PPG.1.7.fm
Text, der geschrieben wird:
Hello (Datentyp String)
X-Koordinate der linken unteren Ecke des Textes 20 (Datentyp int)
Y-Koordinate der linken unter Ecke des Textes 50 (Datentyp int)
29
• Methodenaufruf:
• Der Aufruf einer Methode eines Objekts besteht im allgemeinen aus dem Objektnamen, dem
Methodennamen und einer Argumentliste und sieht folgendermassen aus:
Objektname.Methodenname( Argumentliste );
Die Argumentliste ist dabei eine Folge von Argumenten (Werten), die durch Kommas
voneinander getrennt sind.
• Falls die Methode, die aufgerufen wird, im gleichen Objekt ist, wie der Aufruf, wird das Objekt
mit this bezeichnet oder kann (samt dem nachfolgenden Punkt) auch weggelassen werden.
• Falls keine Argumente übergeben werden, so müssen trotzdem die runden Klammern
geschrieben werden.
• Beispiele von gültigen Methodenaufrufen:
haus.zeichneFenster(5);
rechteck.zeichne();
zeichneDich(10,20);
this.zeichneDich(10,20);
p.penUP();
3.5
•
•
•
•
•
•
Der grafische Bildschirm
Java-Grafiken sind pixel-basiert.
Ein Pixel ist ein Punkt (Quadrätchen) auf dem Bildschirm mit einer bestimmten Farbe.
Bildschirme haben verschiedene Auflösungen, z.B. 600 x 800 Pixel, 768 x 1024 Pixel, oder mehr
Der Nullpunkt (0,0) ist bei Java-Grafiken oben links.
Die x-Achse verläuft von links nach rechts, die y-Achse von oben nach unten.
Jedes Pixel durch seine x- und y-Koordinate bestimmt.
3.6
Ein erstes Bild
• Beispiel 1: Programm FirstLine:
import java.awt.*;
import java.applet.Applet;
public class FirstLine extends Applet {
public void paint(Graphics g) {
g.drawLine(0,0,100,100);
}
}
Programm 2 : FirstLine.java
• drawLine(xst, yst, xend, yend);
• ist eine weitere Methode des GraphikObjekts g
• zeichnet eine Linie zwischen zwei gegebenen Punkten.
PPG.1.7.fm
30
• Argumente der Methode (Reihenfolge beachten!):
– xst
x-Koordinate des Startpunktes, ganze Zahl (int)
– yst
y-Koordinate des Startpunktes
– xend
x-Koordinate des Endpunktes
– yend
y-Koordinate des Endpunktes
• Das dazugehörige HTML-File sieht folgendermassen aus:
<title> Firstline.class </title>
<applet code=FirstLine.class
width=300 height=200> </applet>
• width : gibt die Breite des Applets in Pixel an
• height : gibt die Höhe des Applets in Pixel an
• Resultat des Programm FirstLine im Appletviewer:
Figur 12: Bildschirmausgabe von Programm FirstLine
• Beispiel 2: Zeichnen eines gleichschenkligen Dreiecks
(100,60)
(20,100)
PPG.1.7.fm
31
• Übungsaufgabe:
Programmieren Sie ein gleichschenkliges Trapez auf der gleichen Basis wie das Dreieck, aber mit
halber Höhe.
3.7
Die Methode paint
• Damit die Zeichnungsbefehle wirklich ausgeführt werden, müssen sie in der Methode
public void paint(Graphics g){ Zeichungsbefehle };
stehen.
• Die Methode paint(Graphics g); ist bereits in der Klasse Applet vordefiniert zusammen
mit verschiedenen anderen Methoden.
• Die vordefinierte paint-Methode in der Klasse Applet zeichnet aber selber nichts.
• Ein Appletprogammierer muss eine eigene paint-Methode in seinem Appletprogramm
schreiben, wo er die gewünschten Zeichnungsbefehle auflistet.
• Damit wird die ursprüngliche paint-Methode überschrieben.
• Achtung:
Damit die paint-Methode wirklich überschrieben wird, muss der Methodenkopf der neuen
paint-Methode genau gleich aussehen:
public void paint(Graphics g){...}
• Die so überschriebene paint-Methode wird vom Browser automatisch aufgerufen immer dann,
wenn das Applet neu gezeichnet werden muss.
• Die überschriebene paint-Methode muss alle Befehle für das Zeichnen der gewünschten Grafik
enthalten.
• Insbesondere dürfen keine Anweisungen ausserhalb der Methode stehen!
• Der paint-Methode wird vom Browser ein Objekt der Klasse Graphics übergeben:
• Der lokale Name dieses Objekts innerhalb der paint-Methode ist im obigen Beispiel g
• Sie können auch einen anderen lokalen Namen für dieses Objekt wählen.
• Das Graphics-Objekt g enthält die Grafikumgebung des Applets.
• Das Graphics-Klasse stellt die verschiedenen Methoden zum Zeichnen zur Verfügung: z.B.
g.drawLine(...);
PPG.1.7.fm
32
3.8
Weitere Methoden zum Zeichnen
• Hier eine Liste von weiteren Zeichnungsmethoden, die das Graphics-Objekt zur Verfügung
stellt:
• drawRect(xSt,ySt,breite,hoehe) / fillRect(xSt,ySt,breite,hoehe)
• drawOval(xSt,ySt,breite,hoehe) / fillOval(xSt,ySt,breite,hoehe)
• drawArc(xSt,ySt,breite,hoehe,stWinkel,winkel)/
fillArc(xSt,ySt,breite,hoehe,stWinkel,winkel)
• drawRoundRect(xSt,ySt,breite,hoehe,eckBreite,eckHoehe) /
fillRoundRect(xSt,ySt,breite,hoehe,eckBreite,eckHoehe)
PPG.1.7.fm
33
3.9
Farben
• Falls Sie beim Zeichnen nichts Spezielles angeben, werden die Standardwerte für die Strichdicke,
Farbe etc. verwendet, die im Graphics-Objekt gespeichert sind:
• Vordergrundfarbe (Foreground): schwarz
• Hintergrundfarbe (Background): weiss
• Die Vordergrundfarbe kann verändert werden mit der Anweisung:
g.setColor(Color.farbe);
• Nach Aufruf von setColor() werden alle Zeichnungsbefehle in der neuen Farbe farbe
ausgeführt.
• Es sind 13 Standard-Farben in der Color-Klasse vordefiniert:
• black, blue, cyan (türkis), darkGray, gray, green, lightGray,
magenta, orange, pink, red, white, yellow
• Beispiel: Mit folgender Anweisung wird die Vordergrundfarbe auf Rot gesetzt:
g.setColor(Color.red);
// Die Vordergrundfarbe ist ab dieser Anweisung Rot.
• Die Hintergrundfarbe kann man folgendermassen setzen:
setBackground(Color.farbe);
• Achtung:
Dies ist keine Methode des GraphikObjekts, sondern des Applets selbst.
Deshalb muss diese Methode ohne das Graphics-Objekt g aufgerufen werden.
3.10
Gefüllte Formen
• Gefüllte Formen erhält man, wenn man bei den Zeichenmethoden fill anstatt draw schreibt:
• fillRect, fillOval, fillArc
• Die Argumente sind dieselben wie bei den draw-Methoden.
PPG.1.7.fm
34
• Beispiel: Schweizerkreuz
Pseudocode:
20.00
90.00
20.00
(0,0)
Figur 13: Schweizerkreuz
Folgende Befehlssequenz erzeugt das dargestellte Schweizerkreuz:
3.11
Kommentare
• //
• /* ..... */
•
•
•
•
Bezeichnet einen einzeiligen Kommentar. Er geht bis zum Ende der Zeile.
Bezeichnet einen mehrzeiligen Kommentar. Kommentare können nicht
verschachtelt werden.
Kommentare können beliebigen Text enthalten.
Kommentare werden von Compiler ignoriert (überlesen). In JCreator werden Kommentare in grün
dargestellt.
Achtung: Keine Befehle irrtümlich auskommentieren!
Wann sollen Kommentare gesetzt werden:
• Wenn aus den Anweisungen nicht sofort und eindeutig hervorgeht, was passiert.
PPG.1.7.fm
35
4
Variablen und Berechnungen
4.1
Ziele
• Sie kennen das Binär- und Hexadezimalsystem und können einfache Umrechnungen eigenhändig
durchführen.
• Sie kennen den ASCII-Code zur Codierung von Zeichen.
• Sie können die zwei grundlegenden Zahlen-Datentypen in Java, int und float, richtig einsetzen.
• Sie können die Begriffe "Variable", "Zuweisung" und "Ausdruck" anhand von Beispielen erklären.
• Sie können mit int- und float-Variablen richtig umgehen:
• Initialisierung
• Berechnungen durchführen
• Typenkonversion
• Sie können Syntaxregeln in EBNF richtig interpretieren.
4.2
Einführung
• In Programmen wird häufig mit Werten gerechnet. Z.B.
• Bildschirmkoordinaten
• Salär, Zins
• Physikalische Grössen
• Aus der Mathematik kennen Sie zwei grundlegende Zahlenmengen
• Ganze Zahlen:
• ..., –3, –2, –1, 0, 1, 2, 3,...:
• undendlich viele, aber abzählbar
• Reelle Zahlen:
• Bsp.: 1.4345, Pi, 3.0, –1000.34, 1/3
• unendlich viele
• nicht abzählbar
• Dieses Kapitel behandelt, wie ganze und reelle Zahlen sowie Zeichen auf dem Computer dargestellt
werden, und welche Konsequenzen sich daraus ergeben.
4.3
4.3.1
Interne Darstellung von Daten im Computer
Das Binärsystem
• Als Erstes stellt sich die Frage: Wie rechnet der Prozessor intern mit Zahlen?
• Wie rechnen wir?
• Im Zehnersystem (Dezimalsystem)
• Ungünstig für Computer, da eine Ziffer 10 verschiedene Werte annehmen kann.
Dies ist schwierig in Hardware zu realisieren
• Zweiersystem (Binärsystem)
• Im Gegensatz zum Dezimalsystem hat das Binärsystem nur zwei Werte pro Ziffer.
• Diese sind einfach in Harware darstellbar (ein/aus, links/rechts, Strom/kein Strom, Spannung/
keine Spannung)
• Im Arbeitsspeicher werden die zwei Werte in Form einer Kondensatorladung gespeichert:
Kondensator geladen = 1, ungeladen = 0
• Vorteil: Die grundlegenden Rechenoperationen können einfach direkt in HW realisiert werden
PPG.1.7.fm
36
• In der Tabelle 1 sind die Unterschiede zwischen Binär- und Dezimalsystem zusammengefasst.
Dezimalsystem (Zehnersystem)
Binärsystem (Zweiersystem)
Alphabet:
{0,1,2,3,4,5,6,7,8,9}
Alphabet:
{0,1}
Basis:
10
Basis:
2
Symbole:
Ziffern
Symbole: Binärziffern = Bits (Binary Digits)
159710 = 1000 + 500 + 90 + 7
11012 = 1• 23 + 1• 22 + 0• 21 + 1• 20
= 8 + 4 + 0 + 1
= 1310
= 1• 103 + 5• 102 + 9• 101 + 7• 100
Anz. Stellen:
1
2
3
...
6
...
9
...
12
Anz. mögliche Werte:
10
100 = 102
1000 = 103 = 1k
1‘000‘000
= 106 = 1M (Mega)
109 = 1G (Giga)
1012 = 1T (Tera)
Anz. Stellen
1
2
3
4
...
8
...
10
...
16
...
20
Anz. mögliche Werte
2
4 = 22
8 = 23
16 = 24
256 (entspr. 1 Byte)
1024 ( = 1 KBit)
65536
1'048'576 (= 1MBit)
Tabelle 1: Vergleich Dezimal- mit Binärsystem
• Grundrechenoperationen werden im Binärsystem analog zum Vorgehen im Zehnersystem
durchgeführt
• Bsp. Addition
Dezimalsystem
+
Binärsystem
165
1227
1392
+
1101
101
10010
= 13
= 5
= 18
• Die Addition z = x + y kann im Binärsystem leicht in HW realisiert werden:
• Die Wertetabelle für die Summe und den Übertrag sieht folgendermassen aus:
PPG.1.7.fm
x
y
0
0
0
1
1
0
1
1
Summe
z
Übertrag
ü
37
• Die entsprechende HW-Schaltung kann aus zwei logischen Gattern aufgebaut werden:
Figur 14: Digitalschaltung für die Binäraddition.
• Umwandlung Dezimal ↔ Binär-System
• Die Umwandlung vom Binär- ins Dezimalsystem ist einfach. Man braucht nur jede Stelle mit
ihrer Wertigkeit zu multiplizieren und dann alles zusammenzuzählen:
11012 = 1• 23 + 1• 22 + 0• 21 + 1• 20 = 8 + 4 + 0 + 1 = 1310
Für die Berechnung ist das sogenannte Hornerschema viel effizienter:
11012 = ((1 •2 + 1) •2 + 0) •2 + 1 = ... = 1310
(sogenannte vollständig geklammerte Form des Ausdrucks)
• Die Umwandlung vom Dezimalsystem ins Binärsystem ist etwas komplizierter:
Man dividiert die Dezimalzahl fortlaufend durch 2 (ganzzahlige Division), bis das Resultat 0
ergibt. Dabei schreibt man bei jeder Division den Rest auf. Schreibt man nun die Restwerte
von rechts nach links nebeneinander, so erhält man die gewünschte Binärzahl.
• Beispiel: Zahl 12310
12310
Rest
/2
/2
/2
/2
/2
/2
/2
PPG.1.7.fm
38
4.3.2
Das Hexadezimalsystem
• Binärzahlen sind für den Menschen ziemlich unübersichtlich zu lesen.
• Deshalb fasst man üblicherweise 4-Binärstellen zu einer neuen Zahl zusammen und weist dieser
Gruppe ein eigenes Symbol zu Hexadezimalziffer
• Alphabet : {0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F}
• Basis: 16
• Vergleich Dezimal-, Binär- und Hexadezimalzahlen
Dezimal
Binär
Hexadezimal
0
0000
0
1
0001
1
2
0010
2
3
0011
3
4
0100
4
5
0101
5
6
0110
6
7
0111
7
8
1000
8
9
1001
9
10
1010
A
11
1011
B
12
1100
C
13
1101
D
14
1110
E
15
1111
F
Tabelle 2: Hexadezimalsystem
• Übergang von Hexadezimalzahl Binärzahl
Jede Hexademizalstelle durch 4 Binärziffern ersetzen gemäss Tabelle2:
3A416 = 0011 1010 0100 = 11101001002
• Übergang von Binärzahl Hexadezimalzahl
• Binärzahl von rechts nach links in 4er-Gruppen einteilen.
• Vorderste Gruppe eventuell links mit Nullen auf 4 Stellen ergänzen
• Jede Gruppe gemäss Tabelle 2 in die entsprechende Hexadezimalzahl umwandeln
• Beispiel
1101110012 = 0001 1011 1001 = 1B916
• Übergang von Hexadezimalzahl
2
Dezimalzahl
1D516 = 1 • 16 + 13 • 16 + 5 • 160 = (1 •16 + 13) •16 + 5 = 29 •16 + 5 = 46910
PPG.1.7.fm
1
39
• Übergang Dezimalzahl Hexadezimalzahl
• Gleiches Vorgehen wie bei Übergang von Binärzahl zu Dezimalzahl, nur muss jetzt jeweils mit
16 dividiert werden statt mit 2.
• Einfacher: Dezimalzahl Binärzahl Hexadezimalzahl
• Hexadezimalzahlen werden in der Informatik häufig mit einem „0x“ als Präfix gekennzeichnet, um
sie von Dezimalzahlen zu unterscheiden:
So bezeichnet 0x14 die Hexadezimalzahl 14 oder 0x01f die Hexadezimalzahl 01F.
4.3.3
Darstellung von Zeichen
• Zeichen werden auf dem Computer ebenfalls als Binärzahl dargestellt.
• Der Prozessor kann nicht unterscheiden, ob die Binärzahl in einer Speicherzelle einer Zahl oder
einem Zeichen entspricht.
• Die richtige Interpretation der Binärzahl ist allein Sache der Software!
• Es gibt verschiedene Möglichkeiten, wie man ein Zeichen als Binärzahl codieren kann. Als
allgemein anerkannter Standard wird heute aber praktisch überall der ASCII-Code für die
Darstellung von Zeichen verwendet oder zumindest unterstützt:
• ASCII-Code
• ASCII: American Standard Code for Information Interchange
• ASCII-Code-Tabelle
High
0000
0
0001
1
0010
2
0011
3
0100
4
0101
5
0110
6
0111
7
0000
0
NUL
DLE
SP
0
@
P
`
p
0001
1
SOH
DC1
!
1
A
Q
a
q
0010
2
STX
DC2
"
2
B
R
b
r
0011
3
ETX
DC3
#
3
C
S
c
s
0100
4
EOT
DC4
$
4
D
T
d
t
0101
5
ENQ
NAK
%
5
E
U
e
u
0110
6
ACK
SYN
&
6
F
V
f
v
0111
7
BEL
ETB
'
7
G
W
g
w
1000
8
BS
CAN
(
8
H
X
h
x
1001
9
HAT
EM
)
9
I
Y
i
y
1010
A
LF
SUB
*
:
J
Z
j
z
1011
B
VT
ESC
+
;
K
[
k
{
1100
C
FF
FS
,
<
L
\
l
|
1101
D
CR
GS
-
=
M
]
m
}
1110
E
SO
RS
.
N
^
n
~
1111
F
SI
US
/
O
_
o
DEL
Low
?
Tabelle 3: ASCII-Code: Das Zeichen 'A' hat z.B. den ASCII-Code 4116 = 01000001
PPG.1.7.fm
40
• Beim ASCII-Code wird jedes Zeichen in einem Byte (8 Bit) codiert. Für die 128 ASCII-Zeichen
braucht es aber nur 7 der 8 Bits. Deshalb ist die höchstwertige Binärziffer immer 0.
• Die verbleibenden 128 Zeichencodes werden für Spezialzeichen verwendet, z.B.
sprachspezifische Zeichen oder Symbole.
Beispiel: Zeichensatzerweiterung Latin-1 (ISO 8859-1)
High
Low
1000
8
1001
9
1010
A
1011
B
1100
C
1101
D
1110
E
1111
F
°
À
Ð
à
ð
0000
0
_
_
0001
1
_
_
¡
±
Á
Ñ
á
ñ
0010
2
_
_
¢
²
Â
Ò
â
ò
0011
3
_
_
£
³
Ã
Ó
ã
ó
0100
4
_
_
¤
´
Ä
Ô
ä
ô
0101
5
_
_
¥
µ
Å
Ö
å
õ
0110
6
_
_
¦
¶
Æ
Ö
æ
ö
0111
7
_
_
§
·
Ç
×
ç
÷
1000
8
_
_
¨
¸
È
Ø
è
ø
1001
9
_
_
©
¹
É
Ù
é
ù
1010
A
_
_
ª
º
Ê
Ú
ê
ú
1011
B
_
_
«
»
Ë
Û
ë
û
1100
C
_
_
¬
¼
Ì
Ü
ì
ü
1101
D
_
_
-
½
Í
Ý
í
ý
1110
E
_
_
®
¾
Î
Þ
î
þ
1111
F
_
_
¯
¿
Ï
ß
ï
ÿ
Tabelle 4: ASCII-Zeichensatzerweiterung Latin-1 (ISO 8859-1)
• Unicode
• Aufgrund des Bedarfs an immer mehr Zeichen für die verschiedenen Sprachen, wurde ein neuer
Codierungs-Standard eingeführt, der sogenannte Unicode.
• Beim Unicode wird ein Zeichen mit 16 statt nur mit 8 Bit codiert.
• Damit können insgesamt über 65000 verschiedene Zeichen codiert werden. Alle heute
unterstützten Sprachen belegen bisher knapp 40000 der Codes.
• Die ASCII-Zeichencodes wurden in den Unicode übernommen. So haben alle druckbaren
ASCII-Zeichen (Codes 0x20-0x7E und 0xA0-0xFF in Tabelle 3 und 4) den gleichen Code
auch im Unicode .
• Moderne Betriebssysteme und Programmiersprachen unterstützen bereits den Unicode.
PPG.1.7.fm
41
4.4
Datentypen für ganze und reelle Zahlen
• Grundsätzliches Problem:
Das grundsätzliche Problem bei der Darstellung von Zahlen auf dem Computer besteht darin, dass
sowohl ganze als auch reelle Zahlen unendlich viele Werte annehmen können. Wir haben aber nur
eine endliche Zahl von Bits in einer Speicherzelle im Computer, um diese darzustellen.
• Für die zwei grundlegenden Zahlenmengen in der Mathematik gibt es verschiedene sogenannte
Datentypen (Darstellungsarten) auf dem Computer. Die zwei wichtigsten sind int und float:
Mathematik:
Zahlenmenge
Computer:
Datentyp
ganze Zahlen
int
reelle Zahlen
float
• Da auf dem Computer nur endlich viele Werte dargestellt werden können, müssen bei der
Darstellung der Zahlen Kompromisse eingegangen werden:
•
für int: beschränkter Wertebereich
•
für float: beschränkter Wertebereich, beschränkte Genauigkeit
• Vergleich der Zahlenbereiche in der Mathematik und auf dem Computer:
• Ganze Zahlen:
• Mathematik
• Computer
PPG.1.7.fm
42
• Reelle Zahlen:
• Mathematik
• Computer
4.5
Zahlendarstellung in Java
• Die interne Darstellung von Zahlen im Computer ist normalerweise von Prozessor zu Prozessor
verschieden. Dies ist mit ein Grund, wieso compilierte Programme nicht portabel sind, d.h nicht
einfach auf einem anderen Computer laufen gelassen werden können.
• Bei Java ist deshalb die interne Darstellung von Zahlen von der Sprache selbst vorgegeben und
deshalb auf allen Java-Virtual-Machines gleich.
• Ganze Zahlen:
• Datentyp int
Datentyp
int
Anzahl Bits
32
Wertebereich
–231 bis 231–1
–2147483648 bis 2147483647
Integer-Berechnungen
Innerhalb des Wertebereiches
immer exakt
• Beispiele:
5
-193
0x6B (Darstellung als Hexadezimalzahl = 10710)
• Später werden wir noch weitere Datentypen für ganze Zahlen kennen lernen.
PPG.1.7.fm
43
• Reelle Zahlen:
• Datentyp float
Datentyp
float
Anzahl Bits
32
Wertebereich
–3.4·1038 bis 3.4·1038
relative Genauigkeit
6–7 Dezimalstellen
absolut kleinste Zahl
±1.4·10-45
• Beispiele:
1.34f
-234.837F
1E-3F
3f 0.75f
.001f
• Achtung: Ohne "f" am Schluss wird automatisch der Datentyp double angenommen.
• Ob int- oder float-Darstellung gebraucht wird, ist nicht immer leicht zu entscheiden
(Bsp. Schulnoten).
• Datentyp double
Datentyp
double
Anzahl Bits
64
Wertebereich
–1.79·10308 bis 1.79·10308
relative Genauigkeit
14–15 Dezimalstellen
absolut kleinste Zahl
±4.9·10-324
• Beispiele:
1.34
-10.3
1.e5
5d 0.3D
.001
• Wann soll der Datentyp float, wann double gewählt werden?
• Das hängt von der gewünschten Genauigkeit und dem Wertebereich ab.
• Bei längeren Rechnungen mit reellen Zahlen sollte der Datentyp double verwendet werden,
auch wenn die float-Genauigkeit für das Endresultat genügt. Der resultierende relative Fehler
wird nämlich mit jeder Operation grösser (vor allem bei der Subtraktion von fast gleich grossen
Zahlen!)
4.6
4.6.1
Variablen
Einführung
• In der Mathematik bezeichnet eine Variable einen Wert, der sich ändern kann.
• Beim Programmieren bezeichnet eine Variable einen bestimmten Speicherplatz im Arbeitsspeicher,
in den eine Binärzahl gespeichert werden kann. Die Binärzahl im Speicherplatz kann im Verlauf
eines Programms ebenfalls beliebig verändert werden.
PPG.1.7.fm
44
Figur 15: Arbeitsspeicher
• Variablennamen sind vom Programmierer frei wählbar (mit gewissen Einschränkungen).
• Die Syntaxregeln für Variablennamen (allg. Bezeichner) in Java sind :
• 1. Zeichen :
muss ein Buchstabe (Unicode) , "_" oder "$" sein.
• Nachfolgende Zeichen: müssen Buchstaben , Ziffern , "_" oder "$" sein.
• Namen können beliebig lange sein.
• Es dürfen aber keine reservierten Wörter als Variablennamen verwendet werden.
• Gross- und Kleinbuchstaben werden in Java unterschieden! D.h. A und a sind zwei
verschiedene Variablen (Speicherplätze).
• Gültige Variablennamen sind beispielsweise:
breite
Hoehe
LÄNGE
jahr2000
x
b$3_n
• illegal sind dagegen:
neues Haus
1Ka
• Der Compiler überprüft, ob die Syntaxregeln eingehalten werden. Falls ein Variablenname dagegen
verstösst, gibt der Compiler eine Fehlermeldung aus.
• Zusätzlich zu den Syntaxregeln haben sich bei den Programmierern verschiedene Konventionen für
die Namengebung eingebürgert. Es empfiehlt sich sehr, sich an die gebräuchlichsten Konventionen
zu halten.
4.6.2
Java-Konventionen
• Variablen und Methodennamen beginnen in Java mit einem Kleinbuchstaben.
• Klassennamen beginnen mit einem Grossbuchstaben.
• Bei Namen aus mehreren Wörtern wird der Anfangsbuchstabe jedes neuen Wortes gross
geschrieben.
• Beispiele von Namen, die den Java-Konventionen entsprechen:
paint, drawString, Grafik, Applet, rateProMonat, dezemberLohn,
setzeFarbe, liesBuchstaben, endeMonat, besteNote.
PPG.1.7.fm
45
• Wichtig: Sinnvolle und präzise Namen verwenden (Länge des Namens ist unwichtig).
Bei der Programmentwicklung ist es sehr wichtig, dass für Variablen, Methoden und Klassen
Namen gewählt werden, die möglichst aussagekräftig und präzise sind.
4.6.3
Variablendeklaration
• Bsp.: Programm Berechnung
import java.awt.*;
import java.applet.Applet;
public class Berechnung extends Applet{
public void paint(Graphics g){
// Deklaration lokaler Variablen
int laenge;
// einfache Dekl.
int breite = 10;
// Dekl. mit Initialisierung
int flaeche, flaeche2 = 100; // Mehrere Dekl.
// Hier folgen die Anweisungen
laenge = 20;
// Dies ist eine Anweisung!
flaeche = laenge * breite;
// 2. Anweisung
g.drawString("Flaeche = " + flaeche, 100, 100);
}
}
Programm 3 : Berechnung
• Deklaration
• Eine Deklaration ist eine Vereinbarung des Namens und Datentyps einer Variablen.
• Der Name bezeichnet einen bestimmten Speicherplatz im Computer.
• Der Datentyp bestimmt die Interpretation des Binärwertes (int, float etc.)
• Wieso muss man Variablen deklarieren:
→ Der Compiler kann Fehler besser entdecken (Typenprüfung).
→ Die Programmierenden müssen sich bewusst machen, welche Datentypen sie verwenden.
• Deklaration lokaler Variablen:
• Werden Variablen innerhalb einer Methode deklariert, so sind sie nur in dieser Methode
sichtbar.
• Man bezeichnet diese Variablen als lokale Variablen der entsprechenden Methode.
• Wir werden später Variablen behandeln, die nicht lokal sind.
• Beispieldeklaration für int- und float-Variablen:
int laenge;
int breite;
int winkel, stWinkel;
float groesse;
float wurzelAus2 = 1.414f;
int gesamtPunktZahl = 63;
int anzahl = 2, summe = 7;
• Empfehlungen
• Alle Variablen sollten an derselben Stelle deklariert werden, am besten vor der ersten
Anweisung. Damit muss man sie nicht lange suchen.
PPG.1.7.fm
46
• Variablen gleich bei der Deklaration initialisieren guter Programmierstil.
• Machen Sie keine Annahmen über den Initialwert einer Variablen, falls Sie ihn nicht selbst
gesetzt haben.
4.6.4
Allgemeine Beschreibung von Syntaxregeln
• Problem:
Wie kann man möglichst kompakt und vollständig beschreiben, was eine gültige Variablendeklaration ist.
• Eine Möglichkeit, eine Programmiersprache exakt und kompakt zu beschreiben bietet die
sogenannte Erweiterte Backus-Naur-Form
EBNF
• ENBF (Erweiterte Backus-Naur-Form)
• Eine EBNF-Syntaxregel hat folgende allgemeine Form:
Name ::= Syntaxregel in EBNF.
• Die EBNF verwendet die Metasymbole [ ], { }, | , und ( ) um die Syntaxregeln einer
Programmiersprache zu beschreiben. Diese Metasymbole haben folgende Bedeutung
[ xxx ]
{ xxx }
xxx | yyy
( xxx yyy )
• Weitere Konventionen:
– Name
– xxx
xxx optional
xxx kann 0, 1, oder mehrmals vorkommen
xxx oder yyy kann vorkommen, aber nicht beide
runde Klammern zur Gruppierung
muss durch etwas Gültiges ersetzt werden, d.h. ist selbst
wieder durch eine EBNF-Regel definiert.
muss genau als xxx geschrieben werden
• Beispiel:
Eine gültige Deklaration einer lokalen Variablen in Java kann in EBNF-Notation wie folgt
beschrieben werden:
Variablendeklaration ::= Typ Variablenname [ = Initialwert ] { , Variablenname [ =
Initialwert ] };
• Interpretation:
– Zuerst muss ein Datentyp angegeben werden
Typ ersetzen z.B. durch int oder float
– Dann muss ein Variablennamen angegeben werden
Variablennamen z.B. durch laenge ersetzen
– Optional kann ein Initialwert angegeben werden, z.B. " = 20"
– Weitere Variablendeklarationen können angehängt werden. Diese müssen durch ein
Komma voneinander getrennt sein.
– Die Variablendeklaration muss mit einem Strichpunkt abgeschlossen werden.
• Bedeutung:
Eine solche Variablendeklaration bedeutet, dass eine oder mehrere Variablen vom Datentyp
Typ deklariert werden. Diese Variablen können dann mit dem vereinbarten Variablennamen
angesprochen werden.
PPG.1.7.fm
47
• Aufgabe:
Prüfen Sie anhand der oben angegebenen EBNF-Regel für eine Variablendeklaration, ob folgende
Deklarationen gültig sind:
länge = 10;
float breite;
float int x, z;
int (berta) = 5;
float gewicht s
4.7
Zuweisung (assignment)
• Wie wir gesehen haben, können Variablen Werte zugewiesen werden. Dies kann bereits bei der
Deklaration geschehen, indem der Variablen ein Initialwert zugewiesen wird.
• Im Verlaufe des Programms können einer Variablen beliebige andere Werte (innerhalb des
Wertebereiches) zugewiesen werden.
• Zuweisung:
• Eine Zuweisung ist eine Anweisung, die einer Variablen einen neuen Wert zuweist.
• Beispiele:
laenge = 20;
– Zahl 20 wird in den Speicherplatz mit Namen laenge gespeichert.
– Man sagt auch: Der Variablen laenge wird der Wert 20 zugewiesen.
– Der vorherige Wert der Variablen laenge wird dabei überschrieben.
float groesse = 1.f; // Deklaration der Variable groesse mit
// Initialwert
groesse = 1.7f;
// Zuweisung von 1.7 zur Variablen groesse
groesse = 12.3e+23;
// Zuweisung von 12.3*1023 zur Variablen
// groesse
• Es können nicht nur konstante Werte einer Variablen zugewiesen werden, sondern auch Resultate
aus einer ganzen Berechnung.
• Das Zuweisungszeichen " = " heisst hier "wird zu", nicht "ist gleich" im algebraischen Sinn.
• Beispiele:
flaeche = laenge * breite;
• Ablauf:
– Wert von laenge (20) wird mit Wert von breite (10) multipliziert
– Resultat (200) wird in Variable flaeche gespeichert.
int n;
// Deklaration der Variablen n
n = n + 1; // n wird um 1 erhöht
Zuweisung
n++;
//
abgekürzte Schreibweise für n = n + 1;
n--;
//
abgekürzte Schreibweise für n = n - 1;
• Allgemeine Form einer Zuweisung in Java:
• Zuweisung ::= Variable = Ausdruck;.
• Ausdruck: Bezeichnet eine einzelne Zahl, Variable oder eine ganze Berechnung.
PPG.1.7.fm
48
4.8
Ausdruck (expression)
• Ausdruck
• Ein Ausdruck ist eine einzelne Zahl oder eine ganze Berechnung, d.h. eine Folge von Operanden
und Operatoren.
• Ein Ausdruck liefert immer ein Ergebnis mit einem bestimmten Datentyp, z.B. int.
• Beispiele:
n + 1
Ausdruck liefert eine ganze Zahl (int) als Resultat
0.5 / 4.2
Ausdruck liefert einen double-Wert
• Operanden können sein:
• Konstanten (z.B. Zahlen)
• Variablen
• Funktionsaufruf (ein Aufruf liefert immer einen Funktionswert zurück)
• Operatoren: z.B. +, -, *, /, aber auch > , <
• Ausdrücke innerhalb von Anweisungen
• Ausdrücke kann man überall dort einsetzen, wo ein Wert des entsprechenden Datentyps erlaubt
ist.
• Beispiel int-Ausdruck:
int x = 4;
g.drawString("Hello", 3*x/2, 40);
g.drawString("Hello",
, 40);
1. Ausdruck (3*x/2) wird berechnet.
2. Dann wird das Resultat anstelle des Ausdrucks in die Anweisung eingesetzt.
3. Schliesslich wird die Anweisung ausgeführt.
4.9
Arithmetische Operatoren
Zeichen
Name
Präzedenz
*
Multiplikation
2
/
Division
2
%
Rest
2
+
Addition
3
-
Subtraktion
3
• Division /
• führt je nach Typ der beteiligten Variablen eine normale Division oder aber eine
Ganzzahldivision durch.
• Achtung:
Bei Ganzzahldivision wird nicht gerundet, sondern der Rest nach dem Dezimalpunkt
abgeschnitten!
PPG.1.7.fm
49
• Beispiele:
int a; float x;
a = 15 / 4;
// a = 3
x = 15f / 4f;
// x = 3.75f
a = 9 / 4;
// a = 2 !!
x = 9 / 4;
// x = 2.0f!!
• Rest %
• Der Rest-Operator gibt den Rest der Division zurück.
• Er ist auch für reelle Zahlen definiert (float, double). Dabei verhält er sich analog wie bei
ganzen Zahlen.
• Beispiele:
int a; float x;
a = 12 % 4;
// a = 0 (kein Rest)
a = 13 % 4;
// a = 1 (Rest 1)
a = 15 % 4;
// a = 3
x =
7.0f % 2.0f;// x = 1.0f
x = 8.6f % 2.0f; // x = 0.6f
x = 7.1f % 2.5f; // x = 2.1f
• Präzedenz (Vorrang)
• Sagt aus, welche Operation zuerst ausgeführt wird: Ein Operator der Präzedenz 2 wird vor den
Operatoren der Präzedenz 3 ausgeführt.
• Bei gleicher Präzedenz werden die Operatoren von links nach rechts ausgeführt.
• Beispiele:
int resultat;
resultat = 4 * 8 + 2;
// = 34
resultat = 6 + 3 * 4 - 1;
// = 17
resultat = 3 + ( 2 - 2 ) * 3;
// =
3
• Beachten Sie, wenn Sie mathematische Formeln in Java programmieren:
• Zeichen für Multiplikation
*
• Klammern
es gibt nur runde Klammern ()
• * und / haben gleiche Präzedenz
Nenner eines Bruches in Klammern setzen.
4.10
Darstellung von Variablen
• Beispiel :
g.drawString("Area is " + area, 100, 100)
Wird ein String mit dem +-Operator mit einer Variablen (hier area) verknüpft, so wird
der Wert der Variablen automatisch in einen String konvertiert.
• Typkonversion von int zu String geschieht fortlaufend (normalerweise von links nach rechts)
• g.drawString("Resultat = " + 1 + 2, 20, 20)
"Result = 12" !!
• g.drawString("Resultat = " + (1 + 2), 20, 20) "Resultat = 3"
PPG.1.7.fm
50
4.11
Typkonversion (type cast)
• Falls beim Auswerten eines arithmetischen Ausdruckes zwei Operanden einer Rechenoperation
nicht denselben Datentyp haben, so wird der eine Operand mit einer Typkonversion in den Datentyp
des anderen umgewandelt.
• Einzelne Typkonversionen werden von Java automatisch ausgeführt. Andere müssen vom
Programmierer explizit angegeben werden.
• Explizite Typkonversion:
Eine explizite Typkonversion erreicht man mit dem sogenannten Cast-Operator:
Der gewünschter Datentyp wird dabei in runden Klammern, (Typ), vor die zu konvertierende
Variable gestellt.
(int) x
x wird in int-Wert umgewandelt
(float) x
x wird in float-Wert umgewandelt
• Beispiele:
int ivalue = 33;
float fvalue = 3.9f;
int i; float x;
x = ivalue;
// x = 33.0
Umwandlung von int in float kein Problem, da kein Genauigkeitsverlust.
i = (int) fvalue; // i = 3
Für Umwandlung von float in int braucht es den Cast-Operator (int).
Nachkommastellen werden abgeschnitten, nicht gerundet!
x = (float) (10+11)/2; // x = 10.5
Cast-Operator hat Präzedenz 1 und wird deshalb zuerst ausgeführt!
• Bei einer Operation mit gemischten Operanden (int und float) wird der int-Operand
automatisch in eine float-Zahl umgewandelt.
4.12
Programmierfallen
• Achtung auf Schreibfehler (z.B. "1" und "l" oder "O" und "0")
• f hinter float-Werten nicht vergessen
• Klammern müssen immer paarweise vorhanden sein.
PPG.1.7.fm
51
5
Entscheidungen
5.1
Ziele
•
•
•
•
•
•
Sie kennen die minimal notwendigen Ablaufstrukturen.
Sie setzen Auswahlanweisungen mittels if/else-Konstrukten richtig ein.
Sie können if/else-Konstrukte sinnvoll darstellen.
Sie können mit Vergleichsoperatoren und logischen Operatoren umgehen.
Sie können logische Ausdrücke analysieren und sinnvoll einsetzen.
Sie können einfache switch-Anweisungen programmieren.
5.2
Ablaufstrukturen
• Während des Entwurfs eines Programmes und später auch zur Dokumentation des implementierten
Programms braucht der Softwareentwickler eine Möglichkeit, um den geplanten oder
implementierten Programmablauf möglichst genau und verständlich zu beschreiben.
• Die Beschreibungssprache eines Programmsablaufs sollte deshalb folgende Bedingungen erfüllen:
• einfach, d.h. möglichst wenige Konstrukte
• verständlich (auch für Nicht-Programmierer)
• präzise
• mächtig
• übersichtlich
• Für die Beschreibung sequenzieller Programmabläufe werden verschiedenste Methoden verwendet,
z.B.:
• Flussdiagramm (DIN 66001)
• Wird auch Programmablaufplan (PAP) genannt
• Graphische Darstellung des Programmablaufs
• Sehr einfach zu lesen, präzise, mächtig
• Flussdiagramme werden jedoch schnell unübersichtlich.
• Achtung: Flussdiagramme verleiten zu unstrukturiertem Programmieren!
• Struktogramm (Nassi-Schneidermann, DIN 66261)
• Graphische Darstellung des Programmablaufs
• Einfach zu lesen, präzise, mächtig
• Struktogramme sind übersichtlich darstellbar für kleinere und mittelgrosse Programme.
• Struktogramme erzwingen das strukturierte Programmieren!
• Pseudocode
• Textbasiert: Umgangssprachliche Beschreibung des Programmablaufs mit einfach zu
lesenden aber eindeutigen Sprachkonstrukten.
• Einfach zu lesen (für jemand mit minimalen Programmierkenntnissen), präzise, mächtig
• Pseudocodeprogramm bleiben auch bei grösseren Progammen übersichtlich durch die
Verwendung von Unterprogrammen.
• Pseudoprogramme fördern ebenfalls das strukturierte Programmieren!
• Pseudocode ergibt oft guten Kommentar, falls man ihn als solchen im fertigen Programm
stehen lässt.
PPG.1.7.fm
52
5.2.1
Block
• Der Block ist der Grundbaustein einer Ablaufstuktur.
• Ein Block kann beliebig viele Anweisungen (und Deklarationen) enthalten. Ein Block kann aber
auch leer sein.
• Wichtig ist aber: Jeder Block hat genau einen Eingang und genau einen Ausgang.
• Die Darstellung eines Blocks hängt von der gewählten Beschreibungsart ab:
• Pseudocode:
Block;
• Flussdiagramm und Struktogramm:
Eingang
Block
Ausgang
Figur 16: Block in einem Flussdiagramm oder Struktogramm
• Block in Java:
• Ein Block in Java ist eine Folge von Anweisungen und Deklarationen, die von geschweiften
Klammern umgeben sind.
• Ein Block kann auch leer sein: {}
• Ein Block wird in Java wie eine einzelne Anweisung behandelt. D.h. überall, wo eine Anweisung
erlaubt ist, kann auch ein Block eingefügt werden.
• EBNF-Beschreibung:
Block ::= { { Anweisung }
}
• Falls ein Block nur aus einer einzelnen Anweisung besteht, können die geschweiften Klammern
auch weggelassen werden.
5.2.2
Sequenz
• Die einfachste Ablaufstruktur ist eine Folge von Blöcken, die nacheinander ausgeführt werden.
Diese Ablaufstruktur wird Sequenz genannt.
• Darstellung einer Sequenz:
• Pseudocode:
Block1;
Block2;
Block3;
...
PPG.1.7.fm
53
• Flussdiagramm
Block1
Block2
Block3
Figur 17: Flussdiagramm einer Sequenz
• Struktogramm
Block1
Block2
Block3
Figur 18: Struktogramm einer Seqenz
5.2.3
Zusätzliche Ablaufstrukturen
• Bisher haben wir nur diese einfachste Ablaufstruktur verwendet.
• Es ist klar, dass zusätzliche Ablaufstrukturen nötig sind, um komplexere Abläufe beschreiben zu
können.
• Frage:
Wieviele verschiedene Ablaufstrukturen braucht es, um alle möglichen Programme darzustellen?
• Antwort:
nur 3!
• Die folgenden drei Ablaufstrukturen sind notwendig:
• Sequenz : Folge von Anweisungen.
• Auswahl : Anweisungen, die nur unter bestimmten Bedingungen ausgeführt werden.
• Schleife : Wiederholung von Anweisungen.
PPG.1.7.fm
54
5.3
Auswahlanweisungen
5.3.1
Einfache Auswahl
• 1. Variante:
Ein Block wird nur unter einer bestimmten Bedingung ausgeführt.
• Beschreibung in Pseudocode:
if Bedingung then
Block;
endif
• Graphische Darstellung
• Struktogramm
Bedingung?
Wahr
Block
Falsch
--
Figur 19: Struktogramm einer einfachen Auswahl
• Flussdiagramm
Bedingung
erfüllt?
Ja
Block
Nein
Figur 20: Flussdiagramm einer einfachen Auswahl
• 2. Variante:
Block A wird ausgeführt, falls eine Bedingung erfüllt ist. Falls die Bedingung nicht erfüllt ist, wird
Block B ausgeführt.
• Pseudocode
if Bedingung then
Block A;
else
Block B;
endif
PPG.1.7.fm
55
• Struktogramm
Bedingung?
Wahr
Block A
Falsch
Block B
Figur 21: Struktogramm einer allgemeinen Auswahl
• Flussdiagramm
Bedingung
erfüllt?
Nein
Ja
Block A
Block B
Figur 22: Flussdiagramm einer allgemeinen Auswahl
• Beispiel Wählerkontrolle:
• Es soll anhand des Alters einer Person bestimmt werden, ob sie stimmberechtigt ist oder nicht. Ist
die Person älter als 17 Jahre, so ist sie stimmberechtigt.
• Mit 1. Variante:
Struktogramm
In Java:
Alter abfragen
Alter > 17
Wahr
"stimmberechtigt"
PPG.1.7.fm
Falsch
--
56
• Mit 2. Variante:
Struktogramm
In Java:
Alter abfragen
Alter > 17
Wahr
Falsch
"stimmberechtigt"
"zu jung"
• Allgemein:
Auswahlanweisungen in Java haben folgende allgemeine Form (EBNF):
if ( Bedingung )
Block A
else
Block B
• Bedingung
• Die Bedingung muss ein logischer Ausdruck sein, der wahr (true)oder falsch (false) ist.
• Beispiel von oben: Alter > 17 . Dieser Ausdruck ist wahr oder falsch.
• Bedeutung:
– if-Block (Block A) wird ausgeführt, falls Bedingung wahr ist.
– else-Block (Block B) wird ausgeführt, falls Bedingung falsch ist.
• Block A, Block B
– Diese Blöcke können beliebig viele Anweisungen und andere Ablaufkonstrukte enthalten
(siehe Beschreibung eines Blocks auf Seite 53)
– Beachten Sie:
Die Anweisungen sind bei jedem if- und else-Block einzurücken Damit behält man
besser die Übersicht.
• if-Anweisung ohne else:
if ( Bedingung )
Block
• Bedeutung:
– if-Block wird nur ausgeführt, falls Bedingung wahr ist.
– else-Block fehlt: Falls die Bedingung falsch ist, wird der Block übersprungen.
PPG.1.7.fm
57
• Klammersetzung bei if-Konstrukten:
• Falls ein Block nur aus einer einzelnen Anweisung besteht, dürfte man von der Java-Syntax aus
die geschweiften Klammern auch weglassen.
• Dies ist aber hier nicht empfehlenswert, da dann Interpretationsprobleme bei verschachtelten ifKonstrukten auftreten können!
• Beispiel:
if (alter > 6 )
if (alter < 16)
g.drawString("Jugendpreis",10,10);
else
g.drawString("Erwachsenenpreis",10,10);
Frage: Zu welchem if gehört nun das else?? (Das Einrücken ist dabei nicht
massgebend!)
• Lernaufgabe: Zeichnen Sie das Struktogramm für beide Interpretationsmöglichkeiten.
Durch Klammernsetzung ist die Logik des if-Konstruktes eindeutig und klar ersichtlich:
if (alter > 6 ) {
if (alter < 16) {
g.drawString("Jugendpreis",10,10);
}
else {
g.drawString("Erwachsenenpreis",10,10);
}
}
oder noch einfacher und noch besser lesbar:
if (alter >= 16 ) g.drawString("Erwachsenenpreis",10,10);
else if (alter > 6)g.drawString("Jugendpreis",10,10);
PPG.1.7.fm
58
5.3.2
Mehrfachauswahl
• Beispiel: Wochentage
• In einem Programm werden z.B. die Wochentage durch Zahlen zwischen 1 und 7 dargestellt.
Möchte man nun für eine gegebene Zahl den entsprechenden Tag herausfinden, so braucht man 7
if-Anweisungen.
• Da solche Problemstellungen recht häufig auftreten, stellt Java eine zusätzliche Ablaufstruktur
zur Verfügung, die sogenannte Mehrfachauswahl.
• Darstellungsarten der Mehrfachsauswahl:
• Pseudocode
case Auswahl of
1 : Block A;
2 : Block B;
3 : Block C;
...
n : Block A;
else
Block Z;
end case
• Struktogramm
Auswahl = ?
1
2
3
...
Block A Block B Block C
n
sonst
Block N Block Z
• Flussdiagramm
Auswahl = ?
1
Block A
PPG.1.7.fm
2
Block B
3
Block C
n
...
Block N
sonst
Block Z
59
• Mehrfachauswahl in Java
• Die Mehrfachauswahl wird in Java durch die switch-Anweisung realisiert.
• Beispiel:
Die Bestimmung des Wochentags anhand der Zahl day kann mit folgendem switchKonstrukt realisiert werden:
int day;
switch (day) {
case 1 :
g.drawString("Montag", 50, 50);
break;
case 2 :
g.drawString("Dienstag", 50, 50);
break;
case 3 :
g.drawString("Mittwoch", 50, 50);
break;
case 4 :
g.drawString("Donnerstag", 50, 50);
break;
case 5 :
g.drawString("Freitag", 50, 50);
break;
case 6 :
g.drawString("Samstag", 50, 50);
break;
case 7 :
g.drawString("Sonntag", 50, 50);
break;
default :
g.drawString("kein Tag!", 50, 50);
break;
}
• Programmablauf
• Je nach Wert der Variable springt das Programm zum entsprechenden case-Label und fährt
dort mit der ersten Anweisung weiter.
• break:
– Bei einem break-Befehl springt das Programm ans Ende der switch-Anweisung
– Achtung:
Ohne break-Befehl am Ende eines case-Labels werden auch alle nachfolgenden
case-Labels ausgeführt!
• default:
– Dieses Label steht für alle Fälle, die noch nicht von einem case-Label abgedeckt
werden.
– Die Anweisungen des default-Labels werden nur ausgeführt, wenn keines der caseLabels ausgeführt wurde. (Diese Aussage gilt nur, falls alle case-Labels mit break
abgeschlossen sind)
PPG.1.7.fm
60
• Allgemeines switch-Konstrukt:
Das switch-Konstrukt kann in EBNF folgendermassen beschrieben werden:
switch (Zahlausdruck) {
{case Konstante1 : { Anweisung } [ break; ] }
[ default : { Anweisung } ]
}
• Zahlausdruck:
• Konstante1, 2, ... :
int-, char-Variable (keine anderen Typen erlaubt)
Muss eine ganze Zahl oder ein Character sein (z.B. 3,'a')
• Mehrere Anweisungen pro case-Label:
Einem case-Label können mehrere Anweisungen zugeordnet werden
case 4 : g.setColor(Color.red);
g.drawString("Donnerstag", 50, 50);
break;
• alle Anweisungen bis zur nächsten break-Anweisung (inkl. case-Anweisungen) werden
ausgeführt!
• Mehrfachlabels
Es können auch mehrere Labels denselben Anweisungen zugeordnet werden, z.B.:
switch (day) {
case 1: case 2: case 3: case 4: case 5:
g.drawString("Wochentag",50,50); break;
case 6: case 7:
g.drawString("Wochenende", 50, 50); break;
}
5.4
Vergleichsoperatoren
• Um Bedingungen in Auswahlanweisungen zu beschreiben, braucht man häufig sogenannte
Vergleichsoperatoren.
• Ausdrücke mit Vergleichsoperatoren liefern als Resultat einen der zwei Werte:
• true (wahr)
• false (falsch)
PPG.1.7.fm
61
• In Java existieren folgende Vergleichsoperatoren:
Zeichen
Bedeutung
Präzedenz
>
grösser als
5
<
kleiner als
5
==
gleich
6
!=
nicht gleich
6
<=
kleiner oder gleich
5
>=
glösser oder gleich
5
Tabelle 5: Vergleichsoperatoren in Java
• Achtung! Zuweisung und Vergleich gut unterscheiden:
x = y
x wird zu y (Zuweisung)
x == y
x ist gleich y (logischer Ausdruck. Resultat wahr oder falsch)
• Beispiele logischer Ausdrücke:
int a;
Ausdruck
3 > 4
4 <= 4
a >= 2
a != a
5.5
:
:
:
:
Resultat
falsch
wahr
wahr für a = 2, 3, 4, ..., falsch für a = 1, 0, –1,...
immer falsch
Logische Operatoren
• Damit der Programmierer auch mehrere logische Bedingungen miteinander verknüpfen kann,
definiert Java zusätzlich zu den logischen Variablen sogenannte logische Operatoren.
• Die wichtigsten logischen Operatoren in Java sind in Tabelle 6 zusammengestellt:
Zeichen
Bedeutung
Präzedenz
&&
UND
10
||
ODER
11
!
NICHT
1
Tabelle 6: Logische Operatoren in Java
PPG.1.7.fm
62
• Wahrheitstabelle des Und-Operators && (w: wahr, f: falsch)
p
q
p && q
w
w
w
f
w
f
w
f
f
f
f
f
p
q
p || q
w
w
w
f
w
w
w
f
w
f
f
f
• Wahrheitstabelle des Oder-Operators ||
• Wahrheitstabelle des Nicht-Operators !
p
!p
w
f
f
w
• Beispiel für logische Ausdrücke:
int a, total;
Ausdruck
Resultat
(4 > 3) && (7 < 8)
:
(0 < -1) || (2 > 2)
:
(a > 4) && (a <= 6)
:
(a
:
<= -a) && !(a > 2)
(a == 5) || (a != a)
:
if ((total == 2) || (total == 7)) {
g.drawString("gewonnen!",10,10);
}
:
PPG.1.7.fm
63
5.6
Logische Variablen
• Resultate von logischen Ausdrücke können 2 Werte annehmen:
• Java definiert einen neuen Datentyp dafür:
• Datentyp:
boolean
• Wertebereich:
{true, false}
wahr oder falsch
• Wir können somit auch logische Variablen (auch boolsche Variablen genannt) deklarieren, z.B.:
• boolean gezeichnet;
• boolean fertig = false;
• Logischen Variablen können auch Werte zugewiesen werden:
fertig = true;
• Logische Variablen können schliesslich auch in Bedingungen verwendet werden:
if (fertig){
// nicht: if (fertig == true)
g.drawString("Auf Wiedersehen",10,10);
}
PPG.1.7.fm
64
6
Wiederholungen
6.1
Ziele
• Sie unterscheiden drei Arten von Wiederholschleifen.
• Sie können die drei Arten von Wiederholschleifen grafisch darstellen.
• Sie setzen die drei Schleifenkonstrukte in Java, while, do..while und for
situationsgerecht ein.
6.2
Einführung
• Bei der Programmierung brauchen wir ein Schleifenkonstrukt, um gleiche oder ähnliche
Anweisungen wiederholen zu können.
• Im Prinzip würde ein Schleifenkonstrukt ausreichen.
• Man unterscheidet normalerweise aber drei Arten von Schleifen:
1. Schleife mit Vorabprüfung
Der Block innerhalb der Schleife wird wiederholt, solange die Bedingung gilt. Ist die Bedingung
bereits das erste Mal nicht erfüllt, wird der Block überhaupt nicht ausgeführt.
• Pseudocode:
while Bedingung erfüllt do
Block;
end while
• Flussdiagramm:
Bedingung
erfüllt?
Nein
Ja
Block
Figur 23: Flussdiagramm einer Schleife mit Vorabprüfung
PPG.1.7.fm
65
• Struktogramm
while Bedingung erfüllt
Block
Figur 24: Struktogramm einer Schleife mit Vorabprüfung
2. Schleife mit Endprüfung
Der Block innerhalb der Schleife wird einmal ausgeführt. Er wird danach solange wiederholt,
wie die Bedingung erfüllt ist. Der Block wird also in jedem Fall mindestens ein Mal ausgeführt.
• Pseudocode
do
Block;
while Bedingung erfüllt
• Flussdiagramm:
Block
Bedingung
erfüllt?
Ja
Nein
Figur 25: Flussdiagramm einer Schleife mit Endprüfung
PPG.1.7.fm
66
• Struktogramm
Block
while Bedingung erfüllt
Figur 26: Struktogramm einer Schleife mit Endprüfung
3. Fixe Anzahl Wiederholungen
Der Block innerhalb der Schleife soll eine vorbestimmte Anzahl mal ausgeführt werden (sog.
for-Schleife).
• Pseudocode:
for i = n to m do
Block;
end for
• Flussdiagramm:
Zähler
initialisieren
Zähler Endwert
erreicht?
Ja
Nein
Block
Zähler
aufdatieren
Figur 27: Flussdiagramm einer for-Schleife
PPG.1.7.fm
67
• Struktogramm
for i = n to m
Block
Figur 28: Blockdiagramm einer for-Schleife
6.3
Schleifen in Java
while–Schleife (1)
6.3.1
• Die while-Schleife ist eine Schleife mit Vorabprüfung.
• Beschreibung in EBNF:
while ( Bedingung )
Block
• Bedingung: Logischer Ausdruck, dessen Ergebnis wahr oder falsch ist
• Bedeutung: Der Block innerhalb der Schleife wird solange ausgeführt,
wie die Bedingung erfüllt ist (eventuell gar nicht).
• Block:
• Anweisungen (und ev. Deklarationen) in geschweiften Klammern.
• Kann auch Deklarationen enthalten
• Kann auch leer sein
• Beispiel 1: Zeichnen einer Reihe von Sternen
int counter = 0, x = 10;
while (counter < 8) {
g.drawString("*", x, 20);
x = x + 10;
counter++;
}
PPG.1.7.fm
68
• Ablauf:
• counter wird bei der Deklaration auf 0 gesetzt.
• Schleife wird ein erstes Mal durchlaufen, da counter < 8 ist.
• Es wird 1 Stern gezeichnet.
• Am Ende der Schleife wird counter um 1 erhöht. counter = 1
• Schleife wird noch 7 Mal wiederholt. counter wird am Ende der Schleife jeweils auf die
Werte 2, 3, 4, 5, 6, 7, 8 gesetzt.
• Beim nächsten Test der while-Bedingung ist diese falsch. Die Schleife bricht deshalb ab.
• Resultat: Es wurden 8 Sterne nebeneinander auf den Bildschirm geschrieben.
• Übungsaufgabe:
• Überlegen Sie sich, wieviele Sterne die vorherige Schleife zeichnet, falls counter < 8
ersetzt wird durch die unten stehenden Bedingungen. Notieren Sie zudem, welchen Wert
counter nach dem Verlassen der Schleife aufweist:
• counter < 8
8 Sterne
counter = 8
• counter <= 8
• counter > 8
• counter == 8
• counter != 8
• Beispiel 2: Linienmuster
• Die folgende paint-Methode zeichnet ein Linienmuster auf den Bildschirm:
public void paint (Graphics g){
int appHoehe = 200, appBreite = 300;
int zeilenAbstand = 20;
int xSt = 0, ySt = 0;
int xEnd = appBreite, yEnd = ySt;
while (ySt <= appHoehe) {
g.drawLine(xSt, ySt, xEnd, yEnd);
ySt = ySt + zeilenAbstand;
yEnd = ySt;
}
}
• Wieviele Linien werden auf den Bildschirm gezeichnet? ____________
PPG.1.7.fm
69
• Beispiel 3: Endlosschleifen
• Lernaufgabe:
Überlegen Sie sich, wie Sie eine Endlosschleife programmieren könnten.
• Beachten Sie beim Programmieren von Schleifen:
• Ist die Zählervariable bzw. die Lauf- oder Abbruchbedingung richtig initialisiert?
• Wird die Zählervariable bzw. die Lauf- oder Abbruchbedingung in der Schleife überhaupt
verändert?
• Erreicht die Zählervariable je die Abbruchbedingung (keine ungewollten Endlosschleifen)?
6.3.2
do ... while-Schleife (2)
• Die do-while-Schleife ist eine Schleife mit Endprüfung.
• Beschreibung in EBNF:
do
Block
while ( Bedingung );
• Block: Anweisungen (und ev. Deklarationen) in geschweiften Klammern.
• Bedeutung:
• Block wird ein erstes Mal ausgeführt.
• Block wird danach solange wiederholt, wie Bedingung erfüllt ist.
PPG.1.7.fm
70
• Beispiel: Würfelprogramm
public class Wuerfeln extends Applet {
public void paint(Graphics g) {
int wurf = 0, y = 20;
int versuch = 0;
do{
wurf = (int)(Math.random()*6) + 1;
versuch++;
g.drawString("Versuch " + versuch + " : " + wurf, 20, y);
y = y + 15;
} while (wurf != 6);
}
}
Programm 4 : Würfelprogramm mit do-while-Schleife
• Erklärungen:
• Würfel wird solange geworfen, bis eine 6 gewürfelt wird.
• Die Bedigung für den Abbruch der Schleife ist erst nach dem ersten Mal Würfeln bekannt.
• Math.random() gibt eine zufällige double-Zahl r, 0.0 <= r < 1.0, zurück. Die
erzeugten Zufallszahlen sind gleichverteilt. Durch die obige Anweisung ist wurf sodann
eine zufällige ganze Zahl im Bereich 1..6
• Beachten Sie:
Jede do..while-Schleife kann durch eine while- oder for–Schleife ersetzt werden, aber nicht
ohne weiteres umgekehrt.
• Beispiel: Würfelprogramm von vorher mit einer while-Schleife
Bei Verwendung einer while-Schleife muss dafür gesorgt werden, dass mindestens ein Wurf
durchgeführt wird. Dies kann man auf eine der folgenden zwei Arten bewerkstelligen:
• Man führt einen separaten Wurf explizit vor der while-Schleife durch (siehe Programmcode
Seite 72).
oder
• Man sorgt dafür, dass die Bedingung der while-Schleife das erste Mal sicher richtig (true) ist.
Im Beispielprogramm kann man dies einfach erreichen, indem der Initialwert der lokalen
Variable wurf auf einen Wert ungleich 6 gesetzt wird.
PPG.1.7.fm
71
public class Wuerfeln2 extends Applet {
public void paint(Graphics g) {
int wurf = 0, y = 20;
int versuch = 0;
wurf = (int)(Math.random()*6) + 1;
versuch++;
g.drawString("Versuch " + versuch + " : " + wurf, 20, y);
y = y + 15;
while (wurf != 6){
wurf = (int)(Math.random()*6) + 1;
versuch++;
g.drawString("Versuch " + versuch + " : " + wurf, 20, y);
y = y + 15;
}
}
}
Programm 5 : Würfelprogramm mit while-Schleife
6.3.3
for-Schleife (3)
• Die for-Schleife ist dafür gedacht, um einen Code-Block eine fixe Anzahl Mal zu wiederholen.
• In Java sieht diese for-Schleife folgendermassen aus (EBNF):
for ( [ Initialisierung ] ; [ Bedingung ] ; [ Aufdatierung ] )
Block
• Block: Anweisungen (und ev. Deklarationen) in geschweiften Klammern.
• Initialisierung:
• Wird ein Mal vor dem 1. Durchlauf durch die Schleife ausgeführt.
• Die Initialisierung kann sowohl Zuweisungen als auch Deklarationen enthalten. Die hier
deklarierten Variablen gelten nur innerhalb der for-Schleife.
• Hier wird normalerweise die Laufvariable (Zähler) initialisiert.
• Die Laufvariable kann auch gleich hier deklariert werden. Sie ist dann aber nur innerhalb der
Schleife sichtbar.
• Bedingung:
• Die Bedingung muss ein logischer Ausdruck sein. Er liefert als Resultat wahr oder falsch.
• Die Bedingung wird vor jedem Schleifendurchlauf getestet.
• Falls die Bedingung wahr ist, wird der Block innerhalb der Schleife wiederholt, sonst wird
Schleife verlassen.
PPG.1.7.fm
72
• Nach dem Verlassen der Schleife läuft das Programm weiter bei der 1. Anweisung nach der
for-Schleife.
• Die Bedingung wird normalerweise verwendet, um den Wert der Laufvariablen zu testen.
• Aufdatierung:
• Die Aufdatierung kann Zuweisungen enthalten aber keine Deklarationen.
• Sie wird am Ende jedes Schleifendurchlaufs ausgeführt.
• Sie wird normalerweise dazu verwendet, um Laufvariable aufzudatieren (z.B. um 1 erhöhen)
• Bedeutung:
Der Code-Block innerhalb der for-Schleife (Block) wird eine fixe Anzahl mal wiederholt. Die
Zahl der Wiederholungen ist durch die Initialisierung, die Aufdatierung und die
Abbruchbedingung gegeben.
• Beispiel 1:
int zaehler;
for (zaehler = 0; zaehler < 10; zaehler++) {
g.drawString("*", zaehler*20, 20);
}
• zaehler-Variable durchläuft folgende Werte: 0, 1, ..., 9. Bei zaehler = 10
bricht die for-Schleife ab.
•
Die for-Schleife zeichnet 10 Sterne nebeneinander.
• Die Laufvariable ist hier ausserhalb der for-Schleife deklariert. Sie ist darum innerhalb und
ausserhalb der for-Schleife sichtbar.
• Beachten Sie:
Der Wert der Laufvariablen sollte innerhalb der for-Schleife nicht geändert werden! (dies geht
leider in Java)
• Beispiel 2:
for (int zaehler = 0; zaehler < 10; zaehler++) {...}
• Hier ist die Laufvariable innerhalb der for-Schleife deklariert. Sie ist deshalb nur innerhalb der
for-Schleife (inklusive Schleifenkopf) sichtbar, ausserhalb nicht.
• Beispiel 3:
for (int x = 4; x > 0; x--) {...}
• x-- ist gleichbedeutend mit der Anweisung: x = x-1;
• Die Laufvariable wird hier rückwärts gezählt.
• x = 4,3,2,1
4 Durchläufe
• Beispiel 4:
for (int x = 1; x <= 10; x = x + 2) {...}
• Die Laufvariable wird hier in 2er-Schritten erhöht.
• x = 1,3,5,7,9
5 Durchläufe
PPG.1.7.fm
73
6.4
Verschachtelte Schleifen
• Innerhalb einer for-Schleife können beliebige Anweisungen stehen. Insbesondere können weitere
for-Schleifen darin enthalten sein. In diesem Fall spricht man von verschachtelten Schleifen.
• Beispiel:
Entwerfen Sie ein Applet, das die Fensterfront eines Hochhauses zeichnet. Das Hochhaus soll 15
Stockwerke mit je 10 Fenstern aufweisen.
• Struktogramm
ySt = 20; xSt = 20;
anzFProStock = 10;
anzStockwerke = 15;
fenB = 10; fenH = 20;
fenAbstand = 5*fenB/4; stockH = 5*fenH/4;
PPG.1.7.fm
74
• Programm:
import java.awt.*;
import java.applet.Applet;
public class HochhausFenster extends Applet {
public void paint (Graphics g) {
int xSt = 20, ySt = 20;
int anzFproStock = 10, anzStockwerke = 15;
int fenB = 10, fenH = 20;
int fenAbstand = 5*fenB/4, stockH = 5*fenH/4;
int xPos, yPos;
yPos = ySt;
for (int stock = 0; stock < anzStockwerke; stock++) {
xPos = xSt;
for (int fenster = 0; fenster < anzFproStock; fenster++) {
g.drawRect(xPos, yPos, fenB, fenH);
xPos = xPos + fenAbstand;
}
// end for
yPos = yPos + stockH;
} // end for
} // end paint
}
Programm 6 : Hochhausfenster
PPG.1.7.fm
75
6.5
Kombinierte Ablaufstrukturen
• Nicht nur for-Schleifen sondern alle behandelten Ablaufstrukturen (if, for, while, do,
etc. ) lassen sich beliebig ineinander verschachteln.
• Innerhalb einer solchen Ablaufstruktur können auch beliebig andere Methoden aufgerufen werden.
• Beispiel: Programm Parkett
• Das Programm Parkett auf Seite 78 zeichnet ein Parkettmuster gemäss Figur 29.
Figur 29: Parkettmuster des Programms Parkett
• Pseudoprogramm
• Deklarationen
PPG.1.7.fm
76
• Ablauf
PPG.1.7.fm
77
import java.awt.*;
import java.applet.Applet;
public class Parkett extends Applet {
public void paint(Graphics g) {
int numSquares = 8;
// Anzahl Quadrate pro Reihe
int numLinesPerSq = 10; // Anz. Linien pro Quadrat
int xSt = 20, ySt = 20; // Startpunkt des Parketts
int size = 40;
// Grösse eines Quadrats
int xStL, yStL;
// Startpunkt der aktuellen Linie
// Schleife über alle Zeilen
for (int row = 0; row < numSquares; row++){
//
Schleife über alle Quadrate der Zeile row
for (int col = 0; col < numSquares; col++){
xStL = xSt + col*size;
// Startpunkt des Quadrates
yStL = ySt + row*size;
g.drawRect(xStL, yStL, size, size);
// Umrandung zeichnen
// etweder senkrechte oder waagrechte Linien zeichnen
if ((row + col) % 2 == 0 ){
// senkrechte Linien
for (int line = 0; line < numLinesPerSq; line++){
g.drawLine(xStL, yStL, xStL, yStL + size);
xStL = xStL + size/numLinesPerSq;
}
}
else{
// waagrechte Linien
for (int line = 0; line < numLinesPerSq; line++){
g.drawLine(xStL, yStL, xStL + size, yStL);
yStL = yStL + size/numLinesPerSq;
}
}
}
}
}
}
Programm 7 : Parkett
PPG.1.7.fm
78
7
Methoden
7.1
Ziele
• Sie können eine gegebene Methode korrekt aufrufen.
• Sie können selbständig Methoden mit und ohne Rückgabewert entwickeln, von der Definition bis
zur Implementation.
• Sie können die Sichtbarkeitsbereiche von lokalen Variablen und Parametern in einem gegebenen
Programm bestimmen.
• Sie können den Programmablauf und die Parameterübergabe bei einem Methodenaufruf anhand
eines Beispiels erklären.
• Sie setzen Methoden situationsgerecht ein.
7.2
Motivation
• Welche Vorteile bringt die Aufteilung eines Programmes in Unterprogramme?
• Die Komplexität wird reduziert:
Das gesamte Problem wird zuerst in möglichst unabhängige Teilprobleme aufgeteilt. Für diese
Teilprobleme suchen wir sodann Lösungen = Unterprogramme. Diese Teillösungen können
unabhängig vom Rest entwickelt und getestet werden. Die Teillösungen können sodann zur
Lösung des ursprünglichen Problems (= Gesamtprogramm) zusammengesetzt werden.
• Abstraktion:
Die Verwendung von Unterprogrammen erlaubt das Denken und Programmieren in höheren
Abstraktionsebenen. Jedes Unterprogramm erweitert die Programmiersprache um einen neuen
Befehl. Die Unterprogramm drawString(...) beispielsweise stellt uns einen Befehl zur
Verfügung, um eine Textzeile auf den Bildschirm auszugeben. Der Programmierer kann diesen
Befehl verwenden, ohne zu wissen, wie das Unterprogramm im Detail aussieht.
Abstraktion
• Wiederverwendung:
Ein Unterprogramm, das eine bestimmte Aufgabe erledigt, kann überall wieder verwendet
werden, wo diese Aufgabe auftaucht.
• Unterprogramme und objektorientierte Programmierung
• Unterprogramme haben ihren Ursprung in der prozeduralen Programmierung.
• Dieses Konzept wurde in der objektorientierten Programmierung übernommen und durch das
Konzept der Objekte erweitert:
• Objekte bestehen aus Daten und Methoden.
• Eine Methode ist ein Unterprogramm, das an ein bestimmtes Objekt gebunden ist. Sie
übernimmt eine bestimmte Aufgabe im Bezug auf das Objekt.
• Eine Methode kann selbst wieder andere Methoden aufrufen, um seine Aufgabe zu erfüllen.
PPG.1.7.fm
79
7.3
Eine erste eigene Methode
• Beispiel:
Wir möchten ein gleichschenkliges Dreieck zeichnen gemäss folgender Figur 30:
(100,60)
(20,100)
Figur 30: Gleichschenkliges Dreieck
1. Ansatz: Direkt programmieren
public void paint (Graphics g){
g.drawLine(20,100,100,60);
g.drawLine(100,60,180,100);
g.drawLine(180,100,20,100);
}
• Probleme:
2. Ansatz: Variablen
public void
int xUL =
int yUL =
int basis
int hoehe
paint (Graphics g){
20;
100;
= 160;
= 40;
g.drawLine(xUL, yUL, xUL+basis/2, yUL-hoehe);
g.drawLine(xUL+basis/2, yUL-hoehe, xUL+basis, yUL);
g.drawLine(xUL+basis, yUL, xUL, yUL);
}
PPG.1.7.fm
80
• Vorteil:
• Problem:
3. Ansatz: Methode zeichneGsDreieck
• Aufgabe der Methode:
Die Methode zeichneGsDreieck soll ein gleichschenkliges Dreieck zeichnen an der
gewünschten Stelle und in der gewünschten Grösse.
• Zur Festlegung der Position und der Grösse des Dreiecks werden der Methode 4 Werte für die
Variablen xUL, yUL, basis, hoehe übergeben.
• Dazu werden diese Variablen im Methodenkopf als sogenannte Parameter (werden oft auch als
"formale Parameter" bezeichnet) definiert.
public void paint (Graphics g){
zeichneGsDreieck(g,20,100,160,40);
zeichneGsDreieck(g,50,80,140,80);
}
public void zeichneGsDreieck(Graphics b, int xUL,
int yUL,int basis, int hoehe){
b.drawLine(xUL, yUL, xUL+basis/2, yUL-hoehe);
b.drawLine(xUL+basis/2, yUL-hoehe, xUL+basis, yUL);
b.drawLine(xUL+basis, yUL, xUL, yUL);
}
• Programmablauf:
1. Die aktuellen Werte (Argumente) werden beim Aufruf an die Methode übergeben:
xUL = 20, yUL = 100, basis = 160, hoehe = 40, b = g
2. Programm springt zur 1. Anweisung in der Methode zeichneGsDreieck.
3. Nach der letzten Anweisung in zeichneGsDreieck springt das Programm zurück zur
Methode paint (zur nächsten Anweisung nach dem Methodenaufruf).
• Vorteile:
– Der Programmcode für das Dreieck muss nur einmal geschrieben werden.
– Die Methode kann dann beliebig oft aufgerufen werden.
– Position und Grösse können bei jedem Aufruf geändert werden.
PPG.1.7.fm
81
7.4
Methodendeklaration
• Beispiel: zeichneGsDreieck
• Methodenkopf:
public void zeichneGsDreieck(Graphics b, int xUL, int yUL,
int basis, int hoehe)
a) Zugriffsmodifikator (access control modifier)
– public
überall sichtbar (auch für andere Klassen)
– private
nur innerhalb derselben Klasse sichtbar
b) Methodenname
c) Parameterliste
– Parameterdeklarationen, durch Kommas getrennt
– in runden Klammern unmittelbar nach dem Methodennamen
– Parameterdeklaration sieht gleich aus wie die Deklaration lokaler Variablen
– EBNF:
Parameterliste ::= [ Typ Parametername ] {, Typ Parametername }.
– Methode mit leerer Parameterliste: Methodenname(){...}
d) Resultattyp
– In Java gibt jede Methode einen Wert zurück (wie die Funktionen in Pascal)
– Der Resultattyp gibt den Datentyp des Rückgabewertes an, z.B. int oder float
– void
wird als Resultattyp verwendet, wenn eine Methode nichts zurückgibt.
– EBNF:
Resultattyp ::= void | Typ.
• Methodenkörper:
• ist alles innerhalb der geschweiften Klammern { ... } nach dem Methodenkopf
• Der Methodenkörper entspricht einem Block
• Er besteht demensprechend aus:
– Deklaration lokaler Variablen
– Anweisungen
• Allgemeine Methodendeklaration in EBNF:
Methodendeklaration ::= Zugriffsmodifikator Resultattyp Methodenname ( Parameterliste )
{ Methodenkörper }
• Beispiele:
• public int berechneFlaeche(int hoehe, int breite){ ... }
• private void vergrössern(float faktor){...}
• public void bremsen(){...}
• Da eine Methode immer an ein Objekt (und damit auch an eine Klasse) gebunden ist, muss sie
immer innerhalb einer Klasse deklariert werden.
• In einer Klasse können beliebig viele Methoden in beliebiger Reihenfolge deklariert sein.
PPG.1.7.fm
82
7.5
Entwicklung einer Methode
• Vorgehen
• Genau festlegen, was Methode machen soll.
Methodenname festlegen.
• Welche Informationen braucht die Methode dazu?
Parameterliste festlegen.
• Welche Resultate gibt die Methode zurück?
Resultattyp festlegen.
• Beispiele:
• Schreiben Sie eine Methode, die eine Rechtecksfläche berechnet.
• Ist diese Spezifikation vollständig?
• Namen festlegen:
• Parameterliste festlegen:
• Resultattyp festlegen:
• Methode schreiben:
PPG.1.7.fm
83
• Lernaufabe:
Schreiben Sie eine Methode, die einen ausgefüllten Halbkreis zeichnet. Der Radius und das
Zentrum des Kreises sollen wählbar sein. Zudem soll der Neigungswinkel der Basislinie
einstellbar sein.
Radius
Neigungswinkel
PPG.1.7.fm
84
7.6
Lokale Variablen und Parameter
• Lokale Variablen sind Variablen, die innerhalb einer Methode (oder innerhalb eines Blocks)
deklariert werden.
• Beispiele:
int xUL, yUL, basis, hoehe in der Methode paint von Ansatz 2.
• Sie sind nur innerhalb der Methode (oder des Blocks) sichtbar.
• Lokale Variablen werden beim Aufruf der Methode erzeugt und nach dem Verlassen wieder
gelöscht. Der Wert einer lokalen Variablen bleibt deshalb von einem Aufruf der Methode zum
nächsten nicht erhalten.
• Es können mehrere lokale Variablen mit dem gleichen Namen in verschiedenen Methoden deklariert
sein. Diese Variablen haben trotz des gleichen Namens nichts miteinander zu tun, d.h. es sind zwei
verschiedene unabhängige Variablen.
• Parameter sind lokale Variablen, die beim Methodenaufruf mit den Werten der entsprechenden
Argumente initialisiert werden.
7.7
Aufruf einer Methode
• Beispiel:
zeichneGsDreieck(g, 20,100,160,40);
a) Methodenname
b) Argumentliste
• Liste von Argumenten, durch Kommas getrennt, in den runden Klammern nach dem
Methodennamen.
• Argumente (auch aktuelle Parameter genannt) können sein:
– für Parameter der Zahltypen oder des Typs boolean: ein Ausdruck, insbesondere eine
Variable oder numerische oder symbolische Konstante
– für Parameter der Objekttypen: eine Objektreferenz
• Allgemeiner Methodenaufruf:
Methodenaufruf ::= [Bezeichner.] Methodenname( Argumentliste ).
• Bezeichner: Kann ein Objektname oder Klassenname sein.
7.8
Parameterübergabe
• Beispiel: Aufruf der Methode
public void zeichneGsDreieck(Graphics b, int xUL, int yUL,
int basis, int hoehe)
• Ablauf bei der Parameterübergabe (Siehe Figur 31)
• Ausserhalb der Methode sind nur die Anzahl der Parameter sowie deren Datentypen bekannt,
nicht aber die Namen der Parameter.
• Beim Aufruf der Methode müssen soviele Argumente übergeben werden wie die Anzahl der
Parameter.
• Es werden nur die Werte der Argumente, nicht die Argumente selbst an die Methode
übergeben (wird oft auch Übergabe "by value" genannt).
• Bei der Zuordnung von Argumenten zu den Parametern ist nur die Reihenfolge massgebend,
nicht etwa die Namen.
PPG.1.7.fm
85
• Der Compiler prüft, ob bei einem Methodenaufruf die Datentypen der Argumente mit den
Datentypen der Parameter der Methode übereinstimmen.
• Innerhalb der Methode verhalten sich die Parameter genau wie lokale Variablen, die mit den
übergebenen Argumentwerten initialisiert wurden. Die Werte der Parameter können deshalb in
der Methode beliebig verändert werden. In der aufrufenden Methode verändern sich die Werte
der Variablen dadurch nicht.
• Auch wenn Parameter einer Methode denselben Namen haben wie eine Variable in der
aufrufenden Methode, so haben diese nichts miteinander zu tun.
public void paint(Graphics g){
int b = 30, h = 40;
zeichneGsDreieck(g, 20, 100+30, b, h);
}
1
Graphics
2
int
b
xUL
3
int
yUL
4
int
basis
5
int
hoehe
Methode zeichneGsDreieck
...
b.drawLine(xUL, yUL, xUL+basis/2, yUL-hoehe);
...
Figur 31: Parameterübergabe an eine Methode
PPG.1.7.fm
86
• Achten Sie also bei einem Methodenaufruf auf folgende Punkte:
• Die Zahl der Argumente beim Aufruf muss gleich sein wie die Anzahl der Parameter einer
Methode.
• Die Reihenfolge der Argumente muss mit der Reihenfolge in der Methodendeklaration
übereinstimmen.
• Die Datentypen der Argumentswerte müssen gleich (oder mindestens kompatibel) sein mit den
deklarierten Datentypen der Parameter.
7.9
Rückgabe der Resultate
• Beispiel-Programm
import java.awt.*;
import java.applet.Applet;
public class Rueckgabe extends Applet {
public void paint(Graphics g) {
int antwort;
antwort = berechneFlaeche(30,40);
g.drawString("Fläche des Rechtecks ist " + antwort, 100, 100);
}
private int berechneFlaeche(int breite, int hoehe){
return (breite * hoehe);
}
}
Programm 8 : Rueckgabe
• Deklaration
• Datentyp des Rückgabewertes muss angegeben werden (hier int)
• Falls nichts zurückgegen wird void
• Rückgabe des Resultates
• Falls der Resultattyp einer Methode nicht void ist, muss sie ein Resultat zurückgeben:
• Anweisung, um ein Resultat an die aufrufende Methode zurückzugeben:
return Ausdruck;
• Der Datentyp des Rückgabewertes muss mit der Deklaration übereinstimmen.
• Nach der return-Anweisung kehrt Programm sofort aus der Methode zurück.
• return;
Nach dieser Anweisung kehrt das Programm sofort aus der Methode zurück, ohne etwas
zurückzugeben (Braucht man bei Methoden mit Rückgabewerttyp void).
• Verwendung des Rückgabewertes
• In der aufrufenden Methode muss der Rückgabewert der Methode direkt verwendet werden.
• Beispiel:
antwort = berechneFlaeche(30,40);
• Ablauf:
1. Die Methode berechneFlaeche wird aufgerufen
2. Der Methodenaufruf in der Anweisung wird durch den Rückgabewert der aufgerufenen
Methode ersetzt: antwort = 1200;
PPG.1.7.fm
87
3. Die Anweisung wird ausgeführt.
– Test:
Falls beim Ersetzen des Methodenaufrufs durch den Rückgabewert keine gültige
Anweisung entsteht, ist der Methodenaufruf falsch.
Beispiel: berechneFlaeche(30,40);
1200;
falscher Aufruf.
• Hat eine Methode keinen Rückgabewert, so kann sie direkt aufgerufen werden:
g.drawRect(20,30,40,50);
• Test durch einsetzen:
g.drawRect(20,30,40,50);
;
gültige Anweisung (Leeranweisung)
• Beispiel:
Schreiben Sie eine Methode, die das quadratische Polynom y = ax2 + bx + c für beliebige
reelle a, b, c, x berechnet.
• Lernaufgabe
Schreiben Sie eine Methode, die für eine beliebige reelle Zahl, die entsprechende gerundete ganze
Zahl zurückgibt.
PPG.1.7.fm
88
7.10
Methoden mit Varargs
• Ab der Version Java 1.5 können auch Methoden mit variabler Parameterliste deklariert werden.
• Auf diese Methoden wird in dieser einführenden Vorlesung nicht näher eingegangen.
7.11
•
•
•
•
Programmierfallen
Datentypen bei der Parameterdeklaration nicht vergessen.
Die Argumente beim Methodenaufruf dagegen ohne Datentyp angeben.
Richtige Anzahl, Reihenfolge und Typ der Argumente beachten.
Returnwerte müssen beim Aufruf einer Methode konsumiert werden.
PPG.1.7.fm
89
8
Ereignisse
8.1
Ziele
• Sie können die Merkmale eines ereignisgesteuerten Programms erklären.
• Sie können den prinzipiellen Aufbau eines ereignisgesteuerten Programms in Java skizzieren.
• Sie können ein einfaches ereignisgesteuertes Programm in Java entwickeln, vom Konzept bis zur
Realisierung.
• Sie unterscheiden lokale Variablen und Instanzvariablen.
• Sie können einfache graphische Komponenten richtig einsetzen.
8.2
Einführung
• Alle Programme, die Sie bis jetzt programmiert haben, sind sogenannte sequentielle Programme.
• Die Merkmale eines solchen sequentiellen Programms sind (siehe Figur 32):
• Das Hauptprogramm steuert den gesamten Programmablauf (Bei Applet ist das die paintMethode):
• Es ruft an bestimmten Stellen Unterprogramme auf. Diese geben am Ende jeweils die
Kontrolle wieder an das Hauptprogramm zurück.
• Es verlangt an bestimmten Stellen Eingaben vom Benützer.
• Der gesamte zeitliche Ablauf des Programms ist vor dem Start festgelegt.
• Der Benützer kann wenn überhaupt nur an den vorbestimmten Stellen auf den Programmablauf
Einfluss nehmen, nämlich dort, wo das Programm eine Eingabe verlangt
Start
Benützereingabe
Verarbeitung 1
Unterprogramm 1
Verarbeitung 2
Nein
Fertig?
Ja
Ende
Figur 32: Typischer Ablauf eines sequentiellen Programms
PPG.1.7.fm
90
• Beispiele für sequentielle Programme:
• Compiler
• Kommandozeilenbefehle (cd, dir, more, ...)
• Applets ohne graphische Benützeroberfläche
• Probleme bei sequentiellen Programmen
• Sequentielle Programme sind ungeeignet für interaktive Anwendungen, da alle möglichen
zeitlichen Programmabläufe schon beim Programmieren festgelegt werden müssen.
• Übertragen auf ein Auto würde das heissen:
– Der Fahrer müsste vor der Abfahrt festlegen, wann er beschleunigen oder bremsen will,
wann das Radio einschalten, wann die Türen öffnen will etc.
– Er könnte sodann nur noch zu den vorgegebenen Zeitpunkten beschleunigen, bremsen, etc.
• Eine natürliche Interaktion des Benützers mit solchen Programmen ist nicht möglich.
• Diese Probleme können gelöst werden mit sogenannten ereignisgesteuerten Programmen
• Ereignisgesteuerte Programme (event driven programs)
• Hauptmerkmal eines ereignisgesteuerten Programms ist:
Der Programmablauf ist nicht fix vorgegeben sondern wird durch externe Ereignisse gesteuert,
wie z.B.:
• Mausklick
• Menuauswahl
• Tastendruck
• Betriebssystem, andere Programme
Taste gedrückt?
Maus bewegt?
Maustaste betätigt?
Figur 33: Ereignisschleife
PPG.1.7.fm
91
• Beispiele
• Alle Programme mit graphischer Benützeroberfläche (GUI: Graphical User Interface)
• Telefonbeantworter, TVA (Telefonvermittlungsanlagen)
• Real-Time-Systeme
• Server
• Idee:
Die Idee der ereignisgesteuerten Programme beruht auf einer Ereignisschleife, wie sie in der
Figur 33 auf Seite 91 dargestellt ist.
• Ereignisschleife (event loop)
• Das Hauptprogramm besteht aus einer Ereignisschleife.
• Diese wartet auf Ereignisse.
• Der Programmierer schreibt für jedes Ereignis eine entsprechende Methode.
• Beim Eintreffen eines Ereignisses ruft die Ereignisschleife die entsprechende Methode auf,
um das eingetroffene Ereignis zu behandeln.
8.3
Ereignisse in Java (Events)
• Ereignisschleife
• Das AWT (Abstract Windows Toolkit) von Java implementiert eine Ereignisschleife.
• Der Programmierer muss nur noch die Methoden schreiben, die die Ereignisse behandeln.
• Die Ereignisschleife verarbeitet zusammen mit dem Betriebssystem die Elementarereignisse des
Systems.
• Beispiele für Elementarereignisse
• Die Komponenten des AWT (Button, Scrollbar, etc.) bereiten diese Elementarereignisse auf
• Sie nehmen Elementarereignisse, die sie betreffen, entgegen.
• Sie erzeugen daraus semantische Ereignissse.
• Bsp. Button:
PPG.1.7.fm
92
8.4
Java-Ereignis-Modell (ab Version 1.1)
• Delegation-Event-Modell
• Beim Delegation-Event-Modell werden die auftretenden Ereignisse nicht zentral behandelt.
• Die Behandlung jedes Ereignisses wird vielmehr an ein oder mehrere Objekte delegiert.
• Konzept:
SourceObjekt
Mögliche Ereignisse:
1. ActionEvent
2. AdjustmentEvent
Listener-Objekt
public void
actionPerformed(ActionEvent e){
...
}
Listeners:
Figur 34: Konzept des Delegation-Event-Modells ab Java 1.1
• Source-Objekt
• Definiert Ereignisse, die es erzeugen kann
• Führt eine Liste der Listener-Objekte
• Informiert Listener-Objekte, sobald ein Ereignis eingetreten ist:
• Das Source-Objekt ruft die entsprechende Methode beim Listener-Objekt auf.
• Alle Informationen über das Ereignis werden dabei in einem Ereignis-Objekt übergeben.
• Listener
• Registriert sich beim Source-Objekt als Listener.
• Gibt an, an welchen Ereignissen es interessiert ist (Bsp. ActionEvent).
• Stellt je eine Methode zur Behandlung der entsprechenden Ereignisse bereit.
8.5
Ereignisklassen
• Es gibt zahlreiche Ereignisse, die Komponenten erzeugen können und an denen andere Objekte
interessiert sind.
• In Java werden die verschiedenen semantischen Ereignisse, die die Komponenten erzeugen
können, in Klassen zusammengefasst.
PPG.1.7.fm
93
• 2 Beispiele solcher Ereignisklassen:
Ereignisklasse
SourceObjekt
Listener
Aufgerufene
Methode
Bedeutung
• Dieselbe Ereignisklasse wird von mehreren Komponenten verwendet. Beispielsweise wird die
Ereignisklasse ActionEvent von den Komponenten Button, TextField, List und
MenuItem verwendet.
• Welche der Komponenten ein bestimmtes Ereignis hervorgerufen hat, kann mit Hilfe der
Information im Ereignisobjekt herausgefunden werden.
8.6
Button (Schaltfläche)
• Das Programm 9 auf Seite 96 zeigt an einem einfachen Beispiel, wie man einen Button
(Schaltfläche) erzeugt und dessen Ereignisse abfängt. Das Applet stellt einen Button „Hier drücken“
zur Verfügung wie in Figur 35 dargestellt. Nachdem der Button gedrückt wurde, erscheint die
Meldung „Danke!“.
Figur 35: Programm „Drück Mich“
• Erklärungen zu den einzelnen Zeilen im Programm 9:
1) sagt aus, dass die Klasse DrueckMich das Interface ActionListener implementiert. Die
Klasse muss deshalb die Methode actionPerformed(ActionEvent e) zur Verfügung
stellen.
2) Hier wird ein Objekt mit dem Namen tester der Klasse Button deklariert.
• Das Objekt selbst existiert noch nicht, erst der Variablenname dafür.
• Die Deklaration der Variablen ausserhalb einer Methode bewirkt, dass die Variable in allen
Methoden der Klasse sichtbar ist. Man nennt diese Variablen Instanzvariablen.
PPG.1.7.fm
94
• private bedeutet, dass die Variable nur innerhalb der Klasse DrueckMich sichtbar ist.
3) Methode init()
• Das ist eine vordefinierte Methode der Klasse Applet.
• Sie wird ein einziges Mal aufgerufen, wenn das Applet gestartet wird.
• In dieser Methode werden normalerweise alle benötigten Komponenten erzeugt und
initialisiert.
4) Hier wird nun das Objekt tester der Klasse Button erzeugt und der Variable tester
zugewiesen mit der Anweisung:
tester = new Button(„Hier drücken“);
• Allgemein sieht die Erzeugung eines Buttons folgendermassen aus:
buttonName = new Button(ButtonLabel);
5) Fügt Komponente tester zum Applet hinzu durch den Aufruf der Methode add.
• add ist ebenfalls eine vordefinierte Methode des Applets.
• Man könnte hier auch schreiben this.add(tester);
• this bezeichnet das Objekt, in dem wir uns gerade befinden, d.h. hier das DrueckMichObjekt selbst.
6) Registriert das aktuelle Objekt (this) beim Button tester als Listener für ActionEvents.
Die Registrierungsmethoden für Listener-Objekte folgen einer einheitlichen Namensgebung. Die
Methode, die einen Listener für ein Ereignis XXX anmeldet, heisst
SourceObjekt.addXXXListener(Listener-Obj.);
7) Die Methode actionPerformed(ActionEvent e)
• wird vom Button tester jedesmal bei allen registrierten Listenern aufgerufen, wenn der
Button gedrückt wird.
• In dieser Methode stehen die Anweisungen, die dieses Ereignis behandeln. In unserem
einfachen Beispiel wird hier bloss die Instanzvariable gedrueckt auf true gesetzt.
8) Nachdem der Button gedrückt wurde, muss das Applet neu gezeichnet werden, um dem Benutzer
die Reaktion des Programms anzuzeigen:
• repaint() fordert den Browser auf, das Applet neu zu zeichnen.
• Der Browser ruft sodann unter anderem die Methode paint des Applets auf.
9) In der Methode paint() wird schliesslich „Danke!“ auf den Bildschirm ausgegeben. Danach
wird gedrueckt wieder auf false gesetzt.
Wieso ist das nötig?
PPG.1.7.fm
95
• Das Programm DrueckMich
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class DrueckMich extends Applet
1)
implements ActionListener {
2)
private Button tester;
private boolean gedrueckt = false;
3)
public void init() {
4)
tester = new Button("Hier drücken");
5)
add (tester);
6)
tester.addActionListener(this);
}
9)
public void paint(Graphics g) {
if (gedrueckt) {
g.drawString ("Danke!", 100,50);
}
gedrueckt = false;
}
7)
public void actionPerformed(ActionEvent event) {
gedrueckt = true;
8)
repaint();
}
}
Programm 9 : DrueckMich
PPG.1.7.fm
96
• Übungsaufgabe Zufallszahlen:
Finden Sie heraus, was das Programm ZweiWuerfel genau macht.
Zur Erinnerung: Math.random() erzeugt eine gleichverteilte Zufallszahl r, mit 0 <= r < 1.
public class ZweiWuerfel extends Applet implements ActionListener {
private Button throwDice;
private boolean thrown = false;
public void init() {
throwDice = new Button("Wirf!");
add (throwDice);
throwDice.addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
thrown = true;
repaint();
}
public void paint(Graphics g) {
int die1, die2;
if (thrown) {
die1 = (int)(Math.random() * 6)+1;
die2 = (int)(Math.random() * 6)+1;
g.drawString("Die Augenzahlen der Würfel sind :", 20, 60);
g.drawString(""+ die1 + " und " + die2, 40, 80);
}
if (die1 == die2){
g.drawString ("Gewonnen!", 40, 100);
}
else{
g.drawString ("Tut mir leid!" , 40, 100);
}
thrown = false;
}
}
}
Programm 10 : ZweiWuerfel
PPG.1.7.fm
97
• Ihre Erklärungen zum Programm 10:
• Mehrere Buttons
• Problem bei mehreren Buttons:
Alle Buttons erzeugen ein Ereignis der gleichen Klasse ActionEvent. Wie kann man
herausfinden, welcher Button das Ereignis erzeugt hat?
• Lösung:
• Das an die Methode actionPerformed(ActionEvent e) übergebene EreignisObjekt e enthält verschiedene Informationen zum Ereignis.
• So kann beispielsweise mit der Methode e.getSource() der Name des Source-Objekts, das
das Ereignis erzeugt hat, abgefragt werden.
• Beispiel: Programm KleinerGroesser :
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class KleinerGroesser extends Applet
implements ActionListener {
private int diameter = 20;
private Button smaller, larger;
public void init() {
smaller = new Button("Kleiner");
add (smaller);
smaller.addActionListener(this);
PPG.1.7.fm
98
larger = new Button("Grösser");
add (larger);
larger.addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
if (event.getSource() == smaller){
diameter = diameter - 10;
}
if (event.getSource() == larger){
diameter = diameter + 10;
}
repaint();
}
public void paint(Graphics g) {
g.drawOval (50,50, diameter, diameter);
}
}
Programm 11 : KleinerGroesser
8.7
Instanzvariablen
• In Java müssen Variablen wie Methoden immer innerhalb einer Klasse deklariert sein.
• Variablen haben unterschiedliche Eigenschaften, je nachdem, wo sie innerhalb der Klasse deklariert
werden.
• Man unterscheidet vor allem zwei Arten von Variablen: Lokale Variablen und Instanzvariablen.
• Lokale Variablen
• werden innerhalb einer Methode deklariert.
• sind nur innerhalb der Methode sichtbar.
• werden beim Aufruf einer Methode erzeugt und beim Verlassen wieder gelöscht.
• Lokale Variablen haben keinen Zugriffsmodifikator (siehe Instanzvariablen).
• Die Parameter einer Methode verhalten sich genau gleich wie lokale Variablen:
• Sie sind ebenfalls nur innerhalb der Methode sichtbar
• Sie werden beim Methodenaufruf erzeugt und nach dem Verlassen der Methode gelöscht.
• Nach der Erzeugung werden die Parameter mit den Werten initialisiert, die beim Aufruf der
Methode als Argumente übergeben werden.
• Instanzvariablen
• werden innerhalb einer Klasse aber ausserhalb der Methoden deklariert.
• sind innerhalb derselben Klasse sichtbar, d.h. in jeder Methode der Klasse.
• existieren solange, wie das Objekt (die Instanz) existiert.
PPG.1.7.fm
99
• sind Eigenschaften (properties) oder Attribute des Objektes
• behalten ihre Werte bei, auch wenn das Programm das Objekt verlässt.
• Die Sichtbarkeit von Instanzvariablen kann durch den sogenannten Zugriffsmodifikator
bestimmt werden. Wir kennen bisher folgende Zugriffsmodifikatoren:
• private
Instanzvariable ist nur innerhalb der Klasse sichtbar (das ist die Regel)
• public
Instanzvariable ist auch ausserhalb der Klasse sichtbar und veränderbar
(in der Regel unerwünscht / schlechter Programmierstil)
• Beispiele von Instanzvariablen:
Variablen diameter, smaller und larger im Programm KleinerGroesser auf
Seite 99.
• Lernaufgabe:
Überlegen Sie sich, wieso diese Variablen im Programm KleinerGroesser als
Instanzvariablen deklariert sind und nicht als lokale Variablen. Welche Eigenschaften von
Instanzvariablen werden hier benötigt?
8.8
Textzeile (TextField)
• Neben den Buttons gibt es noch eine andere GUI-Komponente, die ActionEvents erzeugt, die
sogenannte Textzeile.
• Die Textzeile ist für einzeilige Eingaben (und Ausgaben) gedacht.
• Der eingegebene Text kann beliebig editiert werden, bis die Eingabe durch Drücken der Enter-Taste
bestätigt wird.
• Um eine Textzeile zu erzeugen, braucht es dieselben 6 Schritte wie bei einem Button (vgl.
Programm 12 auf Seite 102):
1. Applet als ActionListener deklarieren.
2. TextField-Variable deklarieren: TextField eingabe;
3. Textzeile erzeugen:
eingabe = new TextField(10);
10
bedeutet die Anzahl angezeigter Zeichen
4. Textzeile zu Applet hinzufügen:
add(eingabe);
5. Applet als Listener registrieren:
eingabe.addActionListener(this);
6. Methode actionPerformed schreiben.
PPG.1.7.fm
100
• Um den Text in der Textzeile zu verarbeiten, stellt die Komponente verschiedene Methoden zur
Verfügung:
• Text von der Textzeile einlesen: eingabe.getText()
• Text in Textzeile schreiben:
eingabe.setText("Text")
• Möchte man eine Zahl von einer Textzeile einlesen, so muss man den Text in die entsprechende Zahl
umwandeln. Für int-Zahlen kann man dazu die in der Klasse Integer vorhandene Methode
parseInt verwenden:
int age = Integer.parseInt(eingabe.getText());
• Falls mehrere Textzeilen erzeugt wurden, kann man wieder mit der Methode getSource() des
Event-Obekts (event im Programm 12) die Textzeile herausfinden, die das Ereignis erzeugt hat.
• Beispiel: Programm Waehlerkontrolle
Das Progamm Waehlerkontrolle liest das Alter einer Person als ganze Zahl von einer
Textzeile ein und entscheidet dann, ob die Person wählen darf (d.h. 18 oder älter ist) oder nicht.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Waehlerkontrolle extends Applet implements
ActionListener {
private TextField eingabe;
private int alter;
public void init() {
eingabe = new TextField(10);
add(eingabe);
eingabe.addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
if (event.getSource() == eingabe){
alter = Integer.parseInt(eingabe.getText());
}
repaint();
}
PPG.1.7.fm
101
public void paint (Graphics g) {
g.drawString("Alter ist " + alter, 50, 80);
if (alter >= 18){
g.drawString("Stimmberechtigt", 50, 100);
}
else {
g.drawString("Zu jung!", 50,100);
}
}
}
Programm 12 : Waehlerkontrolle
8.9
Schieberegler (Scrollbar)
• Neben den GUI-Komponenten Button und Textzeile werden häufig auch sogenannte Schieberegler
(engl. scrollbars) wie in Figur 36 eingesetzt.
• Der Scollbar kann durch das Verschieben des Balkens oder durch Drücken auf die Pfeile betätigt
werden. Dabei verschiebt er sich mit der konstanten Schrittweite 1 pro Ereignis. Drückt man
dagegen links oder rechts des Balkens ins Feld, so verschiebt sich der Scrollbar mit einer grösseren,
einstellbaren Schrittweite.
• Beim Erzeugen eines Scrollbars kann die Ausrichtung des Scrollbars, der Minimal- und
Maximalwert, der Startwert sowie die Grösse der Schrittweite angegeben werden.
• Im Gegensatz zu Buttons und Textzeilen erzeugen Scrollbars Ereignisse der Klasse
AdjustmentEvent.
• Der Scrollbar ruft bei jeder Verschiebung der Balkens die Methode
adjustmentValueChanged(AdjustmentEvent e) auf.
• Der aktuelle Wert des Scrollbars kann mit dessen Methode getValue() abgefragt werden.
• Beispiel:
Das Programm Schieberegler auf Seite 104 stellt einen Schieberegler dar. Unterhalb des
Schiebereglers wird jeweils der Wert, der beim Schieberegler eingestellt wird, angezeigt.
• Es braucht auch hier 6 Schritte, um einen Scrollbar samt Ereignis-Bearbeitung zu implementieren:
1. Applet als AdjustmentListener deklarieren:
2. Deklaration einer Scrollbar-Variable:
PPG.1.7.fm
102
3. Scrollbar erzeugen:
4. Scrollbar zu Applet hinzufügen:
5. Applet als Listener beim Scrollbar registrieren:
6. Methode adjustmentValueChanged(AdjustmentEvent ereignis) schreiben.
Figur 36: Programm Schieberegler
PPG.1.7.fm
103
• Der Programmcode:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Schieberegler extends Applet
implements AdjustmentListener{
1)
2)
private Scrollbar slider;
private int sliderValue = 0;
public void init() {
3)
slider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 100);
4)
add(slider);
5)
slider.addAdjustmentListener(this);
}
public void paint(Graphics g) {
g.drawString("Aktueller Schiebereglerwert: " + sliderValue,
100, 100);
}
6)
public void adjustmentValueChanged(AdjustmentEvent e){
sliderValue = slider.getValue();
repaint();
}
}
Programm 13 : Schieberegler
8.10
Labels
• Labels sind Beschriftungen mit einem fixen Text.
• Ein Label-Objekt kann mit folgender Anweisung erzeugt werden (als lokaler Variable):
Label labelVariable = new Label("Labeltext");
Labeltext ist der Text der Beschriftung
• Labels verhalten sich wie andere Komponenten (Scrollbar, Button, etc.)
• Label können aber keine Ereignisse erzeugen.
PPG.1.7.fm
104
• Layout der GUI-Komponenten
Wenn nichts anderes angegeben wird, werden die Komponenten in einem Applet nach einem
Standard-Layout angeordnet. Dieses ist bei Applets das sogenannte Flow-Layout:
• Die Komponenten werden zeilenweise zentriert aufgreiht.
• Wenn eine Zeile voll ist, werden die restlichen Komponeten auf einer neuen Zeile dargestellt.
• Aufgabe:
• Finden Sie heraus, was das Programm LabelDemo macht.
• Verfolgen Sie im Detail, wie das Programm abläuft.
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class LabelDemo extends Applet implements
AdjustmentListener {
private Scrollbar bar1, bar2;
private int bar1Value = 0;
private int bar2Value = 0;
public void init() {
Label title1, title2;
// Lokale Sichtbarkeit genügt
title1 = new Label("up:");
add(title1);
bar1 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 100);
add(bar1);
bar1.addAdjustmentListener(this);
title2 = new Label("
down:");
add(title2);
bar2 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 100);
add(bar2);
bar2.addAdjustmentListener(this);
}
public void paint(Graphics g) {
g.drawString("UP value is " + bar1Value, 100, 100);
g.drawString("DOWN value is " + bar2Value, 100, 150);
}
PPG.1.7.fm
105
public void adjustmentValueChanged(AdjustmentEvent e) {
bar1Value = bar1.getValue();
bar2Value = bar2.getValue();
repaint();
}
}
Programm 14 : LabelDemo
• Ihre Erklärungen zum Programm:
8.11
Skalierung des Schiebereglerwertes
• Problem:
Bei der Verwendung von Scrollbars tritt häufig folgendes Problem auf:
• Man möchte mit dem Scrollbar beispielsweise Werte zwischen 0.0 und 10.0 in 0.1-Schritten
einstellen.
• Die kleinste Schrittweite bei einem Scrollbar ist aber 1, da nur int-Zahlen als Scrollbar-Werte
erlaubt sind.
• Lösung:
• Die vom Scrollbar zurückgegebenen Werte werden skaliert.
PPG.1.7.fm
106
• Beispiel: Progamm zur Umrechnung von inch in cm:
• Der gewünschte Scrollbar-Bereich im Progamm InchesToCm soll 0.0-10.0 sein mit einer
Schrittweite von 0.1.
• Lösung:
• Minimum, Maximum und Inkrement des Scrollbars auf 0, 100 bzw. 1 setzen:
slider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 100);
• Ausgelesenen Scrollbar-Wert jeweils durch 10 dividieren:
sliderValue = (float) slider.getValue()/10;
• Programmcode:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class InchesToCm extends Applet
implements AdjustmentListener {
private Scrollbar slider;
private float sliderValue;
public void init() {
slider = new Scrollbar(Scrollbar.HORIZONTAL ,0, 1, 0, 100);
add(slider);
slider.addAdjustmentListener(this);
}
public void paint(Graphics g) {
float cmEquivalent;
cmEquivalent = sliderValue*2.54f;
g.drawString("Inches = " + sliderValue +
" Cm = " + cmEquivalent, 100, 100);
}
public void adjustmentValueChanged(AdjustmentEvent e) {
sliderValue = (float) slider.getValue()/10;
repaint();
}
}
Programm 15 : Programm zur Umrechnung von inch in cm
PPG.1.7.fm
107
8.12
Aufbauen von Grafiken
• Problemstellung:
• Es soll eine Grafik interaktiv aufgebaut werden, d.h. bei jeder Benützereingabe wird ein Teil der
Grafik gezeichnet.
• Das bereits Gezeichnete soll dabei erhalten bleiben, d.h. nicht gelöscht werden.
• Problem:
Beim Aufruf von repaint()wird die Grafik jedesmal vor dem Zeichnen gelöscht.
• Lösung:
• Die Grafik wird direkt in der Methode actionPerformed gezeichnet, nicht in der Methode
paint.
• Dazu muss man aber irgendwie das Graphics-Objekt des Applets zur Verfügung haben.
• Mit der Methode getGraphics() erhält man das Graphics-Objekt des Applets.
• Achtung: getGraphics() nicht in init() aufrufen, da dort das Graphics-Objekt noch
gar nicht existiert.
• Beispiel: Programm ScrollbarValues
Das Progamm 16 auf Seite 109 erzeugt folgende Bilschirmdarstellung:
• Bei jeder Bewegung des Scrollbars wird eine neue waagrechte Linie gezeichnet mit einer Länge,
die dem aktuellen Wert des Scrollbars entspricht.
• Die früher gezeichneten Linien bleiben dabei erhalten, obwohl sie nicht mehr neu gezeichnet
werden.
PPG.1.7.fm
108
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class ScrollbarValues extends Applet
implements AdjustmentListener {
private Scrollbar slider;
private int currentX = 1;
private int currentY = 5;
public void init() {
slider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 100);
add(slider);
slider.addAdjustmentListener(this);
}
public void adjustmentValueChanged(AdjustmentEvent e) {
Graphics g = getGraphics();
currentX = slider.getValue();
g.drawLine(0, currentY, currentX, currentY);
currentY = currentY+5;
}
}
Programm 16 : ScrollbarValues
PPG.1.7.fm
109
9
Datentypen
9.1
Ziele
• Sie unterscheiden einfache Datentypen und Referenz-Datentypen.
• Sie können mit beiden Arten von Datentypen richtig umgehen.
• Sie kennen die möglichen Ausnahmebedingungen, die bei den einzelnen einfachen Datentypen
auftreten können, und deren Folgen.
• Sie können mindestens eine Möglichkeit nennen, um mit diesen Ausnahmebedingungen
umzugehen.
• Sie können die Typenkonversionsregeln bei Ausdrücken mit gemischten einfachen Datentypen
korrekt anwenden.
• Sie kennen die Methoden in der Klasse Math und setzen sie ein.
9.2
Einführung
• Einfache Datentypen werden verwendet, um einzelne Werte (Zahlen, Buchstaben, logische Werte)
im Computer abzuspeichern und zu verarbeiten.
• Der Variablenname eines einfachen Datentyps bezeichnet dabei genau den Speicherplatz, wo der
Wert abgespeichert ist.
• Der Speicherplatz eines einfachen Datentyps wird gleich bei der Deklaration der Variablen
reserviert.
• Zusätzlich zu diesen einfachen Datentypen definieren viele Programmiersprachen noch Datentypen,
die es erlauben, gleichzeitig mehrere Werte zu speichern und zu verarbeiten. Dabei können die
einzelnen Werte vom gleichen oder von unterschiedlichem Datentyp sein.
• Man bezeichnet solche Datentypen als strukturierte Datentypen.
• In Java sind beispielsweise Klassen und Felder (Arrays) strukturierte Datentypen.
• Bei strukturierten Datentypen wird bei der Deklaration der Variablen nicht schon der ganze
Speicherplatz für die Daten reserviert, sondern nur ein kleiner Speicherplatz, wo dann später die
Adresse der eigentlichen Daten gespeichert wird.
• Der Speicherbereich für die eigentlichen Daten wird durch eine explizite Anweisung (new bei
Klassen) dynamisch im Arbeitsspeicher angelegt. Die Startadresse dieses Speicherbereichs wird
sodann im Speicherplatz der Variablen gespeichert.
• Da bei strukturierten Datentypen im Speicherplatz der Variablen also nicht der eigentliche Wert der
Variablen, sondern nur die Adresse steht, wo die Daten zu finden sind, nennt man die strukturierten
Datentypen häufig auch Referenzdatentypen.
9.3
Einfache Datentypen
• In Java existieren einfache Datentypen für ganze und reelle Zahlen, Zeichen und logische Werte.
9.3.1
Ganze Zahlen
• Für die ganzen Zahlen stellt Java vier verschiedene Datentypen mit jeweils unterschiedlichen
Wertebereichen zur Verfügung:
• byte (8 Bit), short (16 Bit), int (32 Bit), long (64 Bit)
PPG.1.7.fm
110
• Wertebereiche
Typ
Grösse [Bits]
negativer Max.wert
positiver Max.wert
byte
8
-27 = -128
27-1 = 127
short
16
-215 = -32768
215-1 = 32767
int
32
-231 = -2147483648
231-1 = 2147483647
long
64
-263 =
-9223372036854775808
263-1 =
9223372036854775807
Tabelle 7: Wertebereiche von den Ganzzahldatentypen
• Beispiele von Variablendeklarationen mit Initialisierung:
• byte b = 127;
• short s = -1214;
• long l = 104L;
• Soll eine Zahl intern als long-Zahl dargestellt werden, so muss der Zahl ein l oder L
angehängt werden: 104L, -1009337l
• Reelle Zahlen:
Für reelle Zahlen stehen zwei Datentypen mit unterschiedlichen Wertebereichen und Genauigkeiten
zur Verfügung:
• float (32 Bit), double (64 Bit)
• Wertebereiche
Typ
Grösse [Bits]
Max.wert
Min.wert
Präzision
float
32
± 3.4e+38
±1.4e-45
6-7 Stellen
double
64
± 1.79e+308
±4.9e-324
14-15 St.
Tabelle 8: Wertebereiche von float- und double-Zahlen
9.3.2
Logische Werte
• Für logische Werte steht in Java der einfache Datentyp boolean zur Verfügung.
• Der Datentyp umfasst nur die Werte true und false.
9.3.3
Zeichen (Character)
• Java definiert einen einfachen Datentyp für einzelne Zeichen:
char
• Ein char-Literal wird in Java mit einfachen Anführungsstrichen geschrieben, z.B. 'a', 'T'
• Eine Variable vom Typ char enthält den Unicode eines einziges Unicode-Zeichen, z.B. 'a',
'U', '3', ' ', '@', '.', 'ü'.
• Der Datentyp char hat die Länge 16 Bit.
• Es sind also mehr als 65000 verschiedene Zeichen darstellbar. Bis heute sind mit allen unterstützten
Sprachen ca. die Hälfte der Unicodes belegt. Die Zeichen mit den Unicodes 0000-00FF entsprechen
dem ASCII-Code mit der Latin-1 Zeichensatzerweiterung (siehe Seite 40: Darstellung von
Zeichen).
PPG.1.7.fm
111
• Deklaration eines Characters:
char ch;
char grossM = 'M';
char ue = 'ü';
• Die Zuweisung zu einer char-Variablen funktioniert genau gleich wie mit den anderen einfachen
Datentypen:
ch = 'a';
ch = grossM;
• Vergleich:
• Characters sind nach ihrem Unicode geordnet. Das Zeichen 'A' hat den Unicode 0041 (Hex), die
andern folgen in alphabetischer Reihenfolge. Die Kleinbuchstaben beginnen bei Unicode 0061
und sind ebenfalls alphabetisch geordnet.
• Characters können deshalb einfach verglichen werden, indem ihr Unicode verglichen wird.
• Für Characters können die gleichen Vergleichoperatoren verwendet werden wie für Zahlen:
• if (ch == 's') {...} // falls ch das Zeichen 's' ist ...
• 'b' > 'a'
//
ist true, da der Unicode von 'b' grösser ist als
// der von 'a'
• if (ch > 'a') {...} // true für ch = 'b', 'c', 'd', ...
• if (ch != ' ') {...} // falls ch nicht der Leerschlag ist, ...
• Aufgaben:
Stellen Sie fest, ob bzw. für welche Werte die folgenden Ausdrücke wahr oder falsch sind:
• 'n' == 'n'
• 'k' > 'o'
• '3' > '2'
• 'A' <= 'a'
• ch >= 'a' && ch <= 'z'
• char-Variablen können auch spezielle Zeichen enthalten. Für die Gebräuchlichsten gibt es
spezielle Escape-Codes. Zudem kann jedes Unicode-Zeichen über seinen Unicode angesprochen
werden:
• '\n'
Neue Zeile
• '\t'
Tabulator
• '\r'
Carriage return (Wagenrücklauf)
• '\f'
Form Feed (neue Seite)
• '\"'
Anführungszeichen
• '\''
Apostroph
• '\\'
Backslash '\'
• '\uxxxx'
Unicode-Zeichen mit Hexcode xxxx
Bsp. '\u0040'
'@'
PPG.1.7.fm
112
9.3.4
Implizite Umwandlung von einfachen Datentypen
• Implizite Typumwandlung
• Regel:
Bei Operationen mit gemischten Datentypen wird jeweils der Wert mit dem niedrigeren
Datentyp in den höheren Datentyp des anderen umgewandelt.
• Die automatische Umwandlung ist möglich, da die Wertebereiche der niedrigen Typen immer in
den Werterbereichen der höheren Typen enthalten sind.
• Bei der automatischen Umwandlung kann es jedoch zu Genauigkeitsverlusten kommen, zum
Beispiel bei der Umwandlung einer sehr grossen long-Zahl in eine float- oder doubleZahl.
• Die Typenhierarchie:
•
•
•
•
•
•
double
float
long
int
short
byte
höchster Typ
niedrigster Typ
• Beispiel:
int i;
float f;
f = i; ist gültig, da jede int-Zahl als float darstellbar ist (implizite Typenkonversion).
Die Umkehrung gilt nicht, da sehr grosse float-Zahlen nicht mehr als int darstellbar sind!
• Explizite Typumwandlung
• Dazu braucht es einen cast-Operator: ( Typ )
• Beispiel:
i = (int) f;
• wandelt float in int.
• Dabei wird nicht gerundet, sondern die Nachkommastellen werden abgeschnitten.
• Umwandlungen mit Datentyp char
• Eine char-Variable wird implizit (automatisch) in einen int oder long-Wert umgewandelt,
falls nötig. Dabei werden nur die niedrigsten 16 Bit belegt, der Rest ist 0.
• Für die Umwandlung von int- oder long-Werten in char-Werte braucht den expliziten TypeCast (char). Dabei werden ebenfalls nur die niedrigsten 16 Bit berücksichtigt.
9.3.5
Ein- und Ausgabe
• Zahlen müssen als Text (String) auf den Bildschirm ausgegeben und eingelesen werden z.B. via eine
Textzeile.
• Für die Umwandlung von Zahlen in Strings und umgekehrt existieren für alle ZahlenDatentypen Methoden in den entsprechenden Wrapper-Klassen.
• Eingabe von Integer und Long-Werten:
• Integer.parseInt(text) bzw. Long.parseLong(text)
• Bsp. :
TextField eingabe;
int zahl;
PPG.1.7.fm
113
String text;
text = eingabe.getText();
zahl = Integer.parseInt(text);
• Eingabe von float und double-Zahlen:
Genau gleich wie bei Integer-Zahlen mit den entsprechenden Methoden:
• Float.parseFloat(String text) bzw.
• Double.parseDouble(String text)
• Ausgabe von Zahlen:
Zahlen können entweder mit einer Klassenmethode der entsprechenden Wrapperklasse oder aber via
ein entsprechendes Zahlobjekt in den entsprechenden String umgewandelt werden:
• Wrapperklasse.toString(zahl);
• zahlObjekt.toString();
• Beispiel:
int zahl = 10;
Integer zahlObj = new Integer(zahl);
g.drawString(Integer.toString(zahl),10,20);
g.drawString(zahlObj.toString(),10,40);
• Die Umwandlung des Wertes eines einfachen Datentyps (und auch von Referenzdatentypen) in den
entsprechenden String geschieht automatisch, sobald der Wert an einen String angehängt wird:
int zahl = 20;
g.drawString("Resultat = "+zahl, 10,20);
ergibt auf dem Bildschirm „Resultat = 20“, ABER
g.drawString("Resultat = "+1+2, 10,20); ergibt „Resultat = 12“ !!
9.3.6
Ausnahmebedingungen
• Bei Rechnen mit einfachen Datentypen können unterschiedliche Ausnahmebedingungen auftreten.
• Bei byte, short, int, long:
• Der Wert kann ausserhalb des erlaubten Wertebereichs liegen
Dies führt zu einem Underflow bzw. Overflow
• Programm bricht in diesem Fall nicht ab, sondern fährt weiter!
Der Wertebereich des Datentyps wird einfach periodisch wiederholt:
Beispiel:
short s = 32767;
s = s + 1;
// s = -32768!!
• Massnahmen:
• Datentyp so wählen, dass nie eine Ausnahmebedingung eintritt.
• Ausnahmebedingung abfangen (wird später behandelt)
PPG.1.7.fm
114
• Division durch 0:
• bei byte, short, int, long:
Es tritt eine Arithmetic-Exception auf ( Programmabbruch)
• bei float, double:
• Berechnungen mit reellen Zahlen ergeben in Java nie eine Exception. Stattdessen werden
spezielle Konstanten in den Klassen Double und Float definiert:
– POSITIVE_INFINITY
plus unendlich
– NEGATIVE_INFINITY
minus unendlich
– NaN
keine Zahl (z.B. 0.0/0.0 NaN)
• Tabelle der möglichen Resultate (x,y sind float- bzw. double-Zahlen):
x
y
x / y
x % y
endlich (!= 0)
± 0.0
± infinity
NaN
endlich
± infinity
± 0.0
x
± 0.0
± 0.0
NaN
NaN
± infinity
± endlich
± infinity
NaN
± infinity
± infinity
NaN
NaN
Tabelle 9: Resultate bei float- und double-Operationen
• Ob ein Wert unendlich oder eine ungültige Zahl geworden ist, kann getestet werden mit den
Klassenmethoden:
boolean Float.isInfinite(float f) oder
boolean Double.isInfinite(double d)
und
boolean Float.isNaN(float f) oder
boolean Double.isNaN(double d)
• Ist ein Wert unendlich oder eine ungültige Zahl geworden, kann trotzdem damit
weitergerechnet werden.
• Diese Ausnahmewerte können auch mit anderen Zahlen verglichen werden.
Alle Vergleichsoperatoren (<,>,==, ...) von NaN mit einer Zahl oder sich selbst
ergeben false, ausser der Operator !=. Er gibt immer true.
• Es gibt verschiedene Wege, um mit diesen Ausnahmesituationen umzugehen:
• Man kann dafür sorgen, dass die Ausnahme gar nie eintritt (Wahl der Datentypen, Überprüfung
der Benützereingaben).
• Man kann nachträglich testen, ob das Resultat NaN oder ±infinity ist.
9.4
Referenzdatentypen
• Neben der einfachen Datentypen gibt es in Java die sogenannten Referenzdatentypen.
• Folgende Datentypen sind Referenzdatentypen in Java: Klassen und Arrays.
• Bei einfachen Datentypen bezeichnet der Variablenname den Speicherplatz, wo der Wert der
Variablen gespeichert ist.
• Java behandelt diese Daten als Wert („by value“), d.h., bei Zuweisungen und Methodenaufrufen
PPG.1.7.fm
115
wird immer der Wert der Variablen übergeben.
• Beispiel:
int b = 7, a = 5;
b = a;
• Bei Referenzdatentypen hingegen bezeichnet der Variablenname den Speicherplatz, wo die Adresse
der eigentlichen Daten abgespeichert ist.
• Man sagt deshalb auch, dass in der Variablen nur eine Referenz auf die Daten gespeichert ist.
• Wird deshalb eine Variable eines Referenzdatentyps, z.B. einer Klasse, deklariert, so wird nur
Speicherplatz für die Adresse der Daten, d.h. die Referenz auf das eigentliche Objekt, angelegt.
• Bevor nun mit dem Objekt gearbeitet werden kann, muss es zuerst erzeugt werden. Vor der
Erzeugung des Objekts enthält die Variable noch keine gültige Referenz (null).
• Bei der Erzeugung des Objekts wird der benötigte Speicherplatz irgendwo im Arbeitsspeicher
reserviert und die Startadresse dieses Speicherbereichs in den Speicherplatz für die Referenz
abgelegt.
• Beispiel: Button
• Deklaration
Button butA = null;
• Erzeugung
butA = new Button("A");
// Button A heisst jetzt „A“
• Java behandelt Referenzdatentypen ebenfalls „by value“, d.h. er wird bei Zuweisungen und
Methodenaufrufen jeweils eine Kopie des Wertes übergeben. Dieser Wert ist nun aber eine
Referenz, d.h. die Adresse der Daten. Bei Zuweisungen und Methodenaufrufen wird also nur die
Referenz kopiert, die Daten selbst nicht.
• Das hat zur Folge, dass nach einer Zuweisung butB = butA; beide Variablen butA und butB
Referenzen auf dieselben Daten darstellen:
butB = butA;
PPG.1.7.fm
116
• Somit bewirkt jede Änderung beim Button A auch dieselbe Änderung beim Button B, da es ja
derselbe Button ist, auf den die Referenzen butA und butB zeigen.
butB.setLabel("B");
// butB und butA heissen jetzt „B“!
• Übergabe eines Referenzdatentyps an eine Methode:
Auch bei der Übergabe einer Variablen eines Referenzdatentyps an eine Methode als Argument wird
nur der Wert der Variablen, d.h., die Referenz übergeben.
• Dementsprechend arbeitet die Methode auf den Originaldaten nicht auf einer Kopie!
• Jede Änderung der Daten innerhalb der Methode bedeutet somit gleichzeitig die Änderung der
entsprechenden Daten ausserhalb der Methode.
• Auch bei der Rückgabe von Daten eines Referenzdatentyps aus einer Methode wird nur die
Referenz der Daten zurückgegeben.
• Beispiel:
public void paint(Graphics g){
Button butA = null, butC = null;
butA = new Button("A");
butC = changeButton(butA);
// Button A heisst jetzt „A“
// Button A und C heissen jetzt „C“
}
private Button changeButton(Button but){
but.setLabel("C"); // Button but heisst jetzt „C“
return but;
}
• Um effektiv eine Kopie der Daten eines Referenzdatentyps zu erhalten, müssen spezielle Methoden
dieser Referenzdatentypen aufgerufen werden.
9.5
Bibliothek der math. Funktionen
• Java stellt eine Klasse mit den wichtigsten mathematischen Funktionen und Konstanten zur
Verfügung Math
• Diese wird automatisch importiert, muss also bei den import-Anweisungen nicht aufgeführt
werden.
• Wo nötig sind die Funktionen in mehreren Versionen für die verschiedenen Datentypen (float,
double, int, long) verfügbar.
• Die wichtigsten Konstanten und Methoden sind:
PPG.1.7.fm
117
Math.E
Math.PI
Konstante e
Konstante pi
double ceil(double x)
double floor(double x)
int round(float x)
long round(double x)
double rint(double x)
Aufrunden auf nächst grössere ganze Zahl
Abrunden auf nächst kleinere ganze Zahl
Math. Runden auf nächste ganze Zahl.
double exp(double x)
double log(double x)
ex
natürlicher Logarithmus ln x
double pow(double x, double y)xy
double sin(double x)
Sinus-Funktion (x in Bogenmass)
double cos(double x)
Cosinus-Funktion (x in Bogenmass)
double tan(double x)
Tangens-Funktion (x in Bogenmass)
double asin(double x)
Arc-Sinus-Funktion (Ergebnis in Bogenmass)
double acos(double x)
Arc-Cosinus-Funktion (Ergebnis in Bogenmass)
double atan(double x)
Arc-Tangens-Funktion (Ergebnis in Bogenmass)
double random()
Zufallszahl r, mit 0 <= r < 1
double sqrt(double x)
Quadratwurzel von x
typ abs(typ x)
Absolutbetrag
(typ: int, long, float, double)
typ min(typ x, typ y)
Minimum von x und y
typ max(typ x, typ y)
Maximum von x und y.
double atan2(double x, double y)konvertiert kartesische Koordinaten in die Phase
der entsprechenden polaren Koordinaten
double toDegrees(double x)
konvertiert Bogenmass in Grad
• Die Methoden und Konstanten sind alle als static deklariert und müssen deshalb via
Klassenname aufgerufen werden, als z.B.
double x, y;
x = Math.sin(0.5);
x = 3 * Math.PI;
PPG.1.7.fm
118
10
Array
10.1
Ziele
•
•
•
•
Sie können Zweck und Aufbau von Array-Datentypen erklären.
Sie können einen eindimensionalen Array korrekt deklarieren.
Sie können mit eindimensionalen Arrays umgehen (Initialisierung, Zuweisung, Parameterübergabe).
Sie setzen eindimensionale Arrays situationsgerecht ein.
10.2
Einführung
• Bisher haben wir nur einzelne isolierte Variablen behandelt:
int x, zahl;
Konto konto1;
• Probleme:
• Für jede Variable muss ein neuer Name deklariert werden.
• Die Anzahl benötigter Variablen muss bereits bei der Programmentwicklung bekannt sein.
• Häufig möchte man mehrere Zahlen oder Objekte als Gruppe behandeln:
• Beispiel: Passagiere pro Fahrt bei einer Seilbahn:
Sonntag:
Fahrt
1
2
3
4
5
6
7
8
Anzahl
Passagiere
1
3
20
100
90
102
80
100
Fahrt
1
2
3
4
5
6
7
8
Anzahl
Passagiere
10
17
100
100
10
30
0
0
• Montag:
...
PPG.1.7.fm
119
• Merkmale dieser Zahlen:
• Weitere Beispiele:
• Tageseinnahmen an einer Kasse
• Klassenliste
• Farbe aller Pixel des Bildschirms
• Für diese Fälle gibt es einen neue Sorte von Datentypen
Arrays
• Datentyp Array (Feld):
• Ein Array entspricht einer Tabelle mit nur einer Zeile
• Der Variablenname bezeichnet die ganze Tabelle.
• Ein einzelner Eintrag wird Element, Komponente genannt.
• Die Position des Elements innerhalb Tabelle wird durch den Index angegeben.
• Merkmale eines Arrays:
• Alle Daten eines Arrays müssen den gleichen Datentyp haben.
• Ein einzelnes Element wird durch seinen Index adressiert.
• Die Position eines Elementes ist nicht im Computer gespeichert, sondern wird aus dem Index
und der Länge des Elementdatentyps errechnet.
10.3
Arrays in Java
• Array-Datentypen in Java sind Referenzdatentypen wie die Klassen.
• Der Umgang mit Arrays ist daher sehr ähnlich wie der Umgang mit Objekten (Deklaration,
Erzeugung, Löschen, etc.).
• Deklaration eines Arrays:
Datentyp[] Arrayname;
PPG.1.7.fm
120
•
•
•
•
Datentyp: Datentyp der einzelnen Elemente
Der Array existiert nach der Deklaration noch nicht, erst der Variablenname.
Die Anzahl Elemente im Array sind ebenfalls noch nicht bestimmt.
Beispiel:
int[] fahrtenAmSo;
• Erzeugung des Arrays:
fahrtenAmSo = new int[8];
• Die obige Anweisung reserviert Speicher für einen Array mit 8 Elementen vom Typ int
• allgemein:
Arrayname = new Datentyp [Arraygrösse];
• Beachten Sie:
Das 1. Element eines Arrays in Java hat immer den Index 0.
• Aufgabe 1:
• Deklarieren und erzeugen Sie je einen Array für:
• die sechs Lottozahlen
• die Anzahl Tage jedes Monats im Jahr
• die tägliche Sonnenscheindauer in Stunden für einen Monat
• Lösung:
• Initialisierung:
• Array-Elemente werden in Java bei der Erzeugung immer auf die Default-Werte gesetzt.
• Für int-Arrays ist der Default-Wert 0.
• Möchte man die Werte eines Arrays selber mit Werten initialisieren, gibt es folgende
Möglichkeiten:
• Jedes Element einzeln:
fahrtenAmSo[0] = 0;
fahrtenAmSo[1] = 0;
...
fahrtenAmSo[7] = 0;
PPG.1.7.fm
121
• Besser: Mit for-Schleife:
for (int i=0; i<8; i++){
fahrtenAmSo[i] = 0;
}
• Direkt bei der Deklaration des Arrays:
int[] fahrtenAmSo = {0,0,0,0,0,0,0,0};
deklariert und erzeugt einen Array mit 8 Integer-Elementen und setzt die Elemente auf 0.
10.4
Umgang mit Array-Elementen
• Ein Element eines Arrays verhält sich genau gleich wie eine Variable vom entsprechenden
Datentyp:
• Zuweisung, Eingabe, Ausgabe, Argument bei Methodenaufruf, etc.
• Zugriff auf das einzelne Element
• via Index
• 1. Element hat Index 0!
• Für die Berechnungen mit Arrays werden häufig for-Schleifen benötigt:
• Beispiel : Array mit Zweierreihe
int[] zweierReihe;
final int ANZAHL = 100;
zweierReihe = new int[ANZAHL];
for (int i = 1; i <= ANZAHL; i++){
zweierReihe[i-1] = i*2;
}
• Anzahl Elemente (Länge) eines Arrays
• Die Länge eines Arrays wird erst beim Erzeugen festgelegt.
• Sie kann danach nicht mehr geändert werden.
• Die Anzahl Elemente in einem Array ist in einer speziellen Instanzvariable des Array-Objekts
gespeichert:
arrayname.length
10.5
Umgang mit dem Array als Ganzem
• Da Arrays Java-Objekte sind, werden sie ebenfalls als Referenz übergeben.
• Beispiel: Berechnung der Summe der Elemente eines beliegigen Arrays
public int summe(int[] arr){
int total = 0;
for (int i =0; i < arr.length; i++){
total = total + arr[i];
}
return total;
}
Programm 17 : Methode zur Berechnung der Summe der Elemente eines int-Arrays
PPG.1.7.fm
122
• Beachten Sie:
• Bei der Parameterdeklaration im Methodenkopf muss die Länge des übergebenen Arrays
nicht spezifiziert werden. Es können beliebig grosse Arrays übergeben werden.
• Die Methode kann die Länge des Arrays selber aus der Instanzvariablen arr.length
herauslesen.
• Aufruf der Methode summe auf Seite 122:
int[] reihe = {1,2,3,4};
int sum;
sum = summe(reihe);
• Aufgabe 2:
Schreiben Sie eine Methode, die das grösste Element in einem beliebig langen Array von ganzen
Zahlen zurückgibt. Die Methode soll nur den Wert des grössten Elementes zurückgeben.
Für Fortgeschrittene: Wie bestimmen Sie den Index des grössten Elementes?
• Lösung:
PPG.1.7.fm
123
10.6
•
•
•
•
Arrays von Objekten
Arrayelemente können nicht nur einfache Datentypen sein, sondern auch Objekte.
Im Array selbst stehen nur die Referenzen auf die Objekte, nicht die Objekte selbst.
Jedes Element (Objekt) im Array muss in diesem Fall vor der Verwendung erzeugt werden.
Beispiel 1: Array von Scrollbars
Scrollbar[] sliders;
sliders = new Scrollbar[10];
sliders[0] = new Scrollbar(Scrollbar.VERTICAL, 50, 1, 0, 100);
• Deklaration und Erzeugung des Arrays:
Scrollbar[] sliders;
sliders = new Scrollbar[10];
• Initialisierung:
for (int i=0; i < sliders.length; i++){
sliders[i] = null;
}
• Erzeugen des i-ten Scrollbars:
sliders[i] = new Scrollbar(Scrollbar.VERTICAL, 50, 1, 0, 100);
• Aufruf einer Methode des i-ten Scrollbars:
int wertI;
wertI = sliders[i].getValue();
PPG.1.7.fm
124
• Beispiel 2: Array von Ziffern-Buttons
Wir möchten 10 Buttons für die zehn Ziffern erzeugen und zum gegebenen Applet hinzufügen:
Button[] ziffButtons = new Button[10];
for (int i = 0; i < 10; i++){
ziffButtons[i] = new Button(""+i);
add(ziffButtons[i]);
ziffButtons[i].addActionListener(this);
}
• Beispiel 3: Array von Strings
String[] arbeitstage = {"Montag", "Dienstag", "Mittwoch",
"Donnerstag", "Freitag"};
int tag = 2;
String tagname;
tagname = arbeitstage[tag];
• Frage:
Welchen Index hat der Dienstag?
• Suchen eines Elementes
• Beispiel: Methode, die den Index eines bestimmten Wochentags sucht.
public int sucheTag(String str){
int tagNr = -1;
for (int tag = 0; tag < arbeitstage.length; tag++)
if (arbeitstage[tag].equals(str)){
tagNr = tag;
}
}
return tagNr;
}
Programm 18 : Methode, die den Index eines Wochentags zurückgibt.
• Dies entspricht einer linearen Suche, da der Array von vorne bis hinten durchsucht wird. Es
gibt natürlich wesentlich effizientere Suchmethoden, für solch kleine Arrays spielt jedoch die
Effizienz keine grosse Rolle.
PPG.1.7.fm
125
• Aufgabe 3:
Schreiben Sie die Methode sucheTag mit einer do-while-Schleife. Diese soll abbrechen,
sobald der gewünschte Tag gefunden ist. Falls der Tag nicht existiert, soll sie –1 ausgeben.
• Lösung
10.7
Programmierfallen
• Der gewählte Index liegt ausserhalb des erlaubten Bereichs.
• Ein Array wird verwendet, bevor er erzeugt wird.
PPG.1.7.fm
Ergibt Runtime-Fehler.
Ergibt Nullpointer-Exception
126
11
Zweidimensionale Arrays
11.1
Ziele
• Sie können den internen Aufbau eines zweidimensionalen Arrrays in Java anhand einer Grafik
erklären
• Sie können zweidimensionale Arrays korrekt deklarieren.
• Sie können mit zweidimensionalen Arrays richtig umgehen (Initialisierung, Zuweisung,
Parameterübergabe, Rückgabewert).
• Sie setzen zweidimensionale Arrays situationsgerecht ein.
11.2
Einführung
• Beispiel: Umsatzzahlen eines Geschäftes mit 3 Filialen für eine Woche
• Diese können als Tabelle dargestellt werden:
Tag
Montag
Dienstag
Mittwoch
Donnerstag
Freitag
Samstag
Sonntag
Zürich
76
68
85
65
43
100
5
Bern
41
33
36
35
28
49
0
Basel
10
21
13
14
17
15
0
Filiale
• Jede Zeile entspricht den Umsatzzahlen einer Filiale für die ganze Woche.
• Jede Spalte entspricht den Umsatzzahlen für einen Tag in den verschiedenen Filialen.
• Gemeinsames Merkmal der Zahlen dieser Tabelle: Alle Einträge sind vom gleichen Datentyp.
• In Java gibt es dafür einen speziellen Datentyp:
den zweidimensionalen Array
• Zweidimensionale Arrays werden häufig gebraucht, z.B.:
• allgemein Tabellen
• Matrizenrechnung
• Darstellung von Bildern
• Schachbrett
11.3
Zweidimensionale Arrays in Java
• Wir wissen vom eindimensionalen Array:
• Er stellt eine Sammlung von Elementen des gleichen Datentyps dar.
• Diese Elemente können auch Objekte sein.
• Arrays selber sind ebenfalls Objekte.
• Die Elemente eines Arrays können selbst auch wieder Arrays sein.
• Zweidimensionaler Array
• In Java wird deshalb ein zweidimensionaler Array als Array von Arrays implementiert.
• Die Elemente einer Zeile stehen dabei wie beim eindimensionalen Array hintereinander im
Speicher.
• Aufeinanderfolgende Zeilen müssen jedoch nicht hintereinander im Speicher stehen.
PPG.1.7.fm
127
• Mehrdimensionale Arrays
• Auf die gleiche Weise können Arrays mit beliebig vielen Dimensionen aufgebaut werden als
Array von Arrays von Arrays .
• Beispiel: Zweidimensionaler Array für die Umsatzzahlen von oben:
int[][] umsatz;
umsatz = new int [3][7];
11.4
Deklaration und Erzeugung
• Deklaration:
• allgemein:
Datentyp [][] Arrayname;
• Datentyp: Datentyp der einzelnen Elemente
• Array existiert nach der Deklaration noch nicht.
• Die Grösse des Arrays ist ebenfalls noch nicht bestimmt.
• Erzeugung des Arrays:
• Arraynname = new Datentyp [AnzahlZeilen][AnzahlSpalten];
• Tipp: Verwenden Sie Variable oder symbolische Konstante für Arraygrössen, nicht numerische
Konstante.
• Beispiel 1: Tagesumsätze einer Woche in 7 verschiedenen Filialen
final int ANZTAGE = 7;
final int ANZFILIALEN = 7; //zufällig gleich gross wie ANZTAGE
int[][] umsatz;
umsatz = new int [ANZFILIALEN][ANZTAGE]; //
PPG.1.7.fm
besserer Überblick
128
• Beispiel 2: Schachbrett
String[][] schachbrett;
final int GROESSE = 8;
schachbrett = new String[GROESSE][GROESSE];
• Beispiel 3: Kinoplätze
boolean[][] kinoplatz;
int anzReihen = 10; anzPlaetzeProReihe = 20;
kinoplatz = new boolean[anzReihen][anzPlaetzeProReihe];
• Arraygrenzen müssen nicht immer Konstanten sein, sondern es können auch beliebige GanzzahlAusdrücke mit Variablen sein.
• Länge der verschiedenen Dimensionen des zweidimensionalen Arrays:
• Die Anzahl Zeilen stehen in der Variablen Arrayname.length
int anzahlZeilen = umsatz.length;
• Da jede Zeile des zweidimensionalen Arrays selbst wieder ein Array ist, besitzt jede Zeile eine
eigene length-Variable, die die Länge der Zeile angibt. Falls die Anzahl Spalten in jeder Zeile
gleich sind, kann irgend eine Zeile verwendet werden, um die Anzahl Spalten herauszufinden:
int anzahlSpalten = umsatz[0].length
• Randbemerkung: In Java müssen die Zeilen eines zweidimensionalen Arrays nicht unbedingt
gleich viele Spalten aufweisen.
11.5
Initialisierung
• Wie eindimensionale Arrays müssen auch mehrdimensionale Arrays initialisiert werden!
1. Möglichkeit: Direkt bei Deklaration
int [][] tabelle = {{1,0,1},{0,1,0}};
erzeugt einen Array mit 2 Zeilen und 3 Spalten und initialisiert ihn mit den entsprechenden
Werten.
2. Möglichkeit: Innerhalb des Programmcodes, normalerweise mit einer oder mehreren forSchleifen.
• Aufgabe:
• Schreiben sie ein kleines Programmstück, das den Array umsatz auf 0 initialisiert. Folgende
Deklarationen sind gegeben:
final int ANZTAGE = 7;
final int ANZFILIALEN = 7;
int[][] umsatz = new int [ANZFILIALEN][ANZTAGE];
PPG.1.7.fm
129
• Lösung:
11.6
Umgang mit Array-Elementen
• Ein einzelnes Element eines Arrays verhält sich wie eine Variable vom gleichen Typ.
• Für den Zugriff auf einzelnes Element des zweidimensionalen Arrays braucht es 2 Indices:
• allgemein: Arrayname[zeilenindex][spaltenindex]
• Beispiel:
umsatz[2][3] bezeichnet das Element in der 3. Zeile und 4. Spalte des Arrays umsatz.
• Beachten Sie auch hier:
Das 1. Element in der 1. Zeile eines zweidimensionalen Arrays hat die Indices [0][0]
• Die Indices selbst können auch Ausdrücke mit Variablen sein.
• Da in Java ein zweidimensionaler Array als Array von Arrays implementiert ist, kann auf eine Zeile
des Arrays auch als Ganzes zugegriffen werden.
Beispiel:
umsatz[2]
11.7
Dies bezeichnet die Zeile 3 vom zweidimensionalen Array umsatz
Dies ist ein eindimensionaler Array mit 7 Elementen.
Übergabe von Arrays als Parameter
• Auch zweidimensionale Arrays werden als Referenz übergeben.
• Beispiel 1:
Methode für die Berechnung der Summe über alle Elemente eines beliebigen zweidimensionalen
Arrays:
public int sum(int[][] arr){
int total = 0;
for (int row = 0; row < arr.length; row++){
for (int col = 0; col < arr[row].length; col++){
total = total + arr[row][col];
}
}
return total;
}
Programm 19 : Methode, die die Summe über einen 2-dim. Array berechnet
PPG.1.7.fm
130
• Bei der Parameterdeklaration müssen die Grenzen des Arrays nicht angegeben werden.
• Es können somit beliebig grosse Arrays mit der Methode sum verarbeitet werden.
• Die Arraygrenzen in den verschiedenen Dimensionen stehen in den jeweiligen length-Variablen.
• Beispiel eines Aufrufs der Methode sum :
int total;
int[][] umsatz = new int [4][7];
...
total = sum(umsatz);
• Beispiel 2:
Die Methode createZeroMatrix initialisiert einen bliebigen zweidimensionalen Array mit
Nullen:
public int[][] createZeroMatrix(int rows, int cols){
int[][] matrix = new int[rows][cols];
for (int row = 0; row < rows; row++){
for (int col = 0; col < cols; col++){
matrix[row][col] = 0;
}
}
return matrix;
}
Programm 20 : Methode, die einen 2-dim. Array erzeugt und mit 0 initialisiert.
• Beispiel eines Aufrufs der Methode createZeroMatrix:
int[][] mymatrix = createZeroMatrix(3,5);
Dieser Aufruf erzeugt einen 2-dim. Array mit 3 Zeilen à 5 Spalten gefüllt mit Nullen.
11.8
Beispielprogramm Sales
• Das Programm Sales Seite 134 stellt eine Tabelle für das Eintragen der Tagesumsätze
verschiedener Filialen (siehe Figur 37) zur Verfügung. Der Benützer gibt beim Textfeld die
gewünschte Umsatzzahl ein. Dann kann er mit der Maus auf ein Feld klicken, wo dann der
eingegebene Umsatz eingetragen wird.
• Um die Eingabe per Mausklick zu unterstützen, implementiert Sales einen MouseListener :
• Dazu müssen 5 Methoden deklariert werden
• mouseClicked(MouseEvent e)
• mouseReleased(MouseEvent e)
• mousePressed(MouseEvent e)
• mouseEntered(MouseEvent e)
• mouseExited(MouseEvent e)
• Die Position des aktuellen Cursors beim Betätigen der Maus erhält man jeweils mit den zwei
Methoden e.getX() und e.getY()
PPG.1.7.fm
131
Figur 37: Bildschirmdarstellung des Programms Sales
• Der Programmcode des Programms Sales:
/*
* Klasse Sales verwaltet die Tagesumsätze einer Woche
* von 3 Filialen
*
*/
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Sales extends Applet
implements ActionListener, MouseListener {
private final int ANZFILIALEN = 3;
private final int ANZTAGE = 7;
private final int XSTART = 20, YSTART = 60;
private final int BOXHEIGHT = 20, BOXWIDTH = 40;
private TextField value = null;
private int[][] data = new int[ANZFILIALEN][ANZTAGE];
private int rowIndex, colIndex;
private int newValue = 0;
private int sum = 0;
PPG.1.7.fm
132
public void init() {
Label l = new Label("Umsatz eingeben und Felder anklicken");
add(l);
value = new TextField("0",8);
add(value);
value.addActionListener(this);
addMouseListener(this);
// Umsätze initialisieren:
for(int filiale = 0; filiale < ANZFILIALEN; filiale++){
for(int tag = 0; tag < ANZTAGE; tag++){
data[filiale][tag] = 0;
}
}
}
public void paint(Graphics g) {
for(int row = 0; row < data.length; row++) {
for(int col = 0; col < data[0].length; col++) {
int x = XSTART + col * BOXWIDTH;
int y = YSTART + row * BOXHEIGHT;
g.drawRect(x, y, BOXWIDTH, BOXHEIGHT );
g.drawString(Integer.toString(data[row][col]), x,
y + BOXHEIGHT*3/4);
}
}
calculateSum();
g.drawString("Total = " + sum, 100, 150);
}
public void actionPerformed(ActionEvent event) {
if (event.getSource() == value) {
newValue = Integer.parseInt(value.getText());
repaint();
}
}
PPG.1.7.fm
133
public void selectComponent( int x, int y) {
rowIndex = (y - YSTART)/BOXHEIGHT;
colIndex = (x - XSTART)/BOXWIDTH;
if (rowIndex >= 0 && rowIndex < data.length &&
colIndex >= 0 && colIndex < data[0].length){
data[rowIndex][colIndex] = newValue;
}
}
private void calculateSum() {
sum = 0;
for (int row=0; row < data.length; row++){
for (int col = 0; col < data[0].length; col++){
sum = sum + data[row][col];
}
}
}
//MouseListener implementieren - alle 5 Methoden notwendig
public void mouseClicked (MouseEvent event){
int x = event.getX();
// Position des Cursos abfragen
int y = event.getY();
selectComponent(x, y); // entspr. Feld selektieren
repaint();
}
public void mouseReleased (MouseEvent e){
}
public void mousePressed (MouseEvent e){
}
public void mouseEntered (MouseEvent e){
}
public void mouseExited (MouseEvent e){
}
}
Programm 21 : Programm Sales
PPG.1.7.fm
134
11.9
Aufgabe
• Schreiben Sie eine Methode, die die Elemente einer beliebigen reellen Matrix mit einer Konstanten
multipliziert. Dabei soll die gegebene Matrix nicht verändert werden.
• Lösung:
PPG.1.7.fm
135
12
Zeichenketten (Strings)
12.1
Ziele
•
•
•
•
•
Sie können einem Laien erklären, was ein String ist.
Sie kennen die wichtigsten Methoden für die String-Verarbeitung.
Sie können mit Strings praktisch umgehen.
Sie können mit einfachen regulären Ausdrücken umgehen.
Sie setzen die Klasse StringTokenizer situationsgerecht ein.
12.2
Einführung
• Zeichenketten (Strings) werden sehr häufig beim Programmieren benötigt, sei es für die
Kommunikation mit dem Benützer, aber auch für die Kommunikation der Computer untereinander.
• Beispiele für die Verwendung von Zeichenketten:
• Meldungen ausgeben
• Benutzereingaben einlesen
• Textdateien lesen und schreiben
• Datei- und Verzeichnisnamen, URLs
12.3
Strings
• Eine Zeichenkette ist eine Folge von einzelnen Zeichen:
• In Java werden Zeichenketten als Objekte behandelt (nicht als Array von Character wie in C!)
• Ein String kann beliebig viele Zeichen enthalten.
• Jedes Zeichen im String hat einen Index (wie bei einem Array).
• Das 1. Zeichen eines Strings hat den Index 0.
• Es gibt drei String-Klassen in Java:
• String
• Diese Klasse ist für Zeichenketten vorgesehen, die nicht oder kaum editiert werden.
• Bei jeder Änderung eines Strings wird ein neues String-Objekt erzeugt.
• Methoden, die einen String als Argument übergeben bekommen, arbeiten ebenfalls immer auf
einer Kopie des Original-Strings.
• Die Klasse wurde ab JDK-Version 1.4 stark erweitert, unter anderem mit regulären
Ausdrücken.
• StringBuilder und StringBuffer
• Diese Klassen werden für Zeichenketten gebraucht, die häufig geändert werden müssen.
• Die Methoden von StringBuilder und StringBuffer ändern direkt den gegebenen String. Der Unterschied zwischen StringBuilder und StringBuffer ist der,
dass die Methoden von StringBuffer synchronisiert (synchronized) sind, die
Methoden von StringBuilder nicht, diese laufen dafür schneller.
• Im Folgenden wird nur die Klasse String betrachtet.
PPG.1.7.fm
136
12.4
Rekapitulation zur String-Klasse
• Deklaration eines Strings:
String stringName [= "Zeichenfolge"];
• Beispiele:
• String name = "Koller";
• String str = "";
// leerer String
• String-Literale
werden in doppelte Anführungszeichen gesetzt. Bsp.: "Dies ist eine Zeichenkette"
• Zuweisung zu einer String-Variablen:
str = name;
Kopiert nur die Referenz, so dass str und name jetzt auf dasselbe String-Objekt zeigen.
• Umwandlung einer Zahl in einen String
• implizit:
int zahl = 123;
String str = "Zahl = " + zahl;
// zahl wird automatisch in einen String
// umgewandelt
• explizit:
str = Integer.toString(zahl);
• Vergleichen von zwei Strings str1 und str2:
String str1 = "Hallo";
String str2 = str1 + "";
• str1 == str2
vergleicht nur die Referenzen auf die String-Objekte, nicht den
Inhalt! Resultat ist (normalerweise) false auch bei
gleichlautenden Strings
• str1.equals(str2);vergleicht, ob String str1 gleich ist wie String str2.
• Array von Strings:
String[] staedte = new String[10];
staedte[0] = "Los Angeles";
staedte[1] = "Zürich";
...
Zur Erinnerung: Strings in einem Array müssen nicht gleich lang sein. Es werden ja nur die
Referenzen auf die Strings im Array gespeichert. Die sind alle gleich lang.
• Verwendung von speziellen Zeichen innerhalb von Strings:
Es können die gleichen Escape-Codes verwendet werden wie bei Characters: \n, \t, \uxxxx, ...
(\n, \t funktionieren allerdings nicht mit drawString, da drawString pixelorientiert ist
und deshalb keine Zeilenumbrüche und Tabulatoren kennt.)
PPG.1.7.fm
137
12.5
Methoden der Klasse String
• Für den Vergleich von Strings:
Es seien im Folgenden die zwei Strings str1 = "Anna" und str2 = "anna" gegeben.
• boolean equals(String str)
vergleicht, ob zwei Strings gleich sind oder nicht. Dabei wird Gross- und Kleinschreibung
unterschieden.
str1.equals(str2) // -> false, da "Anna" nicht gleich "anna" ist
• boolean equalsIgnoreCase(String str)
vergleicht, ob zwei Strings gleich sind oder nicht, ohne Gross- und Kleinschreibung zu
unterscheiden.
str1.equalsIgnoreCase(str2) // -> true
• int compareTo(String str)
• Zeichenketten werden nach dem gleichen Prinzip wie Characters geordnet, d.h. nach dem
entsprechenden Unicode der Zeichen.
• Dabei hat das Zeichen links aussen das grösste Gewicht.
Beispiele:
– "a" ist vor "b"
– "Z" ist vor "a"
– "abcd" ist vor "acaa"
– "aa" ist nach "a"
• compareTo vergleicht zwei Strings nach obiger Ordnung und gibt zurück, ob der eine
String vor oder nach dem zweiten kommt.
Beispiel:
– int n = str1.compareTo(str2);
Resultat n:
0
:
str1 gleich str2
< 0 :
str1 vor str2
> 0 :
str1 nach str2
– Methodenaufruf auch mit String-Literalen möglich:
int n = "a".compareTo("b"); // n < 0
Beispiele:
– "alles".compareTo("all")
:
– "Alle".compareTo("all")
:
– "Von Tobel".compareTo("Vontobel") :
• Methoden für die Manipulation von Strings
• String replace(char alt, char neu)
• ersetzt in einem String ein bestimmtes Zeichen durch ein anderes. (alle Vorkommen des
Zeichens)
• Beispiel:
String neuStr = str1.replace('a','o');
– ersetzt alle 'a' durch 'o' im String str1
– gibt das Resultat in einem neuen String zurück
– Der String str1 bleibt dabei unverändert.
• String toLowerCase()
PPG.1.7.fm
138
• wandelt alle Grossbuchstaben eines Strings in Kleinbuchstaben um.
• Beispiel:
String neuStr, str = "Version 1.2";
neuStr = str.toLowerCase(); // neuStr = "version 1.2"
– gibt eine Kopie von String str zurück, wobei die Grossbuchstaben durch
Kleinbuchstaben ersetzt werden.
• String toUpperCase()
• wandelt alle Kleinbuchstaben in einem String in Grossbuchstaben um.
• Beispiel:
String neuStr, str1 = "Version 1.2";
neuStr = str1.toUpperCase(); // neuStr = "VERSION 1.2"
– gibt Kopie von str1 zurück, wobei Kleinbuchstaben durch Grossbuchstaben ersetzt
werden
• String trim()
• entfernt alle "white spaces" (Leerschläge, Tabulatoren, Zeilenumbrüche) am Anfang und
Ende eines Strings.
• Beispiel:
String neuStr, str1 = " \t alles weg \n";
neuStr = str1.trim(); // neuStr = "alles weg"
– gibt Kopie von str1 zurück, wobei "white spaces" (Leerschläge, Tabs, Zeilenumbrüche)
am Anfang und Ende des Strings entfernt worden sind.
• Methoden zur Untersuchung von Strings
• int length()
gibt die Anzahl Zeichen in einem String zurück.
• String substring(int start, int afterEnd)
• gibt den Substring zwischen dem Index start (inklusive) und afterEnd (exklusive, also „bis
und ohne ...“) eines Strings zurück.
• Beispiel:
String str1 = "nicht hängen";
String neuStr = str1.substring(6,12);
// neuStr = "hängen"
– Der String neuStr enthält das 6. bis zum 11. Zeichen von str1
Beachten Sie: Das erste Zeichen in einem String hat Index 0
– Das zweite Argument der Methode substring ist der Index des ersten Zeichens nach
dem gewünschten Substring.
• char charAt(int index)
• gibt das Zeichen an der Stelle index eines Strings zurück
• Rückgabetyp ist char
• int indexOf(String str, int idx) bzw. int indexOf(String str)
• sucht den String str im gegebenen String. Die Suche beginnt bei Index idx bzw. am
Anfang des Strings.
• Beispiel:
String str1 = "nicht hängen";
PPG.1.7.fm
139
int n = str1.indexOf("gen",5);
Resultat: n = 9
– Returnwert –1 heisst
gesuchter String wurde im gegebenen String nicht gefunden.
• int lastIndexOf(String str, int idx) bzw. int lastIndexOf(String str)
• sucht ebenfalls String str im gegebenen String. Die Suche geht aber von hinten nach vorne
• Returnwert –1 heisst gesuchter String wurde im gegebenen String nicht gefunden
• boolean endsWith(String str) bzw. boolean startsWith(String str)
• gibt zurück, ob der gegebene String mit str endet bzw. beginnt
12.6
Reguläre Ausdrücke
• Reguläre Ausdrücke sind eine Metasprache, mit der man effizient eine ganze Klasse von Strings
beschreiben kann.
• Damit kann man einfach nach Strings, die bestimmte Eigenschaften aufweisen, suchen und/oder sie
ersetzen.
• Beispiel:
• Im Programm Sales auf Seite 134 sollen alle int-Variablen durch long-Variablen ersetzt
werden. Ersetzt man nun einfach alle int-Vorkommen durch float, so wird z.B. auch
repaint() ersetzt durch repafloat() oder Integer.parseInt(...) durch
floateger.parsefloat(...)!
• Mit Hilfe von regulären Ausdrücken würde man das Ersetzen folgendermassen einschränken:
Ersetze alle Vorkommen von int gefolgt von mindestens einem Leerschlag durch float.
• Der dazu nötige reguläre Ausdruck, um nur diese Vorkommen von int zu finden, würde
folgendermassen aussehen: .*int[ ]+.*
• Um einen regulären Ausdruck zu spezifizieren, braucht es Metasymbole wie bei EBNF. Die
wichtigsten Metasymbole für reguläre Ausdrücke sind zusammen mit ihrer Bedeutung und
Beispielen in Tabelle 10 aufgelistet.
Metasymbol
Beispiel
Bedeutung
Menge der gültigen Literale
*
ax*b
0 oder mehrere x
ab, axb, axxb, axxxb,...
+
ax+b
1 oder mehrere x
axb, axxb, axxxb, ...
?
ax?b
x optional
ab, axb
|
a|b
a oder b
a, b
()
x(a|b)x
Gruppierung
xax, xbx
.
a.b
Ein beliebiges Zeichen
aab, acb, aZb, a[b, ...
[ ]
[abc]x
1 Zeichen aus einer Klasse
ax, bx, cx
[-]
[a-h]
Zeichenbereich
a, b, c, ..., h
Tabelle 10: Metasymbole für reguläre Ausdrücke
• Übungsbeispiele:
PPG.1.7.fm
140
Finden Sie für die in Tabelle aufgeführten regulären Ausdrücke alle gültigen Beispiele, die dem
regulären Ausdruck entsprechen.
Regulärer Ausdruck
Menge der gültigen Literale
a?b+
{ein, eine, einer}
a(x|y)?b*
Java-Bezeichner
alle ganze Zahlen
Tabelle 11: Ergänzen Sie obige Tabelle
• Die wichtigsten Methoden der Klasse String, die reguläre Ausdrücke verwenden:
• boolean matches(String regexp)
• gibt an, ob der String dem in regexp angegebenen regulären Ausdruck entspricht.
• Beispiel:
String text = "Hallo Welt", neu;
boolean passt;
passt
passt
passt
passt
=
=
=
=
text.matches("H.*W.*");
//
text.matches("H..o Wel?t");
//
text.matches("H[alo]* W[elt]+");//
text.matches("Hal+o Welt.+");
//
gibt
gibt
gibt
gibt
true zurück
false zurück
true zurück
false zurück
• String replaceAll(String regexp, String replaceStr)
• ersetzt alle Substrings des gegebenen Strings, die dem regulären Ausdruck regexp
entsprechen, durch replaceStr.
• Beispiel:
neu = text.replaceAll(„l+“, „LL“); // neu = „HaLLo WeLLt“
• String replaceFirst(String regexp, String replaceStr)
• wie replaceAll, ersetzt aber nur das erste Vorkommen von regexp im gegebenen String.
• Beispiel:
neu = text.replaceFirst(„l+“, „LL“); // neu = „HaLLo Welt“
• String[] split(String regexp)
• teilt den gegebenen String in Substrings auf, wobei Zeichenfolgen, die dem regulären
Ausdruck regexp entsprechen, als Grenzmarken interpretiert werden.
• Beispiele:
String[] teile = text.split("[ l]");
// teile[0] = "Ha", teile[1] ="", teile[2] = "o",
// teile[3] = "We", teile[4] = "t"
String[] teile = text.split(" l");
// teile[0] = "Hallo Welt"
PPG.1.7.fm
141
12.7
Klasse StringTokenizer
• Die Klasse StringTokenizer teilt einen gegebenen String in Substrings (Tokens) auf, wobei die
Tokens durch Grenzmarken voneinander getrennt sind.
• Beispiel:
String data = "4, 5, 6 2,8,, 100, 18";
String grenzMarken = " ,"; // Grenzmarken sind Kombinationen von
// " " und/oder ","
StringTokenizer tokens = new StringTokenizer(data, grenzMarken);
• Beliebige Kominationen von " " und "," (z.B.", ," werden zu einem einzigen Delimiter
zusammen gefasst. Der String data im obigen Beispiel zählt also nur 7 Tokens.
• Nach dem Erzeugen des StringTokenizer-Objekts tokens enthält dieses die Tokens des
analysierten Strings data.
• Folgende Methoden des StringTokenizer-Objekts stehen dann zur Verfügung:
• String nextToken()
gibt nächstes Token zurück
• boolean hasMoreTokens()
gibt true zurück, falls noch Tokens
vorhanden sind
• int countTokens()
gibt die Anzahl noch verfügbarer Tokens
zurück
• Beispiel:
int x = 20, y = 20;
while (tokens.hasMoreTokens()) {
g.drawString(tokens.nextToken(), x, y);
y = y + 15;
}
12.8
String als Parameter
• Strings sind Objekte
• Es werden deshalb ebenfalls eine Kopie der Referenz auf das String-Objekt übergeben.
• Aber:
• das übergebene String-Objekt kann nicht verändert werden
• sobald der übergebene String verändert wird, wird ein neues String-Objekt erzeugt.
• der neu erzeugte String muss dann mit return zurückgegeben werden.
• Beispiel:
private String wiederhole(String str){
str = str + str;
return str;
}
• str ist nicht eine Referenz auf den übergebenen String, sondern ein lokaler String, der eine
Kopie vom übergebenen String enthält.
PPG.1.7.fm
142
Beispiel: replace-Methode
12.9
• Die Methode replace im Codebeispiel 22 ersetzt in einem übergebenen String alle Substrings
from durch den Substring to.
String replace(String original, String from, String to){
String leftBit, rightBit;
int startSearch = 0;
int place = original.indexOf(from);
if (from.length() != 0){
while (place >= startSearch){
leftBit = original.substring(0, place);
rightBit = original.substring(place + from.length()),
original.length());
original = leftBit + to + rightBit;
startSearch = leftBit.length() + to.length();
place = original.indexOf(from, startSearch);
}
}
return original;
}
Programm 22 : Methode replace
• Aufgabe:
Studieren Sie im Detail den Ablauf der Methode replace.
Ihre Erklärungen:
PPG.1.7.fm
143
Herunterladen