Ich darf Sie herzlich begrüßen zur Programmieren-Vorlesung.
Wir hatten ja letzte Woche am Montag eine eher allgemeine Einführung,
da haben Sie die KIT-Hymne auch gehört und was die Professoren hier
sonst noch so machen gesehen, außer sich mit Informatik zu
beschäftigen.
Und heute jetzt wollen wir beginnen mit den eigentlichen Inhalten der
Vorlesung Programmieren.
Die Themen, die heute auf dem Programm stehen, sehen Sie schon hier
vorne projiziert.
Das ist einmal Objekte und Klassen, größerer Themenblock.
Und dann haben wir noch ein zweites Thema für heute vorgesehen, Typen
und Variablen.
Gut, dann fangen wir doch gleich an.
Erster Teil, Objekte und Klassen.
Was hat es damit auf sich?
Fangen wir gleich richtig an, gehen mitten rein.
Nehmen wir an, wir wollen anfangen, etwas zu programmieren.
Und zwar haben wir uns als Thema gesucht, ein Billiardspiel.
Wir wollen ein Billiardspiel programmieren.
Und jetzt überlegen wir uns, wie können wir da vorgehen?
Was machen wir als erstes, um dieses Billiardspiel auf den Computer zu
kriegen?
Und nehmen wir jetzt mal an, Ihre Idee ist, dass man wahrscheinlich
irgendwie simulieren muss, wie sich die Kugeln bewegen auf dem
Billiardtisch, was passiert, wenn die Kugeln zusammenstoßen, was
passiert, wenn die Kugeln gegen den Tisch prallen, dann ändert das
Ihre Bewegungsrichtung.
Und deshalb nehmen wir uns mal vor, als ersten Schritt, dass wir die
Simulation der Kugeln auf dem Tisch programmieren wollen.
Wie machen wir das jetzt?
Wie gehen wir dazu vor?
Als erstes brauchen wir wohl irgendwie einen Tisch.
Das heißt, wir müssen den irgendwie auf dem Computer repräsentieren.
Aber eben nicht nur den Tisch brauchen wir, oder gut, was ist da eine
wichtige Eigenschaft bei dem Tisch?
Wir müssen irgendwie die Größe wissen, um eben diese Kollisionen mit
dem Rand berechnen zu können.
Und eventuell auch andere Sachen, also wenn wir einen Pool-Billiard
haben, dann gibt es ja die Taschen, wo die Bälle reinfallen, die
könnte man eventuell bei dem Tisch noch mit berücksichtigen.
Aber wir bleiben mal bei diesem einfachen Modell hier und sagen, wir
haben einfach einen Pool-Billiardtisch, wo die Kugeln nicht darauf
verschwinden können.
Was müssen wir noch irgendwie für unser Programm umsetzen?
Wir müssen die Kugeln natürlich darstellen können.
Hier haben wir mal drei von denen.
Was für Eigenschaften brauchen wir?
Was müssen wir in unserem Programm über die Kugeln wissen?
Die haben so eine zeitliche Eigenschaft, weil die sich ja bewegen auf
dem Billiardtisch.
Und das heißt, wir müssen wissen für die Kugeln zu jedem Zeitpunkt die
Position, wo befinden die sich auf dem Tisch.
Und dazu habe ich hier jetzt schon mal so ein Koordinatensystem
eingezeichnet.
Irgendwie müssen wir die Position angeben können, bestimmen können,
messen können.
Und dann haben wir hier eben einfach auf dem Tisch mal so ein
zweidimensionales Koordinatensystem mit einer x- und einer y-Richtung.
Und die Position von den Bällen, die geben wir jetzt relativ zu diesem
Koordinatensystem an.
Also wir nehmen an, der Nullpunktursprung vom Koordinatensystem ist
links unten in der Ecke des Billiardtisches.
Und dann ist eben die Position, jetzt zum Beispiel von der blauen
Kugel, bestimmt durch die beiden Koordinaten px und py, also x- und y
-Koordinate.
Gut, damit könnten wir irgendwie die Position bestimmen.
Was wir auch noch brauchen ist, dass zu jedem Zeitpunkt die Kugel ja
auch eine Geschwindigkeit hat.
Also die bewegen sich normalerweise während des Spiels.
Das heißt, die Geschwindigkeit müssen wir irgendwie in unserem
Programm darstellen können und mit ihr umgehen können.
Und auch die Geschwindigkeit können wir jetzt wieder angeben mit so
einer Richtung und Betrag der Geschwindigkeit.
Also wie schnell bewegt er sich und in welche Richtung bewegt er sich,
auch das können wir wieder durch zwei Werte machen.
Geschwindigkeit in x- und in y-Richtung.
Und dann je nachdem, wie exakt wir dieses Billiardspiel modellieren
wollen, können wir eventuell noch zusätzliche Eigenschaften
berücksichtigen in der Kugel.
Also haben die Fe, drehen die sich in eine bestimmte Richtung, weil
das eben bei den Zusammenstößen auch eine Rolle spielen kann.
Wenn wir ein einfaches Modell erstmal wählen würden, was man
vielleicht im ersten Schritt machen würde, dann lassen wir das erstmal
weg mit dem Fe.
Was wir jetzt auch natürlich umsetzen müssen in unserem Programm ist,
bei diesem Bewegungsablauf, was passiert, wenn Kugeln zusammenstoßen,
wie bewegen die sich dann weiter.
Damit sind wir jetzt eigentlich schon bei einem Kernbegriff der
Programmierung, bei der objektorientierten Programmierung.
Und die befasst sich damit, wie man eben solche Dinge aus der Realität
auf dem Computer abbilden kann.
Ich habe das jetzt auch noch aufgeschrieben, Grundidee der
objektorientierten Programmierung ist, ein wichtiger Kerngedanke,
jedes Objekt der Realität hat ein virtuelles Gegenstück.
Das ist so eine ganz grundlegende Idee hier, also wir haben an dem
Beispiel, das wir schon gesehen, es gibt den Billiardtisch, ein Objekt
der Realität, und für dieses Objekt der Realität gibt es dann ein
virtuelles Gegenstück, eine Repräsentation auf dem Computer, wie
dieser Tisch im Computer dargestellt wird.
Und genauso gibt es die Kugeln in unserem Modell, und auch für die
haben wir dann ein virtuelles Gegenstück, also auch die müssen
irgendwie auf dem Computer repräsentiert werden.
Und bei der objektorientierten Programmierung ist eben das Objekt,
also diese Gegenstände, wie Tisch und Kugeln, die sind der zentrale
Begriff, um die man die Programme aufbaut.
Also wenn Sie eine Programmieraufgabe anfangen und mit dieser
objektorientierten Programmierweise vorgehen wollen, ist das
typischerweise der erste Schritt, den Sie machen.
Sie überlegen sich, wie kann ich mein Problem strukturieren, und dazu
überlegen Sie sich, welche Objekte sind daran beteiligt, an meinem
Problem, und wie können die auf dem Computer repräsentiert werden.
Also im Zentrum steht die Modellierungsfrage, wie strukturieren wir
die Daten, die wir haben.
Strukturierung, wer macht was, im Gegensatz zu wie genau was umgesetzt
wird, das ist dann erst der nächste Schritt.
Also erstmal versuchen wir, das grob einzuteilen und zu untergliedern.
Wer macht was, dann im zweiten Schritt, wie wird das gemacht.
Ich habe ja auch geschrieben, Objekte kooperieren durch Datenaustausch
weiter oben.
An unserem Beispiel, wie kann man sich das vorstellen, wenn zwei
Kugeln zusammenstoßen, dann findet da irgendeine Interaktion zwischen
denen statt.
Oder wenn die Kugel auf den Rand des Tisches prallt, findet auch eine
Interaktion mit dem Tisch statt, weil sich da eben die
Bewegungsrichtung ändert.
Das ist auch ein ganz zentrales Element in der Objektorientierten
Programmierung, dass diese Objekte eben nicht isoliert sind und gar
keine Zusammenhänge untereinander haben, in der realen Welt ist das ja
auch nicht so, sondern die Objekte spielen irgendwie zusammen und
kooperieren.
Und es gibt dann bestimmte Begriffe, die in der Objektorientierten
Modellierung verwendet werden, eigentlich zwei Varianten.
Die ältere Variante ist, dass Objekte Nachrichten senden können an
andere.
Also das heißt, eine Kugel, die blaue zum Beispiel, könnte an die rote
Kugel die Nachricht schicken, wo bist du auf dem Tisch, an welcher
Position befindest du dich.
Und die wird dann antworten mit ihrer aktuellen Position und daraus
könnte dann die blaue Kugel berechnen, ob eben ein Zusammenstoß mit
dieser Kugel stattgefunden hat oder nicht.
Eine andere Sprachweise, die in Java verbreiteter ist, ist, dass man
weniger von Nachrichten senden redet, sondern von Methoden aufrufen.
Im Grunde genommen ist es genau dasselbe, was dahinter steckt.
Also wenn wir nochmal bei dem Beispiel mit den beiden Kugeln bleiben,
das blaue Objekt möchte wissen, ist es mit der roten Kugel
zusammengestoßen und ruft dann auf der roten Kugel eine Methode auf,
zum Beispiel, wo befindest du dich auf dem Tisch und kann daraus eben
wieder berechnen, ob eine Kollision stattgefunden hat.
Also Objekte, die interagieren und für die Interaktion die Begriffe
Nachricht senden an ein anderes Objekt oder eine Methode aufrufen auf
einem anderen Objekt.
Gut, jetzt haben wir die Grundbegriffe, wir haben Objekte und wir
haben diese Interaktion zwischen Objekten.
Schauen wir uns nochmal an, wie diese Abbildung jetzt aussieht von der
realen Welt in die Welt auf dem Computer.
Also in die Programmwelt, nenne ich es jetzt mal, oder in diese
virtuelle Darstellung der Gegenstände.
Objekte habe ich immer geschrieben, weil das ist dann der Begriff, der
in der objektorientierten Programmierung ja verwendet wird.
Objekte ist das, was auf dem Computer die realen Gegenstände
repräsentiert.
Nehmen wir als erstes den Billardtisch.
Was müssen wir wissen über den Billardtisch oder wie sieht unsere
Repräsentation auf dem Computer aus?
Das hängt jetzt natürlich ganz stark von dem Problem ab, was wir
modellieren möchten.
Also wenn Sie sich den Billardtisch anschauen als einen Verkäufer von
Billardtischen, dann haben Sie ganz andere Eigenschaften und Dinge,
die an diesem Billardtisch für Sie interessant sind.
Hersteller zum Beispiel, was der Preis von so einem Tisch ist, als
wenn man jetzt wie in unserem Beispiel eine Simulation schreiben
möchte.
Also das ist sehr kontextabhängig, wie so eine Modellierung, wie der
virtuelle Gegenstand aussieht.
Und für unser Spiel, die Kugeln haben wir auch noch, für unser Spiel,
was sind da wichtige Eigenschaften?
Einmal die Länge, die Breite vom Tisch, dann eventuell noch ein Name,
wie der heißt, aber das ist wahrscheinlich weniger wichtig, das
braucht man in der Simulation nicht unbedingt.
Toronto Deluxe gibt es wirklich als Billardtisch, können Sie mal
nachgoogeln, das ist ein nettes Modell.
Und dann gibt es eben bestimmte Dinge, die für die Interaktion mit
diesem Tisch benötigt werden.
Also so eine Kugel, die sich auf dem Tisch bewegt, möchte eventuell
von dem Tisch wissen, wie groß, was ist die Länge des Tisches, was ist
die Breite des Tisches.
Und das kann dann zum Beispiel über diese Get-Length, Get-Width-Dinge,
indem man eine Nachricht sendet oder diese Methode aufruft, kann das
festgestellt werden.
Und eventuell gibt es auch noch eine Möglichkeit, auf dem Tisch einen
Ball hinzuzufügen, dass der eben weiß, welche Kugeln sich auf dem
Tisch befinden.
Gut, da hätten wir jetzt schon so eine Repräsentation dieses realen
Gegenständes als Objekt.
Und der Schritt, den wir gemacht haben, ist eine Modellierung, das
heißt, wir identifizieren wichtige Eigenschaften des realen Objekts
und versuchen, die auf den Computer zu bringen.
In diesem Objekt, da sieht man jetzt auch bestimmte Dinge, die sind
meistens aus so einem Kasten hier gezeichnet.
Einmal haben wir einen Objektname, also das soll sich um einen Tisch
handeln.
Der Name des Tisches ist hier sehr einfach, das ist einfach nur klein
t.
Dann haben wir diese Eigenschaften vom Tisch, die werden Attribute
genannt in der objektorientierten Programmierung, also bestimmte
Attribute der Tisch, wie zum Beispiel Länge, Breite, Name.
Und dann, was wir hier unten haben, sind diese Dinge zur Interaktion,
Methoden.
Und das sind eigentlich immer die typischen drei Sachen, die wir für
die Beschreibung eines Objekts benötigen.
Den Objektname, die Attribute und die Methoden.
Gut, dann schauen wir weiter.
Als zweiten realen Gegenstand, die Billardkugeln.
Was können da relevante Dinge sein, die wir für unsere
Computerdarstellung benötigen?
Ich habe es jetzt hier schon mal ein paar angeschrieben.
Der Durchmesser zum Beispiel könnte wichtig sein von so einer Kugel,
wenn man eben die exakten Zusammenstöße berechnen möchte.
Gewicht könnte wichtig sein, wenn wir eine exakte physikalische
Simulation machen wollen.
Farbe ist wahrscheinlich auch interessant.
Dann als weitere Attribute haben wir hier noch die Position in X- und
Y -Richtung und eventuell noch weitere Dinge, wie zum Beispiel die
Geschwindigkeit.
Und zur Interaktion habe ich hier nur eine Sache angegeben, die
praktisch als Interaktion mit der Außenwelt zu verstehen ist.
Also die Außenwelt kann irgendwie sagen, jetzt möchte ich einen
Simulationsschritt durchführen und dann bewegen sich eben alle Kugeln
für eine gewisse Zeit, eine zehntel, hundertstel Sekunde und bewegen
sich dann an ihre neuen Positionen.
Und das könnte man eben mit dieser Interaktionsmethode, Simulation
Step durchführen.
Gut, also was wir haben auf der linken Seite, die realen Gegenstände,
auf der rechten Seite die Repräsentation am Computer.
Noch eine kurze Anmerkung, hier in dem Beispiel hatten wir jetzt
wirklich konkrete Dinge, die wir modelliert haben, die Sie auch
anfassen können, einen Tisch, Billardkugeln.
In der Realität ist es aber auch häufig so, dass Sie mit abstrakteren
Dingen zu tun haben.
Also dass es zum Beispiel einfach ein Plan sein kann oder ein Prozess
in der Firma, den Sie modellieren, der nicht mehr so ein wirklich real
anfassbares Gegenstück hat.
Aber das nur so als Randbemerkung, wir werden dann in Zukunft auch
noch einige solcher Beispiele sehen, wo die Dinge weniger greifbar
sind.
Was wir hier auch noch sehen, ist, wir wollen ja nicht nur einen Ball
modellieren, sondern wir wollen mehrere Bälle modellieren.
Wir haben im Billardspiel sogar noch mehr als diese drei Bälle, die
jetzt hier dargestellt sind.
Und für jeden dieser Bälle können wir auf dem Computer natürlich so
eine Repräsentation haben als Objekt.
Die haben alle ähnliche Eigenschaften, also überall haben wir den
Durchmesser, Gewicht, eine Position, eine Farbe gespeichert.
Und wenn man sich das jetzt anschaut, dann vermutet man wahrscheinlich
schon, die Dinge haben so viel gemeinsam, dass man die irgendwie gar
nicht zusammenfassen möchte.
Und einmal eben das Konzept von einem Ball beschreiben und nicht jedes
Objekt immer wieder neu beschreiben, weil das eben sehr viel
Duplikation wäre.
Und da kommt jetzt der Begriff der Klassen ins Spiel.
Und die Klassen, die fassen praktisch diese gemeinsamen Eigenschaften
von Objekten zusammen, bilden praktisch einen Bauplan von Objekten.
Schauen wir uns das mal an.
Also wir haben jetzt den roten Ball hier als Objekt mit den ganzen
Attributen, die Sie hier nochmal sehen, mit der Methode unten und das
versuchen wir jetzt eben zu abstrahieren.
Das heißt, wir vergessen einfach die konkreten Werte, die hier drin
stehen.
Und damit sind wir schon bei einer Klasse.
Also anstatt hier einen festen Durchmesser von 47,2 Millimeter zu
haben, haben wir auf der rechten Seite gar nichts mehr darüber gesagt.
Genauso über Gewicht, X- und Y-Position.
Und das heißt, man kann jetzt aus diesem Bauplan auf der rechten Seite
mit dieser Klasse, kann man jetzt verschiedene Objekte erzeugen, indem
man eben diesen Attributen verschiedene Werte zuweist.
Also Sie können einen roten Ball anlegen, Sie können einen blauen und
grünen Ball anlegen und jeder von diesen hat eben dann seine eigenen
Eigenschaften, X-Y-Position und die weiteren Eigenschaften.
Also Klasse fasst Objekte zusammen auf gewisse Weise, bildet auch
einen Bauplan für die Objekte.
Wie, was ist der Kern von einem Ballobjekt, ist hier zusammengefasst
innerhalb der Klasse.
Gesagt habe ich schon, dass aus einer Klasse beliebig viele Objekte
anhand des Bauplans erzeugt werden können.
Diese Objekte, die aus einer Klasse erzeugt wurden, nennen sich dann
auch Objektinstanzen oder Instanzen der Klasse.
Also ich habe die Klasse Ball und erzeuge da zum Beispiel dann drei
Instanzen der Klasse, roter Ball, blauer Ball, weißer Ball.
Gut, dann versuchen wir nochmal die wesentlichen Aspekte
zusammenzufassen von Objekten und Klassen.
Ein Objekt wird durch drei Aspekte charakterisiert.
Das haben wir auch in dieser grafischen Blockdarstellung gesehen, da
gab es drei Bereiche, oben, Mitte, unten.
Oben stand der Name drin, das ist die Identität des Objekts.
Jedes Objekt bekommt eine Identität, die es eindeutig unterscheidet
von anderen Objekten.
Das heißt es bekommt einen Namen.
Vorher hatten wir relativ einfache Namen, T für den Tisch, Red Ball
für den roten Ball und so weiter.
Und durch den Objektnamen können wir eben auf ein konkretes Objekt
jetzt Bezug nehmen.
Und auch wenn sich das Objekt verändert, die Position zum Beispiel von
dem roten Ball auf dem Tisch, die Identität bleibt gleich, das heißt
es bleibt immer der rote Ball, auch wenn er sich auf dem Tisch bewegt.
Das wird hier durch den Objektnamen sichergestellt.
Objekte haben auch einen Zustand, das heißt zum Beispiel zu jedem
Zeitpunkt bestimmte Eigenschaften, die auf dieses Objekt zutreffen.
Und die Eigenschaften zusammengenommen repräsentieren dann den Zustand
von diesem Objekt, wie wir es eben modelliert haben.
Und das hatten wir Attribute genannt, also diese einzelnen
Eigenschaften, die zusammengenommenen Gesamtzustände ergeben, jedes
einzelne nennt sich Attribut.
Und dann gibt es eben noch Verhalten, das waren unsere Methoden, die
Kommunikation zwischen Objekten ermöglichen, dass die eben nicht für
sich alleine nur arbeiten können, sondern auch mit anderen zusammen.
Das heißt, Verhalten von Objekten, auch innerhalb eines einzelnen
Objekts, aber im Zusammenspiel hauptsächlich mit anderen, wird durch
Methoden realisiert.
Und das ist dann der dritte wichtige Aspekt eines Objekts, also Name
oder Identität, Zustand des Objekts, Position des Balls, Farbe des
Balls und Verhalten.
Zum Beispiel, er kann sich bewegen, so ein Ball kann einen Zeitschritt
vor uns rechnen, man könnte den Ball auf den Tisch verrücken um 10
Zentimeter, falls jemand versucht, vielleicht durch Betrug sich eine
bessere Situation hinzubekommen, dann könnte man sowas machen.
Aber insgesamt sind es eben diese drei Eigenschaften, die für ein
Objekt wichtig sind.
Ein Objekt, eine Klasse ist dann ein Bauplan, der die gleichartigen
Objekte zusammenfasst und legt dann für die Attribute eben konkrete
Werte fest.
Und eine Klasse ist dann durch diese Attribute und Methoden bestimmt.
Schauen wir uns das jetzt nochmal an, wie das in einer
Programmiersprache wie Java umgesetzt wird.
Das, was wir vorher schon gesehen hatten, auf der rechten Seite dieser
Bauplan mit diesem blauer karierten Hintergrund, das war eigentlich
schon Java, was Sie da gesehen hatten.
Und ich habe es jetzt hier nochmal wiederholt, Sie müssen da jetzt gar
nicht alles verstehen, was hier direkt dran steht, wichtig ist
eigentlich nur dieser Grundaufbau einer Klasse.
Also wir sehen hier wieder oben den Namen der Klasse, Ball, dann die
Attribute der Klasse, eben diese ganzen Werte, die den Zustand
repräsentieren und die Methoden, die sind hier unten mal weggelassen.
Und das generelle Schema, wenn Sie selber eine Klasse in Java
programmieren wollen, ist eben, Sie schreiben hin dieses Schlüsselwort
Klass, dann den Namen, den die Klasse bekommen soll, dann geschweift
die Klammer auf, dann diese Dinge im Klassenrumpf wie Attribute und
Methoden und geschweift die Klammer zu.
Und das Ganze nennt sich dann Klassendeklaration, das heißt, Sie haben
erklärt, wie diese Klasse aussieht.
Nur ein paar Kleinigkeiten, was wir hier auch noch sehen, ist, wie man
Kommentare in sein Programm schreiben kann.
Also das ist hilfreich, wenn man bestimmte Dinge, die nicht direkt im
Programmcode stecken, zum Beispiel noch mit ablegen möchte.
Hier sehen Sie in dem Beispiel die Einheiten von diesen Attributen.
Also das, was Sie hier sehen, so ein Kommentar wird immer eingeleitet
durch zwei solche Schrägstriche, zwei Slashes, und dann danach können
Sie Ihren Kommentar einfügen, der an dem Programm, an der Bedeutung
des Programms und wie das von dem Computer ausgeführt wird, gar nichts
ändert, sondern nur für den Menschen da ist, der das Programm eben
lesen und verstehen möchte.
Diese Kommentare, die mit den zwei Slashes anfangen, nennen sich auch
Zeilenkommentare und die sind automatisch immer mit dem Ende der Zeile
abgeschlossen.
Das heißt, auf der nächsten Zeile geht dann wieder der Programmcode
für den Computer weiter.
Wenn Sie jetzt mal längere Kommentare schreiben möchten, die sich über
mehrere Zeilen erstrecken, dann gibt es da eine andere Notation dafür.
Sie machen einmal den Slash und dann einen Stern, dann beginnt Ihr
Kommentar und der geht so lange, bis wieder ein Stern und ein Slash
kommt.
Gut, so viel zu Kommentaren.
Jetzt kommen wir zu einer ganz interessanten Frage.
Wir haben hier den Ball so modelliert.
Ist das eine gute Modellierung?
Gut ist immer sehr relativ, erfüllt wahrscheinlich ihren Zweck, wie
wir es benötigen für unser Spiel.
Das wäre auch noch so ein Qualitätsmaß.
Ist die Klasse verwendbar für das, was wir benötigen?
Oder wäre das eher so eine Balldarstellung, wie es für den
Billardtischhändler brauchbar ist?
Aber das scheint ganz gut zu passen.
Aber es gibt eine andere Sache, die hier interessant ist.
Und zwar, wir sehen hier so eine Art von Verdopplung in dieser
Klassenteklaration.
Wir haben zweimal fast dasselbe Konstrukt.
Wir haben zweimal so eine X-Position und eine Y-Position.
Oder zweimal X-Werte, zweimal Y-Werte.
Einmal für Position und einmal für Geschwindigkeit.
Und da kann man sich jetzt die Frage stellen, können wir das irgendwie
vereinfachen, das Ganze?
Das werden Sie später auch immer wieder sehen, wenn Sie Duplikationen
in Ihrem Programmcode haben, ist das meistens ein Hinweis darauf, dass
sich irgendwas daran verbessern lässt.
Dass Sie das irgendwie umstrukturieren können, dass eben keine solche
Doppelungen vorhanden sind.
Und warum macht man das?
Doppelungen erhöhen eben die Gefahr, dass Sie Fehler in Ihrem
Programmcode haben.
Und wenn Sie versuchen, das rauszunehmen, haben Sie häufig weniger
Fehler.
Und das ist normalerweise auch besser strukturiert.
Sie haben irgendwelche zusätzlichen Informationen meistens über Ihr
Programm ausgenutzt.
Also was können wir hier machen?
Diese beiden Dinge, die aus X und Y teilbestehen, die könnten wir
versuchen zusammenzufassen zu einem neuen Objekt dann wieder, das
einfach nur X- und Y-Koordinate enthält.
Also ja, wir können das vereinfachen, und zwar indem wir diese X-Y
-Paare abstrahieren.
Und ein neues Objekt, eine neue Klasse dafür einführen.
Da kann man sich jetzt überlegen, was ein passender Name ist, man
könnte es einfach Punkt nennen.
Punkt im zweidimensionalen Raum, Punkt in der Ebene.
Ich habe jetzt hier das mal Vector2D genannt, für zweidimensionalen
Vektor.
Vektor kennen Sie bestimmt alle noch aus der Mathematik.
Das sind einfach nur zwei Koordinaten, die sich hier zusammengefasst
sind.
Schauen wir uns mal an, wie denn so eine Klasse aussehen würde.
Also eine Klasse, die zweidimensionale Vektoren beschreibt, die hat
dann eben diese zwei Attribute, X-Y-Koordinate und irgendwelche
Methoden, die wir darauf aufrufen könnten.
Und mit dieser neuen Klasse können wir jetzt versuchen, unsere alte
Klasse umzuschreiben und zu vereinfachen.
Das heißt, das war die alte Klasse für den Ball, wo wir eben zweimal
die X- und Y-Koordinaten drin hatten, einmal für Position und
Geschwindigkeit.
Und das werfen wir jetzt raus, die X-Y-Koordinaten, und ersetzen es
durch so einen zweidimensionalen Vektor.
Das passiert jetzt hier.
Und was wir jetzt haben, ist eben, dass wir diese X-Y-Koordinaten
nicht mehr direkt hier drin stehen haben, sondern wir haben Position
und Geschwindigkeit.
Und wir haben das damit auf eine ein bisschen abstraktere Ebene
gebracht, weil wir gezeigt haben, diese X- und Y-Koordinate hängen
irgendwie miteinander zusammen, die sind beides Komponenten, zum
Beispiel der Position, ist jetzt hier eben deutlicher zu sehen als
davor.
Und wir haben das Ganze auch einfach besser strukturiert und diese
Duplikation vermieden.
Also was haben wir gewonnen?
Wir haben eine kürzere, übersichtlichere Klassendeklaration und wir
haben eine bessere Strukturierung erreicht.
Man nennt es auch Kapselung von Daten.
Das heißt, wir haben diese vormalig unabhängigen X-Y-Werte
zusammengefasst, gekapselt in ein neues Objekt, Position.
Und was man hier jetzt auch sieht schon ist, dass man diese Objekte
auch schachteln kann.
Also wir haben jetzt hier eine Klasse, von der wir zum Beispiel ein
Objekt Roter Ball erzeugen können und das enthält dann wieder
innerhalb dieses Objekts wieder andere Objekte, zum Beispiel die
Position oder die Geschwindigkeit.
Das ist auch was ganz Typisches und tritt in noch viel größerem Maße
bei großen Programmen natürlich auf, dass sie verschachtelte Objekte
haben.
Ein weiterer Vorteil von dieser Abstraktion, dass Sie das hier so
zusammenfassen in einem zweidimensionalen Vektor, falls Sie an diesem
Teil zweidimensionaler Vektor irgendwann mal was ändern wollen, dann
ist das eben nur eine Stelle innerhalb der Klasse Vektor 2D, wo Sie
Änderungen machen müssen und nicht mehr an verschiedenen Stellen, wo
Sie eben getrennt mit X- und Y-Koordinaten rechnen.
Gut, was wir uns jetzt noch nicht überlegt hatten, ist, wo kommen die
Objekte her?
Die müssen ja irgendwo mal generiert werden.
Bisher hatten wir die zwar als Modellierungsinstrument kennengelernt,
aber auf Programmierseite gab es ja nur die Klassen.
Das heißt, Sie können in Java eine Klassendeklaration hinschreiben,
haben damit aber noch kein Objekt.
Also wo kommen die Objekte her?
Und dazu gibt es den New Operator.
Also die genaue Syntax hier müssen Sie noch nicht verstehen, das ist
dann in der nächsten Vorlesung dran.
Aber was man sieht, ist, man hat hier den Namen von der Klasse, für
die man ein neues Objekt haben möchte.
Hier den Namen der Klasse, also Position wäre der Name des neuen
Objekts, das wir aus diesem Klassenbauplan erzeugen wollen.
Und auf der rechten Seite steht dann eben nochmal dieses New, als
Indikation neues Objekt erzeugen, bitte.
Und hier nochmal der Klassenname.
Genauso können wir mit New dann noch ein zweites Objekt erzeugen für
die Geschwindigkeit, auch wieder von derselben Klasse.
Und dann am Schluss zum Beispiel den roten Ball neu anlegen lassen.
Und nach diesen drei Aufrufen, nach diesen drei Instruktionen, hätten
Sie dann einen roten Ball erzeugt, ein rotes Ballobjekt, eine Position
und eine Geschwindigkeit.
Die sind jetzt noch nicht miteinander verknüpft, aber sind eben schon
mal da.
Das heißt, damit kann man Objekte erzeugen.
Gut, jetzt wollen wir uns noch ein bisschen anschauen, wie das jetzt
aussieht, wenn Sie sowas wirklich mal machen wollen, also wenn Sie das
programmieren wollen in Java.
Dann stehen Sie erstmal vor dem Problem, dass wenn Sie so ein Java
-Programm eintippen, der Computer gar kein Java direkt kann.
Also Sie können das nicht einfach aufrufen, das Programm und der
Computer weiß dann, was diese Instruktionen da drin zu bedeuten haben,
sondern Sie müssen das erst übersetzen.
Und dazu gibt es eben Programme, Übersetzerprogramme, die die
Programmiersprache Java kennen und die das umsetzen können in eine
Sprache, die der Computer versteht.
Und diese Programme nennen sich Compiler.
Das heißt, Sie müssen Ihr Java-Programm, wenn Sie das geschrieben
haben, erstmal kompilieren, übersetzen in die Sprache, die der
Computer versteht.
Und dazu auch noch ein zusätzlicher Hinweis.
Im Normalfall, mit ganz wenigen Ausnahmen, werden Sie für jede Klasse
eine eigene Datei erzeugen.
Das heißt, bei uns zum Beispiel, wenn Sie eine Klasse Vector2D haben,
werden Sie eine Datei anlegen auf Ihrem Computer mit einem Texteditor
zum Beispiel, die Vector2D.java heißt.
Das heißt, Sie verwenden immer die Endung .java für Ihre Programme und
legen für jede Klasse ein Objekt an.
Und was Sie dann machen, ist eben, dass Sie diesen Programmcode in
Java übersetzen und Sie erhalten dann die ausführbare Version der
Klasse, mit der der Computer etwas anfangen kann.
Das nennt sich auch Bytecode.
Was es damit genau auf sich hat, dazu auch später noch mehr.
Und dieses Bytecode wird abgelegt in einer Datei, die sich dann
genauso nennt wie die Ursprungsdatei, also auch Klassenname, aber die
hat dann eben die Endung .class.
Gut, das schauen wir uns mal ganz schnell an einem Beispiel an.
Also ich schalte jetzt hier zum Beispiel meinen Editor und tippe diese
Klasse Ball ein.
Das habe ich jetzt schon gemacht.
Also hier oben sehen Sie nochmal so einen mehrzeitigen Kommentar.
Da steht drin, was diese Klasse machen soll oder was die Objekte
dieser Klasse machen sollen.
Also, a ball object represents a ball in a billiards game.
Hier sehen Sie dann die Klassendeklaration, Klassename, geschweifte
Klammern, dann die Attribute.
Dann die Methoden, Methoden haben wir noch keine.
Gut, und nachdem der Computer mit dieser Klasse noch nichts anfangen
kann, übersetzen wir die erstmal.
Also javac für javacompiler ball.java und gucken wir, was passiert.
Da braucht es ein bisschen.
Hoppla, jetzt sehen wir, da ist irgendwas noch nicht so richtig, wie
es sein sollte.
Also der Compiler hat uns hier einen Fehler gemeldet.
Und was sagt er uns?
Ball.java, Zeile 10, das bedeutet, das ist Doppelpunkt 10.
Error, cannot find symbol.
Also er kann mit irgendeinem Symbol, irgendeinem Wort, das in unserem
Programm drin steht, nichts anfangen.
Und wenn wir mal drauf schauen, er hat es hier auch gleich unter
Kringel, die Zeile 10, da steht Vector3D Velocity.
Und da sagt er, ja, dieses Symbol, Glas Vector3D, da kann er irgendwie
nichts damit anfangen.
Und Sie vermuten wahrscheinlich schon, was das Problem ist.
Mal schauen, was hat man denn?
Wir hatten hier eine Klasse Vector2D, die ja auch schon vorhanden ist,
aber eben keine Klasse Vector3D.
Also dann ändern wir das mal.
Also starten wir unseren Texteditor.
Das war die falsche Datei.
Wo haben wir es?
Hier.
Wir machen hier aus diesem 3D hier ein 2D.
Gut, dieses D ist hier klein geschrieben, das macht auch einen
Unterschied.
Also so mit klein D würde es auch noch nicht funktionieren, aber das
erspare ich mir jetzt.
Dann mache ich gleich noch einen Groß-D draus hier und versuche es
jetzt nochmal zu kompilieren.
Also wieder Java-C für den Java-Compiler.
Ball.java.
Und super, jetzt hat er das kompiliert, das Ganze.
Und wir können mal nachschauen.
So sehen wir die untereinander.
Ursprünglich hatten wir Ball.java, das ist das, was ich eingetippt
hatte, eben diese Klassendeklaration.
Und die wurde jetzt von dem Java-Compiler übersetzt und wir haben hier
die maschinenlesbare Repräsentation.
Ball.class und hier unten dasselbe für Vector2D, da haben wir auch
diese Klassenrepräsentation.
Gut, diese Klassen machen jetzt noch nicht arg viel.
Was wir versuchen können, ist, dass wir einfach diese Programme mal
starten.
Und das geht mit dem einfachen Aufruf Java und dann gibt man auch
wieder den Klassennamen an.
Java Ball zum Beispiel.
Mal gucken, was passiert.
Übrigens wieder eine Fehlermeldung.
Also er sagt hier, auch noch auf Deutsch diesmal, Hauptmethode in
Klasse Ball nicht gefunden, definieren Sie die Hauptmethode.
Was immer das bedeuten soll jetzt, also die, die Java schon mal
programmiert haben, wissen, was das Problem ist, die anderen müssen
sich noch ein bisschen gedulden.
Gut, aber das Problem ist, was wir hier haben, wir haben noch kein
Programm geschrieben, der Computer weiß nicht, was er tun soll.
Er hat bisher praktisch nur die Modellierung, die Beschreibung der
Daten, aber wie er jetzt zum Beispiel so einen Simulationsschritt
machen soll, dazu weiß er noch nichts.
Gut,
damit sind wir mit unserem ersten Teil auch schon fertig zu Klassen
und Objekten.
Und ich möchte die Pause mal nutzen, um noch ein bisschen, den Wechsel
muss ich sagen, noch nutzen, ein paar Bücher zu zeigen, die auch auf
der Webseite als Literatur angegeben sind und auf denen die Vorlesung
zum Teil basiert.
Also zum einen gibt es hier das Buch Programmieren Lernen von Peter
Pepper.
Und an diesem Buch orientiert sich die Vorlesung relativ genau.
Also das heißt, wenn Sie Dinge haben, die Sie in der Vorlesung nicht
verstanden haben, oder etwas nochmal ein bisschen genauer nachlesen
wollen, oder ein bisschen andere Darstellungen, zum Teil ist es hier
nicht ganz so wie in der Vorlesung, dann schauen Sie in dieses Buch
rein, Programmieren Lernen, eine grundlegende Einführung mit Java von
Peter Pepper.
Dann ein weiteres Buch, das relativ neu ist, habe ich auch erst
kürzlich bekommen, nennt sich Einführung in die Programmierung mit
Java.
Das ist von einem Autor, der am MIT, also nicht am KIT, sondern am MIT
in den USA lehrt, Robert Sedgwick heißt der, der ist sehr bekannt in
der Algorithmenwelt und hat zusammen mit dem Co-Autor Kevin Wayne
diese Einführung in die Programmierung mit Java geschrieben.
Finde ich auch sehr gut strukturiert, hat sehr viele Beispiele aus den
verschiedensten Anwendungen, aus allen möglichen
naturwissenschaftlichen Bereichen, Wirtschaftswissenschaften, finde
ich auch ein spannendes Buch, wenn Sie also Beispiele noch und noch
sehen wollen, schauen Sie in dieses Buch von Sedgwick und Wayne rein.
Drittes Buch habe ich noch hier, Java in a Nutshell, das ist ein sehr
altes Buch, das ist fast mit den Anfängen von Java schon in der ersten
Auflage erschienen.
Es richtet sich ein bisschen an C-Programmierer, also Programmierer,
die diese ältere Programmiersprache C oder eventuell C++ schon kennen,
die werden sich in diesem Buch sehr schnell zurechtfinden.
Die Sprachbeschreibung oder wie man programmiert, ist nur relativ kurz
gefasst, das ist nur ein kleiner erster Teil hier, dieses Viertel,
Fünftel, was ich hier, den auf dieser Seite und der andere Teil ist
wie ein Nachschlagewerk, eine Beschreibung von den Bibliotheken, die
bei Java mit dabei sind.
Also die Bibliotheken machen in Java auch einen Großteil der Sprache
aus und erweitern die um zusätzliche Klassen, die sie nicht mehr von
Hand schreiben müssen.
Und was es da alles an Klassen gibt, das finden Sie in diesem Buch
sehr gut beschrieben.
Also es ist als Nachschlagewerk zum Programmieren, es hat ganz gut
geeignet.
Java in a Nutshell.
Gut.
Gibt es noch Fragen zu dem ersten Teil?
Oder ist das, denke ich, eine gute Gelegenheit, um mal die möglichen
Fragen, die es aus den anderen Hörsälen, in die die Forschung ja auch
noch übertragen wird, sich anzuhören?
Okay, gut, ich kann nochmal die Frage wiederholen.
Die Frage war, wie man die Übungsblätter abgibt, ob man die ausdrucken
muss und irgendwo in Papierform abgeben.
Das ist nicht der Fall.
Sie müssen die Abgaben von den Übungsblättern immer in rein
elektronischer Form abgeben, über dieses Praktomat-System im Internet.
Also keine Ausdrucke, kein Papier, keine Bäume, die sterben wegen
unserer Vorlesung, sondern wirklich alles nur elektronisch auf dem
Computer abschicken.
Das war eine Frage zu den Übungen mehr.
Haben wir noch weitere Fragen?
Gut, keine weiteren Fragen von unseren Zuschauern aus der Ferne.
Gibt es hier gerade noch Fragen?
Ja, hier oben sehe ich eine.
Ja, die Frage war, ob es ein Skript, ein Kurzskript, wenn ich es
richtig verstanden habe, zu der Vorlesung gibt.
Es wird nicht direkt ein Skript geben.
Es gibt die Vorlesungsfolien, wie ich sie hier zeige, im Internet, die
können Sie sich runterladen.
Die stehen auch jetzt schon, dieser erste Foliensatz im Internet.
Im Normalfall werden die kurz vor der Vorlesung hochgeladen.
Da gehen Sie an die Adresse studium.kit.edu in den
Vorlesungsarbeitsbereich.
Da finden Sie die ganzen Folien zum Runterladen.
Ein durchgängiges Skript mit zusätzlichen textuellen Bausteinen gibt
es nicht.
Also dazu würde ich Ihnen dann empfehlen, wenn Sie dann mehr
Informationen brauchen, einfach in dieses Buch Programmieren, Lernen
von Peter Pepper reinzuschauen.
Ansonsten sind wir auch noch, oder bin ich, am Überlegen, ob diese
Vorlesung, die ja auch zum Streamen in die anderen Hörsäle auf Video
aufgenommen wird, ob wir die ins Internet stellen, dass Sie die sich
auch im Nachhinein nochmal anschauen können.
Da scheint Interesse dran zu bestehen, dass wir das machen.
Ich hoffe natürlich, dass trotzdem noch einige von Ihnen dann in die
Vorlesung kommen, dass Sie nicht alle sich nur zu Hause am Computer
dann die Aufzeichnung ansehen.
Aber ich denke, das werde ich dann machen und ich würde Ihnen dann in
der nächsten Vorlesung nochmal Bescheid geben, wo Sie genau dann die
Videos finden.
Gut, gibt es noch weitere Fragen?
Ja, hier vorne haben wir noch eine.
Ja, die Frage war, ob es dann nur das Video gibt oder ob es auch die
Folien noch gibt.
Die Folien, die gibt es auf jeden Fall.
Ganz bedingungslos werden die in diesem Systemstudium KIT-EDU
erhältlich sein.
Wie gesagt, die stehen auch jetzt schon auf der Seite, gehen in den
Forschungsarbeitsbereich.
Und wenn es das Video gibt, dann wird es zusätzlich sein zu den
Folien, die Sie im Internet finden.
Dann kommen wir nun zum zweiten Teil der Vorlesung.
Und in dem zweiten Teil, da schauen wir uns Typen und Variablen in
Java an.
Was haben wir bisher gesehen?
Wir hatten Objekte und Klassen, das heißt, wir haben uns mit der
Modellierung beschäftigt.
Was wir aber auch gesehen haben ist, als wir vorher mit dem Java
-Compiler das Programm starten wollten, dass es ja noch gar nichts
macht bisher.
Das heißt, das, was wir uns jetzt anschauen, geht in die Richtung, wie
füge ich Funktionalität meinem Programm dazu.
Und dazu verwenden wir, oder ein wichtiger Begriff, den wir dazu
benötigen, sind die Datentypen.
Und ich möchte hier erst mal mit einer Definition beginnen, was ist
ein Datentyp?
Ein Datentyp, oder auch, gibt es die Kurzbenennung Typ, bezeichnet
eine Menge gleichartiger Werte.
Also Datentyp fasst gleichartige Werte zusammen.
Werden wir gleich ein Beispiel sehen, was das bedeutet.
Vielleicht mal so viel, was wir uns vorstellen, drunter werden zum
Beispiel unsere Objekte für die Billardkugeln, die irgendwie
gleichartig sind.
Also das könnte so etwas wie ein Datentyp sein.
Oder Zahlen, wenn Sie an ganze Zahlen denken, das sind auch irgendwie
gleichartige Dinge, gleichartige Werte, die man zusammenfassen könnte
mit so einem Datentyp.
Und die Datentypen legen die möglichen Werte von Variablen, Attributen
und Methoden fest.
Also was Methoden sind, haben wir auch bloß ganz kurz gehört.
Attribute kennen wir schon, das war zum Beispiel die Position von
einer Kugel auf dem Tisch.
Oder die Geschwindigkeit oder die Farbe.
Und die werden durch so einen Datentyp festgelegt.
Und außer dem bestimmten Datentyp auch noch welche Operationen mit
diesen Werten, die in dem Datentyp enthalten sind, möglich sind.
Also das ist jetzt noch ein bisschen abstrakter alles vielleicht,
deshalb schauen wir uns mal an Beispielen an, was haben wir in Java an
Datentypen.
Da gibt es erstmal eine grobe Unterscheidung in zwei Varianten von
diesen Datentypen.
Es gibt die elementaren Datentypen und es gibt Klassen als Datentypen.
Elementare Datentypen, im Englischen werden die auch Primitive Data
Types genannt.
Und im Deutschen gibt es da auch manchmal die Benennung Primitive
Datentypen, wobei man dazu sagen kann, im Englischen hat das Primitive
nicht diese negative Annotation, die es im Deutschen gibt.
Also das bedeutet wirklich eher so etwas wie einfacher oder Basis
-Datentyp.
Gut, welche Datentypen haben wir in Java?
Acht Stück von diesen Basis-Elementar-Datentypen.
Zum einen sind es Zahlen.
Verschiedene Varianten von Zahlen.
Das können ganze Zahlen sein, das können aber auch so eine
Modellierung von reellen Zahlen sein.
Auf dem Computer verwendet man dazu Fließkomma-Zahlen, weil sich nicht
alle reellen Zahlen einfach abbilden lassen auf dem Computer.
Also einmal Zahlen in verschiedenen Varianten, Wahrheitswerte, auch
etwas, was wichtig sein könnte, und Zeichen.
Also sowas wie die Buchstaben, die Sie hier auf den Folien sehen, die
werden auch Zeichen oder Character im Englischen genannt.
Und auch dafür gibt es einen Datentyp.
Das heißt, wir fassen da gleichartige Dinge zusammen, wir fassen zum
Beispiel diese Zeichen, die dargestellt werden können, zusammen in
einem Typ Zeichen.
Wir fassen Fließkomma-Zahlen zusammen in einem Typ Fließkomma-Zahlen.
Das ist die eine große Gruppe, die elementaren Datentypen.
Kommt gleich dazu mehr, wie die genau im Einzelnen aussehen und was
man mit denen machen kann.
Die zweite große Gruppe sind dann Klassen als Datentypen.
Das heißt, jede Klasse bildet auch einen Datentyp.
Und wenn wir uns nochmal anschauen, die Definition hier oben, dann
sehen wir schon, dass das auch ganz gut zutrifft, was wir über Klassen
wissen, auf diese Datentyp-Definition.
Also gleichartige Werte, also alle Objekte haben ja diese gemeinsamen
Attribute, also da haben wir schon eine Gleichartigkeit.
Datentypen legen Werte von variablen Attributen fest, haben wir auch,
Attribute gibt es ja in den Klassen.
Und die Datentypen bestimmen, welche Operationen möglich sind.
Das sind eben die Methoden, die wir in die Klassen reinschreiben, die
man als Operationen auf die Objekte auffassen kann.
Und eine andere Sichtweise ist, dass man auch Klassen so verstehen
kann, oder die Datentypen der Klassen, dass wir dadurch diese
elementaren Datentypen, die uns Java schon zur Verfügung stellt,
erweitern können, um das, was wir eben für unsere Anwendung oder für
das Programm, das wir schreiben wollen, benötigen.
Also wir können eigene benutzerdefinierte Datentypen über Klassen
realisieren.
Gut, dann schauen wir uns mal die elementaren Datentypen, die uns Java
zur Verfügung stellt, der Reihe nach an.
Erstmal ein Überblick, was haben wir an elementaren Datentypen.
Acht Stück, hat man ja festgestellt, gibt es in Java.
Der erste Datentyp nennt sich Boolean.
Boole kommt von boolscher Logik, dem Mathematiker und Logiker George
Boole, nach dem sind eben diese boolschen Wahrheitswerte benannt.
Das ist ein sehr einfacher Datentyp, welche Werte sind da möglich, es
gibt nur wahr und falsch.
Und dann eben noch bestimmte Operationen auf diesen Datentypen, auf
diesem Datentyp Boolean, den wir nachher sehen.
Es gibt diesen Datentyp, um Zeichen darzustellen, also sowas wie die
Buchstaben.
Der nennt sich Character oder abgekürzt nur als Char, sagt man da
meistens dann im Englischen dazu.
Und was in Java damals relativ neu war, ist, dass man eben nicht nur
die Standard 8-Bit-Codierung, die damals gebräuchlich war, diese ASCII
-Codierung verwendet hat, sondern eine umfassendere Codierung mit 16
-Bit, die mehr Werte zulässt, um eben damit zum Beispiel auch Umlaute
und Schriftzeichen, die nur in bestimmten Sprachen vorhanden sind,
auch in diesen Datentyp reinzubekommen.
Da haben 255 Werte nicht mehr ausgereicht, deshalb haben wir hier
einen größeren Datentyp.
Und Sie sehen auf der rechten Seite, da ist zum Beispiel das Groß-A,
gehört zum Beispiel da als Wert mit rein.
Dann diese komische Sache mit diesem Backslash-N, kommt vielleicht
noch was dazu, was das bedeutet.
Oder sowas wie dieses Backslash-U, 05D0, das ist so eine sogenannte
Unicode -Codierung von Zeichen.
Aber dazu auch noch mehr gleich.
Gut, also Bool'sche Werte, Wahrheitswerte waren falsch, Zeichen, wie
sie im Text vorkommen.
Und jetzt kommen eine ganze Reihe von Zahldatentypen.
Beginnen tut es mit vier Ganzzahldatentypen, Byte, Short, Int und
Long.
Und wie unterscheiden die sich jetzt?
Sie können alle ganze Zahlen darstellen, aber sie haben eben eine
unterschiedliche Bitbreite.
Das heißt, die Anzahl der Bits, die auf dem Computer verwendet werden,
um einen Wert von diesem Typ darzustellen, sind unterschiedlich.
In 8-Bit passen eben nur kleinere Zahlen rein, 16-Bit größere und in
64 -Bit dann eben sehr große Zahlen.
Auf der rechten Seite sehen wir wieder Beispiele, wie solche
Ganzzahlen aussehen können.
Das überrascht niemand, da haben wir 3 mal 12 da stehen.
Das ist jetzt vielleicht ein bisschen was Interessanteres, 12 L oder
14 klein L.
Über diesen angehängten L-Buchstaben teilen wir Java mit, dass es sich
dabei um einen Long-Wert, eine Long-Konstante handeln soll.
Das weiß man sonst nicht, aber das ist nur eine kleine Rennbemerkung.
Wenn Sie programmieren und das weglassen, weist sich der Compiler im
Normalfall darauf hin, dass da was nicht stimmt.
Wenn Sie eine Konstante ohne so ein L haben, dann können Sie das
korrigieren in Ihrem Programm.
Also 4 Ganzzahldatentypen, die sich durch die Größe der Zahlen oder
der Werte, die in diesem Typ darstellbar sind, unterscheiden.
Und dann haben wir noch ganz unten 2 Datentypen, um Gleitpunkte oder
Fließkomma -Zahlen darzustellen.
Also sowas an die realen Zahlen Angenähertes.
Und auch die unterscheiden sich wieder durch die Bitbreite, die
verwendet wird und damit durch den Bereich der darstellbaren Werte.
Also wie groß können die maximal sein?
Bei Fließkomma-Zahlen auch, wie präzise ist die Darstellung?
Also wie viele Stellen hinter einem Komma lassen sich mit einem
solchen Datentyp darstellen?
Rechts haben wir wieder Beispiele, wie Sie das notieren können.
9,81, dann wieder F als eine Erkennung, dass es sich um eine
Fließkomma -Zahl handelt.
Dann 0,379E-8F, das liest sich jetzt ein bisschen komisch.
Aber so eine ähnliche Notation kennen Sie von Ihrem Taschenrechner
bestimmt.
Also das F hinten, das ist auch wieder bloß ein Kennzeichen, dass es
sich um eine Fließkomma-Zahl handelt.
Das denken wir uns jetzt erstmal weg.
Und was dann noch übrig bleibt, ist dann dieses 0,379E-8.
Und das ist eben die, wie gesagt vom Taschenrechner auch bekannte
Exponentiationsnotation oder wissenschaftliche Notation.
Und es drückt eben aus, dass dieser Wert 0,379 mit 10 hoch minus 8
multipliziert werden soll.
Und dass das der Wert ist, der hier dargestellt ist.
Aber das Ding, das kennen Sie alle von Taschenrechnern.
Dann hier nochmal 2F.
Was hier vielleicht noch interessant ist, ist, wenn wir nur die 2
hinschreiben würden, dann wäre das ein ganz zahliger Wert.
Wenn wir ein F dahinter schreiben, weiß Java, dass es sich um einen
Fließkomma -Wert handelt.
Ähnlich bei Gleitkommazahlen, da kann man das F weglassen.
Das heißt, wenn man F weglässt, wird standardmäßig Double als
Fließkommatyp angenommen.
Okay, das sind die acht Basisdatentypen.
Aber was man jetzt genau mit denen machen kann, welche Operationen
darauf definiert sind, wissen wir bisher noch nicht.
Also schauen wir uns das mal als nächstes an.
Eine Sache noch davor, vor uns die Operationen anschauen, die möglich
sind, nochmal die Wertebereiche der Variablen.
Also was können wir mit diesen unterschiedlichen Ganzzahlen und
Fließkommazahlen darstellen.
Ganz oben nochmal dieser Zeichenwert, der umfasst 65.536 Werte, von 0
bis 6535.
Und die können eben mit dieser Backslash-U-Notation angegeben werden.
Und das, was man dahinter angibt, ist eine Zahl in diesem Bereich in
Hexadezimaldarstellung.
Also deshalb haben Sie da rechts zum Beispiel auch diese 4F, die dann
eben hexadezimal für 65.535 stehen.
Wichtiger sind aber noch die Integer-Datenbereiche.
Also beide haben wir gesagt, 8-Bit, was kann man mit 8-Bit darstellen?
256 Werte, 2 auf 8 Werte.
Und die könnte man zum Beispiel wählen von 0 bis 255.
Dann hätten wir diese 256 möglichen Werte, die mit 8-Bit gehen,
abgedeckt.
In Java haben sich die Sprachdesigner aber entschieden, einen anderen
Zahlenbereich zu nehmen, der nicht von 0 anfängt bis 255 geht, sondern
symmetrisch oder annähernd symmetrisch um die 0 angeordnet ist.
Das heißt, die Werte gehen hier von minus 128 bis plus 127.
Dann bei Short haben Sie 16-Bit zur Darstellung.
Auch da wieder nicht der Wertbereich von 0 bis 65.535, sondern auch
wieder symmetrisch um die 0 angeordnet oder fast symmetrisch von minus
32.000 und so weiter bis plus 32.000.
Dann wenn Sie jetzt für Ihr Programm noch größere Werte benötigen,
dann gehen Sie eben zu Int, der erlaubt Werte von minus 2 Milliarden
ungefähr bis plus 2 Milliarden.
Oder wenn Sie noch größere benötigen, wenn Sie die Staatsverschuldung
von Griechenland oder Deutschland darstellen wollen, dann nehmen Sie
vielleicht am besten einen Long.
Da passen dann wirklich auch so große Werte rein.
Falls das immer noch nicht reicht oder wenn Sie Fließkomma-Zahlen
benötigen, also Kommazahlen, wo irgendwas nach dem Komma kommt, dann
müssen Sie eben auf diese Fließkomma-Werte gehen.
Und da sind die kleinsten darstellbaren Zahlen minus 3,4, das ist die
kleinste negative Zahl absolut gesehen, minus 3,4 mal 0,38, wo die
größte Zahl, die Sie darstellen können, 3,4 mal 0,38 und dann bei
Double haben Sie wieder einerseits die Möglichkeit, größere Zahlen
darzustellen, andererseits sehen Sie auch, dass Sie eine höhere
Präzision haben.
Also die Anzahl der Stellen, die in diesem Datentyp relevant sind,
nimmt bei Double auch zu.
Und es gibt auch noch die Möglichkeit, die Zahlen in verschiedenen
Zahlensystemen anzugeben.
Bei Ganzzahlen ist das der Fall, Sie können die ganz normal im
Dezimalsystem angeben oder im Achtersystem, im Oktalsystem, da muss
man dann eine Null davor schreiben, da müssen Sie aber auch ein
bisschen aufpassen, Sie können nicht einfach vor die Zahl 10 eine Null
schreiben, ohne dass sich da die Bedeutung verändert, dann wird das
als Oktalzahl gewertet und 010 werden einem nur noch 8 und nicht mehr
10.
Genauso, wenn Sie hexadezimale Notationen verwenden wollen, dann
schreiben Sie 0x vor Ihre Zahl und können dann eben die
Hexadezimalziffern von 0 bis F verwenden.
Warum Oktal- und Hexadezimalsystem?
Computer arbeiten ja intern mit einem Zweiersystem, aber will das eben
in so einem Zweiersystem hinzuschreiben, dass eben die Zahlen sehr
lang werden würden, fasst man die dann eben zusammen bei Oktalzahlen
in Dreierblöcke, also immer drei Binärziffern zusammengefasst zu einer
Oktalzahl, bei Hexadezimalzahlen immer vier Binärziffern
zusammengefasst zu einer Hexadezimalziffer.
Das ist praktisch eine Anpassung an den Computer, aber in allermeisten
Fällen, wenn man nicht gerade systemnahe Programme schreibt, ist
eigentlich die Dezimalnotation das, was man verwendet.
Gut, soweit die Wertebereiche.
Jetzt, was können wir mit diesen Werten anfangen?
Wir wollen irgendwie mit denen ja rechnen können.
Und dazu stellt Java eine ganze Reihe von Operatoren oder Operationen
zur Verfügung, mit denen wir rechnen können.
Und die unterscheiden sich auch jetzt wieder nach Typ, auf dem
bestimmte Operationen möglich sind, oder lassen sich in bestimmte
Unterklassen eingruppieren.
Und ganz oben geht es los mit den arithmetischen Operationen und mit
Vergleichsoperatoren.
Das sind Dinge, die überraschen niemanden groß.
Sie können dieses unnähere Plus Minus verwenden, einfach vorne Zahl
Plus schreiben.
Das ändert nichts an der Zahl selber, aber es ist nochmal ein
zusätzliches Hinweis, dass das eben Plus ist und nicht die negative
Zahl.
Sie können Minus einfach davor schreiben, das ist dann die Negation.
Dann haben wir die üblichen arithmetischen Operationen.
Multiplikation mit dem Stern geschrieben, Division mit dem
Schrägstrich geschrieben.
Und dann dieses Prozentzeichen, das ist vielleicht nicht so
gebräuchlich, das nennt sich Modulo-Operation und gibt den Rest der
Division an.
Also wenn ich X durch Y teile, ganzzahlig, kann ja ein Rest übrig
bleiben.
Und dieser Rest ist eben das Ergebnis dieser Operation.
Zum Beispiel 5 durch 3 geht einmal rein und dann bleiben noch zwei
übrig.
Und zwei werden dieser Modulus, den Sie hier bekommen.
Also das Ergebnis von 5 Modulo 3 wäre 2.
Dann haben Sie Addition, Subtraktion, Vergleiche, kleiner, größer,
gleich, Gleichheit, Ungleichheit.
Das finde ich interessant, für die Gleichheit müssen Sie zwei
Gleichheitszeichen hintereinander schreiben.
Warum man das macht, dazu kommen wir auch noch später, aber Sie können
sich jetzt einfach merken, wenn Sie einen Gleichheitsvergleich machen
wollen, zwei Gleichheitszeichen hintereinander schreiben.
Wenn Sie auf Ungleichheit testen wollen, gibt es dieses Ausrufezeichen
gleich.
Gut, soviel zur Arithmetik.
Dann gibt es noch weitere Operationen auf ganzen Zahlen, die auf der
Bitdarstellung auf dem Rechner passend oder für die gedacht sind.
Und zwar können Sie mit diesem tilde-Präfix ein bitweises Komplement
erreichen.
Was heißt jetzt bitweises Komplement?
Wenn Sie sich die Zahl in Binärdarstellung angucken, besteht die ja
nur aus Einsen und Nullen.
Also 101 wäre zum Beispiel die 5.
Und das Komplement der Zahl ist einfach dadurch zu erhalten, dass man
jede 1 durch die 0 ersetzt und die 0 durch die 1.
Also Sie drehen die Werte einfach um.
Das ist das Komplement.
Dann gibt es bitweise Und-Operationen, mit diesem einfachen Kaufmann
-Und bezeichnet.
Das Exklusiv-Oder, mit diesem Hut oder Hochzeichen beschrieben.
Und das bitweise Oder mit einem sinngerechten Strich markiert.
Dann gibt es Operationen auf Wahrheitswerten.
Die Negation eines Wahrheitswertes, der wird aus True eben False und
aus False True.
Die Und-Verknüpfung von Wahrheitswerten und die Oder-Verknüpfung von
Wahrheitswerten.
Hier vielleicht noch die Anmerkung, dieses einfache Und-Zeichen und
das einfache Oder-Zeichen, die sind auch auf Boolchen-Werten möglich.
Das heißt, Sie können auf Boolchen-Werten sowohl das einfache Und
schreiben oder dieses Doppel-Und hintereinander.
Und hier unten steht noch dran, sequentielles And.
Das hängt damit zusammen, dass man eben dieses Sequentielle
unterscheidet von dem oberen, dazu auch gleich noch ein bisschen mehr,
was da genau der Unterschied ist.
Aber lassen Sie mich erst vorher noch die Liste noch von uns
abschließen.
Als letzten Block von Operatoren haben wir noch Shift-Operationen.
Das sind praktisch auch wieder auf dem Bit-Level arbeitende
Operationen, mit denen man eine Zahl in der Binärdarstellung nach
links oder rechts schieben kann.
Wenn man eine Zahl nach links schiebt, entspricht es arithmetisch fast
immer einer Verdoppelung und das, was unten praktisch reinkommt, wo
ein Platz frei wird, ist immer eine Null.
Und was oben rausfällt, das fällt dann halt unter den Tisch.
Also wenn ich schiebe einfach alle Bits um Y-Positionen nach links,
was links rausfällt, ist weg und auf der rechten Seite kommen Nullen
rein.
Dann gibt es noch den Rechts-Shift in zwei Varianten.
Da wird die Zahl um Y-Bits in die andere Richtung, nach rechts,
verschoben.
Dadurch wird eine Zahl im Normalfall durch zwei hoch Y geteilt.
Wenn man es sich arithmetisch wieder anschaut, und hier gibt es zwei
Varianten, je nachdem, ob man das Vorzeichen behaftet oder ohne
Vorzeichen machen möchte.
Und das hat Einfluss darauf, ob eben an dieser Stelle, wo dann neue
Werte nachgeschoben werden, Nullen nachgeschoben werden oder das
passende Vorzeichen.
Jetzt noch eine zusätzliche Information.
Die ganzen Operatoren, die hier genannt sind, haben alle eine
sogenannte Präzedenz.
Und die Präzedenz gibt an, wie stark die Operatoren binden.
Und das dient dazu, um Klammerungen zu vermeiden.
Sie kennen das aus der Mathematik alle, da gibt es ja die Punkt-Vor
-Strich -Regelung.
Das heißt, wenn ich eine Multiplikation oder eine Division habe, dann
ist die vor den Strichoperatoren, vor Plus und Minus auszuführen.
Und das dient ja auch dazu, Klammern zu sparen und ähnlich ist es
hier.
Hier ist jetzt die Bedeutung so, je kleiner dieser Präzedenzwert, der
in der linken Spalte angegeben ist, desto stärker bindet der Operator.
Das heißt, wenn wir wieder an Punkt-Vor-Strich denken, dann bräuchte
die Multiplikation einen kleineren Wert, damit sie eben stärker bindet
als die Addition.
Das können wir ja gleich mal prüfen, also hat die Multiplikation einen
kleineren Wert als die Addition?
Schauen wir nach, ja, die zweite Zeile sind wir.
Zwei ist die Präzedenz der Multiplikation, drei die der Addition, also
das passt.
Das Mal bindet stärker als das Plus.
Dazu kommt gleich noch ein Beispiel.
Jetzt nochmal kurz zu dieser Unterscheidung zwischen den Bool'schen
Operatoren, dem Und und dem Oder, die man ja einmal mit einem Doppel
-Und schreiben kann auf Wahrheitswerten, oder mit einem einfachen Und.
Und in fast allen Fällen, wenn Sie programmieren, werden Sie, wenn Sie
mit Wahrheitswerten rechnen, dieses zweifache Und verwenden.
Und dieses zweifache Und unterscheidet sich von dem einfachen,
dadurch, dass das eine sogenannte Kurzschlussauswertung vornimmt.
Das heißt im Englischen auch Short Circuit Evaluation.
Und was hat man sich darunter vorzustellen?
Das bedeutet, wenn so ein Bool'scher Ausdruck ausgewertet wird, und
der Auswerter, also das Java schon weiß, wie der Wahrheitswert
zwangsläufig sein muss, dann wird die Auswertung nicht mehr weiter
fortgesetzt.
Also nehmen wir an, ich schreibe hin A und B.
Und A hat den Wahrheitswert falsch.
Dann weiß ich schon, egal was hinter dem Und noch kommt, der
Gesamtwert von A und B, falsch und irgendwas, wird immer auch falsch
sein müssen.
Und deshalb ist es unabhängig von dem zweiten Wert, B auf der rechten
Seite, und der muss deshalb nicht ausgewertet werden, und wird dann
auch in dieser Kurzschlussauswertung gar nicht mehr betrachtet,
sondern der bricht dann sofort ab, wenn er den linken Wert bestimmt
hat.
Aber das ist ein Detail, das werden Sie später in Ihrem
Programmieralltag noch in der Praxis sehen.
Gut, zu Präzedenz.
Ich habe schon gesagt, Präzedenzregeln helfen, unnötige Klammern zu
vermeiden.
Schauen wir uns ein Beispiel an.
Der Ausdruck, den ich hier hingeschrieben habe, der hat oben relativ
wenige Klammern auf der linken Seite.
Rechts habe ich nochmal die Präzedenzen dargestellt von den
verschiedenen Operationen und steht auch nochmal drunter, je kleiner
die Präzedenz ist, desto stärker bindet der Operator.
Das heißt, in dem Ausdruck auf der linken Seite können wir jetzt
versuchen herauszufinden, in welcher Reihenfolge Java diesen Ausdruck
auswertet.
Das heißt, wie geklammert ist der zu verstehen?
Schauen wir mal, was am stärksten bindet.
Am stärksten binden die Werte, die kleinsten Werte.
Also zum Beispiel Multiplikation hat Wert 2.
Das heißt, hier auf der linken Seite, die Multiplikation 2 mal Y ist
etwas, was vor der Addition ausgeführt wird.
Das ist wenig überraschend, das ist einfach Punkt vor Strich.
Aber wenn wir schauen, zum Beispiel mit dem Kleinen, wird X kleiner 2
zuerst betrachtet oder wird zuerst 2 mal Y plus 1 berechnet.
Sehen wir hier, dass das Kleine hat eine Präzedenz von 5, bindet also
schwächer.
Das heißt, erst wird die rechte Seite berechnet, 2 mal Y plus 1 und
dann der Vergleich gemacht.
Das kann man jetzt natürlich noch vollständig ergänzen hier.
Und am Schluss stellen wir fest, dass das, was hier drunter steht, die
vollständig geklammerte Fassung ist.
Jetzt noch eine Frage an Sie.
Was passiert denn, wenn wir hier oben in dem Beispiel, da ist ja noch
eine Klammer drin, was passiert denn, wenn wir die auch weglassen?
Da haben wir ein paar Antworten.
Sie mit dem weißen T-Shirt, wenn Sie eine Idee haben.
Fangen Sie nochmal kurz bitte.
Genau, ich wiederhole nochmal die Antwort.
Was passiert ist, dass dann dieses Ausrufezeichen, weil es eben einen
sehr kleinen Präzedenzwert hat, sehr stark bindet, das heißt, dieses
Ausrufezeichen bezieht sich nur auf das X und die restlichen Sachen,
die werden dann eben später berechnet.
Also erst nicht X, dann dieses größere Gleich.
Dazu gibt es noch hier einen Kommentar.
Richtige Feststellung hier.
Was wir hier gerade gehört haben, ist, dass wenn wir diese Klammern
weglassen, dass sich zwar die Präzedenz ändert, aber noch ein Problem
auftritt, dass das Programm nicht mehr korrekt ist, dass wir einen
Syntaxfehler bekommen.
Und das liegt daran, dass eben dieses Nicht-X-Bullshit-Wert hat und
das dann nicht mehr mit dieser Vergleichsoperation Größer-Gleich
zusammenpasst.
Ich denke, die Zeit ist ein bisschen knapp, deshalb würde ich das
gerne zurückstellen, machen wir vielleicht noch am Ende der Vorlesung,
wenn Zeit übrig bleibt, dass wir das anschauen, was der Compiler dazu
sagt, wenn wir das wirklich eintippen.
Ansonsten können Sie das auch mal zu Hause ausprobieren oder Ihrem
Tutor in den Übungen noch sagen.
Aber die Beobachtungen sind richtig, die Präzedenz würde sich ändern,
was wir als erstes gehört haben, und das Nicht würde dann stark an das
X binden.
Und genauso auch die zweite Anmerkung, dass wir dann einen
Syntaxfehler, einen Typfehler hätten, also praktisch fast schon ein
semantischer Fehler, den wir hier haben.
Gut, jetzt gehen wir die Operationen der Reihe nach durch, die wir
haben, auf den Bool'schen Werten haben wir die Operationen Und, Oder,
Xor und Negation.
Und ich habe jetzt hier mal statt True und False, weil das so lange
ist und so viel Platz braucht, einfach 1 für True geschrieben und 0
für False, das steht hier unten auch nochmal dran, aber in Ihrem
Programm müssten Sie immer True und False verwenden, wenn Sie sowas
auswerten lassen möchten.
Schauen wir mal an, also das Und ist einfach das, was Sie
üblicherweise auch erwarten, also das Und von A und B ist genau dann
eins, wenn sowohl A und B eins sind, oder mit True gesagt, wenn A und
B wahr sind, dann und nur dann ist auch die Unverknüpfung wahr.
Bei Oder ist das Ergebnis eben wahr, wenn mindestens einer der beiden
Argumente wahr ist.
Bei dem Xor, dem Entweder-Oder, muss eben entweder A oder B wahr sein,
aber nicht beide dürfen wahr sein, deshalb haben wir hier eine 0 in
der letzten Zeile.
Und die Negation, hier jetzt von A ausgedrückt, dreht einfach wahr und
falsch um, das heißt aus jedem wahr wird ein falsch und umgekehrt.
Soviel zu den Wahrheitswerten, da gibt es auch noch eine Frage hier.
Die Frage war, ob man mit den Wahrheitswerten rechnen kann, wenn hier
statt True und False 0 und 1 angegeben wird.
Und das ist nicht der Fall, also Sie können nicht zum Beispiel 3 plus
True rechnen, dass da so etwas wie 4 rauskommt, das ist hier wirklich
nur eine notationelle Abkürzung, damit es besser auf die Folie passt.
Man kann nicht mit den Wahrheitswerten wie mit Ganzzahlen rechnen.
Gut, zum nächsten Datentyp, den Ganzzahlen, die habe ich hier mal
zusammengefasst.
Das ist Byte, Short, End und Long.
Die Additions-, Subtraktions- und Multiplikationsoperatoren arbeiten
fast so, wie Sie das kennen, mit einer kleinen Einschränkung, die wir
gleich noch sehen werden.
Division und Modulo-Operation, also die Restwertbildung, da muss man
ein bisschen aufpassen, die arbeiten ganzzahlig, das heißt zum
Beispiel 17 durch 5 ergibt 3 und nicht 3, irgendwas, weil das ja eben
kein ganzzahliges Ergebnis mehr wäre, aber dafür können Sie dann den
Rest bestimmen mit dem Modulus-Operator Prozent und kriegen dann den
Restwert raus.
Also Division ganzzahlig, das kann manchmal ein bisschen Verwirrung
sorgen, wenn man eben nicht den Komma-Wert bekommt, sondern die
ganzzahlige, das ist ein ganz klares Ergebnis.
Dann hatte ich gesagt, dass bei den Plus-Minus-Mal-Operatoren, die
sich nur fast wie in der Mathematik verhalten, wo treten Unterschiede
auf?
Unterschiede sind dadurch gegeben, dass die Zahlenbereiche beschränkt
sind.
Das heißt, ganze Zahlen können nicht beliebig groß werden und auch
nicht beliebig groß-negativ, sondern die sind eben beschränkt auf
einem bestimmten Bereich, wie wir vorher gesehen hatten.
Und das heißt, es kann dadurch eben ein Überlauf auftreten oder ein
Unterlauf, wenn die Zahl negativ eben aus dem Bereich rausläuft.
Und dann bekommen wir falsche Ergebnisse.
Und was dann passiert, ist einfach, dass die durch den Überlauf
eigentlich benötigten mehr Ziffern oder mehr Binärziffern einfach
abgeschnitten werden.
Und dadurch bekommt man eben solche komischen Effekte, wie das, was
Sie hier unten jetzt in den Beispielen sehen.
Also wenn Sie den Integer-Datentyp von Ihnen, der so einen
Darstellungsbereich hat, ist ungefähr zwei Milliarden und ein bisschen
dazu.
Wenn Sie jetzt zweimal zwei Milliarden zusammenzählen, dann gibt es
vier Milliarden, würden Sie sagen.
Aber wenn es eben aus dem Bereich für ganze Zahlen rausfällt, bräuchte
es ein Bit mehr, bräuchte 33 Bit, um das darzustellen und dieses 33.
Bit fällt einfach weg und man bekommt dann eben dieses komische,
negative, falsche Ergebnis.
Also das ist etwas, auf das man aufpassen muss und was auch in der
Realität wirklich zu Fehlern in Programmen führen kann, wenn man
solche Überlauf-Effekte nicht berücksichtigt.
Und genauso das zweite, da haben wir ein Beispiel für den Unterlauf,
diese Zahl, die wir links sehen, diese zwei Milliarden irgendwas, ist
die kleinste negative darstellbare Zahl für einen Typ Integer und wenn
ich da jetzt eins abziehe, dann ist sie eben nicht mehr darstellbar
und ich bekomme auch ein falsches Ergebnis.
Wenn Sie sich das mal anschauen, was passiert in der Binärdarstellung,
sehen Sie, dass das dann eben die größte darstellbare positive Zahl
ergibt.
Also da müssen Sie aufpassen über Unterlauf.
Eine zweite Sache, worauf Sie auch noch achten sollten, ist, dass wenn
Sie Werte des Typs Byte oder Short miteinander verrechnen, also wenn
Sie zum Beispiel zwei Bytes zusammenzählen, dann ist das Ergebnis
dieser Addition nicht auch wieder ein Byte-Wert, sondern immer ein
Integer -Wert.
Das heißt, der wird auf einen größeren Zahlenbereich erweitert.
Wie diese Konvertierungen genau aussehen, das machen wir in der
nächsten Vorlesung in einer Woche.
Fließkomma-Zahlen, hat man gehört, gibt es zwei.
Einmal diese mit geringerer Präzision Float, mit höherer Präzision
Double.
Die implementieren einen Standard, den es für Fließkomma-Zahlen gibt.
Der nennt sich IEEE 754.
IEEE ist eine amerikanische oder internationale Ingenieursvereinigung,
die eben solche Standards festsetzen kann, ähnlich wie die DEAN in
Deutschland.
Und die hat eben diesen Standard festgelegt für Fließkomma-Zahlen.
Die Werte von Fließkomma-Zahlen kann man sich so grob als eine
Teilmenge der reellen Zahlen vorstellen.
Notation ist mit Dezimalpunkt zum Beispiel oder in dieser
wissenschaftlichen Notation, wie wir sie vorher auch schon gesehen
hatten, also zum Beispiel 6,022E23, da steht das E dann für mal 10
hoch.
Aber wie gesagt, kennen Sie von Ihrem Taschenrechner.
Was vielleicht noch interessant ist, ist die interne Darstellung
dieser Zahlen.
Die müssen ja auch wieder auf der Maschine, auf dieser Bit-Ebene
dargestellt werden.
Und das wird so gemacht, dass man die auftrennt dadurch in ein
Vorzeichen, in ein Exponent und eine Mantisse.
Und Exponent ist ungefähr das, was Sie da oben auch schon gesehen
hatten, bei dem 6,022 mal 10 hoch 23, da wäre 23 der Exponent und
diese 6,022 die Mantisse.
Aber auf der Maschine, weil die eben mit Binärzahlen arbeitet, haben
wir jetzt als Basis der Exponentiation nicht die 10, wie in der
wissenschaftlichen Notation, sondern auf dem Computer wird das mit
Basis 2 dargestellt.
Und das heißt, wenn ich jetzt so eine Bit-Repräsentation habe mit
Vorzeichen, Bit, Mantisse und Exponent, dann berechnet sich der Wert
daraus durch diese Formel, die hier angegeben ist, also das Vorzeichen
-Bit fließt mit ein, die Mantisse und eben die Exponentiation mit
unserem Exponenten.
Ein Beispiel, Vorzeichen 1 bedeutet, es ist eine negative Zahl,
Exponent minus 1 heißt, wir müssen mal 2 hoch minus 1 rechnen und
Mantisse gleich 5 ist klar.
Also wenn wir das mal ausrechnen, bekommen wir dann als Ergebnis minus
1 hoch 1 mal 5, die Mantisse, mal 2 hoch minus 1 und es gibt dann eben
minus 5 durch 2, minus 2,5.
Werden Sie im Bedarfsfall auch nochmal nachschlagen, vielleicht, wenn
Sie da genauer in der Zukunft nochmal was dazu wissen müssen.
Hier vielleicht bloß noch, wie unterscheiden sich jetzt die Daten
durch Float und Double?
Die unterscheiden sich eben durch die Anzahl der Bits, die für diese
verschiedenen Bereiche verwendet werden.
Floats haben insgesamt, jeder Float wert 32 Bit, jeder Double wert 64
Bit.
Bei Float werden 23 für die Mantisse verwendet, plus einer für das
Vorzeichen und 8 für den Exponenten.
Bei Double 52 für die Mantisse, das heißt, Sie haben höhere Präzision.
52 binär Ziffern statt 23, auch wieder das Vorzeichen und 3 Bit mehr
im Exponent, das heißt, der Exponent kann Faktor 8 größer sein.
Noch ein paar Besonderheiten gibt es zu berücksichtigen bei den
Fließkomma -Zahlen.
Es gibt da besondere Werte und zum Beispiel gibt es eine extra
Darstellung für Positive Infinity und Negative Infinity, das heißt,
Plusunendlich, Minusunendlich lassen sich auch hiermit darstellen.
Dann gibt es noch einen zusätzlichen Wert, Not a Number.
Wozu könnte man den brauchen auf Kommazahlen?
Division durch 0 wäre denkbar, was Sie sagen, dass das zu so einem
Fehler führt.
Das haben in dem IEEE-Standard sich Designer aber anders überlegt, und
zwar haben die bei Division durch 0 Positive Infinity und Negative
Infinity vorgesehen.
Aber hätten wir natürlich auch so machen können, wie Sie gesagt haben,
ist aber in dem Standard nicht so.
Wozu können wir es da noch verwenden?
Richtig, das wäre denkbar, also was hier gerade gesagt wurde, wenn ich
versuche, eine Konvertierung vorzunehmen von einer Zeichenkette in
eine Fließkomma-Zahl, dass dann diese Zeichenkette eben keine
vernünftige Zahl ergibt.
Also wenn da ABC zum Beispiel drinsteht und nicht 2,5.
Das wäre denkbar, das weiß ich jetzt gar nicht auswendig, ob das so
gemacht wird, das ist anzunehmen, dass da dann Not a Number rauskommt.
Was anderes wäre noch, wenn eben die Operation nicht definiert ist,
das wollten Sie wahrscheinlich auch gerade sagen, zum Beispiel Wurzel
von einer negativen Zahl.
Ist eben nicht definiert auf den realen Zahlen und deshalb wird hier
dafür Not a Number verwendet.
Es wird auch unterschieden zwischen, es gibt nicht einfach die Nulls,
sondern es gibt zwei Nullen.
Es gibt die positive und die negative Null, hat auch wieder mit
Rundungseigenschaften zu tun.
Wie gesagt, ich habe es gerade schon erwähnt, das Stichwort Rundung,
die Operationen werden gerundet.
Es gibt auch wieder eine Präzision, die nicht ausreichen kann, dass
überraschende Ergebnisse entstehen.
Das heißt, bei den Fließkomma-Zahlen muss man noch mehr aufpassen als
bei Ganzzahlen bezüglich Überläufen, bezüglich Rundungsfehler, da kann
es zum Beispiel passieren, dass wenn Sie eine physikalische Simulation
schreiben, dass dann die Werte eben immer weiter von dem eigentlichen
korrekten Ergebnis abweichen.
Gleichheit und Ungleichheit verwenden wir besser nicht, weil eben
diese wenige Präzision drin ist.
Stattdessen lieber Absolutbetrag prüfen, ob der sehr klein ist, der
Absolutbetrag, die Differenz.
Dann machen wir an der Stelle Schluss, machen nächstes Mal den Rest
der Vorlesung und keine Pause mehr dann.