Herzlich willkommen zur vierten Vorlesung von SE1. Ich habe mir so über die Jahre angewöhnt,
immer so ein paar Worte vorweg zu sagen,
wenn es gerade sinnvoll ist, jetzt ist gerade was relativ Wichtiges.
Momentan läuft die vierte oder wir sind jetzt am Beginn der
vierten Woche von SE1 und die ersten vier Wochen bilden ja einen,
waren wir eine inhaltliche Einheit, zumindest haben wir die so geschnitten,
haben gesagt, das ist Level 1 von SE1.
Und was wir euch anbieten, ist ein Online-Selbsttest für das,
was bisher drankam an Themen.
Das heißt, Es geht um die Themen,
die wir in den ersten vier Wochen behandelt haben.
Jeder von euch kann diesen Test durchführen.
Eigentlich sollte jeder von euch diesen Test ziemlich bald durchführen,
damit ihr einfach euren eigenen Lernfortschritt überprüfen könnt.
Die Idee ist, euch früh Feedback zu geben,
ob ihr genügend Zeit investiert habt in diese Veranstaltung.
Muss leider ein bisschen runtersehen, ist halt bei mir.
Ja, müssen wir noch mal so eine kleine Mikroeinstellung machen.
Pegel, ich das Mikro zwei,
Ja, ich hoffe, ihr hört mich noch.
Hört ihr mich noch? Ja. Gut. Ja,
ihr sollt feststellen, ob ihr genügend Zeit investiert habt in die Inhalte dieser Veranstaltung bisher.
Insbesondere heute werde ich relativ viel Zeug erzählen und das macht
dann alles, gehört alles noch zu Level 1.
Also da solltet ihr dann euch noch mal ein bisschen ransetzen.
Idealerweise macht ihr das so, dass ihr diesen Test durchführt,
nachdem ihr das vierte Blatt bearbeitet habt.
Also die ersten Leute, die morgen ihre vierte Übung haben,
können am Abend sich hinsetzen und diesen Test durchführen.
Wir werden also den Test morgen online stellen im Comsee
Also wenn ihr ihn erfolgreich bearbeitet habt,
wenn ihr mit dem vierten Blatt noch nicht durch seid,
dann macht das nicht viel Sinn, diesen Test zu machen,
wartet einfach, bis ihr mit dem vierten Blatt durch seid,
macht dann möglichst schnell den Test.
Und am besten macht ihr ihn alleine und ihr nehmt euch dafür wirklich
eine halbe Stunde Zeit. Der ist nämlich so getimed,
dass ihr das in einer halben Stunde eigentlich ganz gut schaffen können solltet.
Dieser Test steht, als Material im SE1 kommen sie. Das heißt,
es ist keine Hürde vorhanden, diesen Test durchzuführen,
müsst einfach ins Komse gehen, auf das Material darauf gehen,
dann liest ihr euch erstmal den Text durch,
der da steht.
Da steht nämlich eine Erläuterung, wie das mit dem Test funktioniert,
dann würde ich euch bitten,
den in Ruhe durchzulesen
Und dann den Test durchzuführen. Wie gesagt,
nehmt euch eine halbe Stunde Zeit oder reserviert euch eine halbe Stunde,
wenn ihr schneller seid, ist das auch gut,
aber eine halbe Stunde solltet ihr mindestens in Ruhe alleine irgendwo haben.
Ganz wichtig, die Testergebnisse werden auch im Kommensee abgelegt, aber anonymisiert.
Das heißt, wir kriegen eine ganze Reihe von Testergebnissen,
wo wir nicht erkennen können, von wem sie sind.
Also wir wissen nicht, welches Testergebnis zu welcher Person gehört.
Das interessiert uns nämlich eigentlich gar nicht.
Das ist für euch in erster Linie eine Möglichkeit,
Feedback zu bekommen zu eurem Lernfortschritt
Was uns interessiert, ist, dass wir feststellen können,
welche Fragen werden besonders häufig falsch beantwortet,
einfach um festzustellen, wo sind die häufigsten Missverständnisse.
Klassische Fehlverständnisse von Fragen zu SE1. Wenn wir die kennen,
dann können wir die besser adressieren.
Das haben wir die ganzen Jahre durch immer so gemacht,
dass wir feststellen, Mensch,
also immer wieder kommt dieser Fehler zum Beispiel in der ersten Woche,
dass die Studierenden verwechseln Parameter und Zustandsfelder.
Das ist irgendwie so mehr oder weniger das Gleiche.
Ich hoffe, inzwischen ist das euch klar,
dass es ein Unterschied ist,
zumindest in der Terminologie hier
Deswegen interessieren uns dann so die Auswertungen darüber. Diese Auswertungen
kann man tatsächlich dann machen, aber wie gesagt, anonymisiert.
Ihr könnt eure eigenen Ergebnisse aber jederzeit wiederfinden. Wie gesagt,
die werden an das Material rangehängt als eine ZIP-Datei,
also euer individuelles Ergebnis, einer Test eines Testdurchlaufs,
wird als ZIP-Datei an das Material rangehängt.
Da hängen da ganz viele ZIP-Files an diesem Material dran.
Und ihr könnt aber euer eigenes wiederfinden. Wie das geht,
steht in der textuellen Beschreibung. Da steht dann drin,
wie ihr anhand eures, eurer QTI-ID, die in eurem Komsi steht,
dann ist ein bisschen, will ich jetzt nicht erläutern.
Das ist eine Frage. Kann man nicht gestern nochmal nachdenken,
wenn man jetzt irgendwie sprecht nachgearbeitet. Sehr gute Frage.
Er fragt, ob man den Test auch nochmal durchführen kann.
Ihr könnt den Test beliebig oft durchführen. Es ist sogar
so, dass wir jetzt zwei Links zur Verfügung stellen.
Einen, den solltet ihr als ersten wählen.
Da werden die Fragen in der normalen Reihenfolge abgefragt.
Und dann gibt es einen weiteren Link, da gibt es
eine zufällige Reihenfolge. Es sind ja die gleichen Fragen,
aber gebt euch zumindest so gefühlt den Eindruck,
als wenn es denn ein anderer Test wäre.
Ich glaube, der Innervolzieger. Ich glaube,
der Fondue ist noch wo hier.
Oh ja. Freeze off. Juhu. Sehr schön.
Hättet ihr
doch was gesagt
Ich habe mal wieder geschlafen, das heißt,
es war nicht zu sehen,
auf dem Livescreen ist es zu sehen und für die Leute,
die das Video hinterher gucken, das wäre jetzt total gemein,
das darf nicht passieren, dass gerade die,
die in die Vorlesung kommen, einen Nachteil haben.
Also das, was ich gerade gesagt habe,
steht alles auch nochmal da. Also Online-Selbsttest, Level 1,
eigenen Lernfortschritt überprüfen, nach dem vierten Blatt bearbeiten,
möglichst schnell, Ergebnisse hängen dann auch im Komsi,
anonymisiert, ihr könnt eure eigenen Ergebnisse aber wieder finden,
wenn ihr sie sucht
Gut, das war's, was ich sagen wollte zu dem Selbsttest.
Macht ihn, macht gerne, wenn ihr Feedback habt,
dann auch im Kommen sie vielleicht eine Diskussion eröffnen zu den Selbsttests,
machen wir vielleicht auch noch, damit ihr euch auch darüber austauschen könnt.
Es werden einige schwere Fragen dabei sein. Also wir haben hier immer so die Logik,
wo auch mal unseren Klausuren, wir haben schwere Fragen,
die über den von uns vermittelten Stoff hinausgehen,
wo wir einfach sagen, naja,
wenn Leute auch mal so ein bisschen was lesen über die Veranstaltung hinaus,
dann könnten sie das wissen.
Und das sind dann aber nur maximal zehn Prozent der Fragen.
Aber solche Fragen sind da auch drin,
also wundert euch nicht,
wen ihr ganz schön zu knapsen habt an manchen Dingern
So, jetzt. Heute schließen wir einen ganz entscheidenden Teil ab,
nämlich Level 1. Und auf Level 1 haben wir uns mit
den objektorientierten Grundlagen beschäftigt, aber auch mit imperativen Grundlagen.
Und heute machen wir nochmal so ein paar weitere imperative Grundlagen.
Und das ist tatsächlich relativ viel Zeug. Also das ist, ja,
dicht gedrängt, was hier an Begriffen jetzt noch kommt und auch an Konzepten.
Ich werde vor der Pause mehr oder weniger alle vier Themen anschneiden,
also nicht nur, wie das hier angedeutet ist,
Operatoren vor der Pause waren, sondern auch etwas generell zu Basistypen sagen.
Also insgesamt geht es erstmal um
Variablen nochmal? Was ist eine Variable in der imperativen Programmierung?
Zuweisungen und dann kommen wir darauf, dass ja bei einer Zuweisung
immer Ausdrücke beteiligt sind und in den Ausdrücken kommen Operatoren vor.
Wir gehen also immer weiter runter auf die Grundbausteine,
bis wir dann irgendwann bei den Basistypen sind,
die da als Operanten dann auch auftreten in den Ausdrücken.
Und gucken uns in der zweiten Hälfte an, wie das
genau in Java gebaut ist. Gut, noch einmal,
diese Folie habe ich schon mal gezeigt. Ganz wichtig,
dass ihr euch, dass ihr im Hinterkopf habt,
dass es sowas gibt wie Variablen und das in einer Sprache wie Java,
wo die Typen deklariert werden müssen bei einer Variablen,
wo man wirklich sagen muss, diese Variable soll vorm Typ Int sein,
soll also nur Werte vom Typ Int aufnehmen können.
Dass in solchen Sprachen eine Variable immer aus einem Typ und einem Namen besteht.
In Java steht der Typ zuerst da und dann der Name.
Und dann ist es eben wichtig,
dass so eine Belegung einer Variablen sich ändern kann.
Okay, nur noch mal jetzt hier,
welche Arten von Variablen wir bisher kennengelernt haben.
Wir haben Exemplarvariablen kennengelernt, die den Zustand von Objekten halten.
Hier ist eine Klassendefinition, die ihr schon mehrfach gesehen habt.
Also das ist jetzt hoffentlich für euch nichts Neues mehr,
klasse Girokonto mit einer Exemplarvariablen und einer Methode einzahlen
Und an diesem minimalen oder sehr kleinen Beispiel einer Klasse
kann man eigentlich alle drei variablen Arten sehen.
Haben wir natürlich explizit ein bisschen hier so hingechincht,
dass da auch eine lokale Variable auftritt.
Hier haben wir eine Exemplarvariable, Konvention SE1 mit Unterstrichbeginn,
den Namen. Dann haben wir hier einen formalen Parameter,
erkennbar daran, dass er im Kopf einer Methode steht.
Ein Typ und einen Namen hat. Und hier haben wir
eine lokale Variable. Und was da passiert ist,
dass dieser Betrag hier, der hier übergeben wird,
der wird irgendwie mit dem bestehenden Saldo addiert.
Und das Ergebnis dieser Addition wird in der Variablen
Neuer Saldo abgespeichert
Und hinterher wird dann das, was in der Variablen Neuer Saldo steht,
in der Variablen Saldo abgelegt. Das ist quasi im Schnelldurchlauf das,
was wir uns gleich noch mal ein bisschen genauer angucken,
weil jetzt hier einiges auftritt, was wir diskutieren werden,
also dass hier zum Beispiel ein Ausdruck steht,
hier auf der linken Seite einer Variable steht und so weiter.
So, diese Variablen Arten müssen alle deklariert werden.
Ja, das ist einfach so. Ihr müsst, bevor
ihr eine Variable in Java verwenden wollt, sie deklarieren.
Es gibt Sprachen, in denen das nicht notwendig ist.
Wie gesagt, wir gucken uns hier solche Sprachen nicht an
Und ja, Exemplar war ja mit einer Klassendefinition für alle Exemplare. Das heißt,
wenn ich in der Klassendefinition eine Exemplar war, ja behindschreibe,
heißt das, dass jedes Exemplar diese Variable auch hat.
Ich habe zufällig Blue Jay dabei und zeige euch hier mal
eine Klasse, die ihr kennt.
Das ist mehr oder weniger die gleiche Klasse wie gerade auf der Folie.
Nur jetzt hier Klasirokonto in Saldo. Jetzt gibt es aber
hier einen Konstruktor, okay, Konstruktor kennt ihr auch,
damit initialisiert man ein neu erzeugtes Exemplar
Ja, das hier ist ein Konstrukt für Parameter, ein formaler Parameter.
Dann gibt es hier ein Einzahlen und dann gibt es hier
aber noch eine weitere Methode, nämlich Gibsaldo.
Das ist eine sondierende Methode, während das hier eine verändernde Methode ist.
Ja, weil diese verändernde Methode ändert den Zustand des Exemplars,
auf dem sie aufgerufen wird.
So, was ich jetzt eigentlich zeigen will, ist,
dass diese Variablen auch eine Anfangsbelegung haben, beziehungsweise initialisiert werden müssen.
Also hier Anfangsbelegung der Variablen Arten. Exemplarvariablen werden automatisch mit
einem Standardwert belegt
Diesen Standardwert gucken wir uns gleich noch an.
Es kommt noch später, was für jeder Typ,
den es in Java gibt, hat einen Standardwert.
Ein Default Value, die formalen Parameter, das ist klar,
die sind immer belegt mit dem, was der Aufrufer angegeben hat.
Bei einem formalen Parameter ist es ja so, dass irgendjemand
das Ding aufgerufen haben muss und der musste ja einen aktuellen Parameter angeben.
Und die lokalen Variale, die müssen wirklich explizit initialisiert werden.
Das kann man sich mal hier jetzt live angucken,
indem ich jetzt einfach mal hier in diesem Konstruktor einen Haltepunkt setze.
Und sozusagen die Exemplarerzeugung mal anhalte, also nicht die Exemplarerzeugung,
falsch, die Exemplarinitialisierung.
Also ich initialisiere hier ein Girokonto,
mach da mal zehn
Euro als Anfang Saldo, gebe ich da an.
Jetzt ist der Konstruktor gerade aufgerufen worden. Und wir sehen
hier Anfang Saldo, ist hier als lokale Variable aufgeführt.
Ganz wichtig, formale Parameter sind aus Sicht des Debuggers,
aus Sicht des Laufzeitsystems von Java,
sind lokale Variablen und formale Parameter synonym.
Das heißt also, die formalen Parameter werden hier aufgeführt unter
lokale Variablen. Gut, also Anfang Saldo ist gleich 10.
Der Saldo ist aber noch null. Das heißt,
dieses Exemplar wurde erzeugt und der Saldo wurde schon
auf null initialisiert
Das ist in Java so, das Exemplar Variablen auf einen Default-Wert initialisiert werden.
Bevor man irgendwas tut, selbst bevor man im Konstruktor
es initialisiert, hat das Ding schon eine Belegung.
Das ist von der Sprache garantiert. Es gibt andere Sprachen,
da ist das nicht garantiert, zum Beispiel in C Plus Plus.
In Java ist das klar, dass eine Exemplar variable eine
Belegung hat, eine Anfangsbelegung. Wir sorgen jetzt dafür,
dass der Anfang Saldo hier 10 ist,
wenn ich jetzt also hier Schritt übermache, das heißt,
die gelb unterlegte Zeile wird ja jetzt noch ausgeführt,
da stehen wir gerade, dann sieht man,
dass jetzt Saldo auch 10 ist.
Das heißt also, diese Zuweisung ist erfolgt und in Saldo
steht jetzt dieser Anfangswert drin
Gut, jetzt kann ich hier versuchen, einen Haltepunkt hinzusetzen, einen weiteren.
Das geht nicht, weil das nur eine Deklaration ist.
Eine Deklaration ist keine Anweisung im Java-Sinne. Ich kann also nur eine Haltepunkt setzen,
da wo irgendwo tatsächlich hier zum Beispiel wirklich was passiert,
wo auch zur Laufzeit irgendwas passiert.
Okay, jetzt habe ich hier einen weiteren Haltepunkt hingesetzt.
Jetzt kann ich also tatsächlich an meinem,
ich muss mal hier noch erstmal fortsetzen, aufrufen,
der Debugger ist nicht so weit.
Jetzt habe ich mein Exemplar, der Konstruktoraufruf,
die Exemplarerzeugung ist durchgelaufen.
Jetzt kann ich hier
ein Zahn aufrufen
Und gebe wieder irgendwas an. Also 20 soll ich einzahlen.
Jetzt stehe ich wieder an dieser Stelle hier, an dieser, hier.
Habe also jetzt Betrag als lokale Variable, wird 20 sein,
weil ich gerade 20 als aktuellen Parameter angegeben habe als Klient.
Und jetzt sieht man hier, dass diese lokale Variable
neuer Saldo noch gar nicht zu sehen ist.
Also die ist hier noch gar nicht aufgetaucht in der Laufzeitumgebung.
Bei der Laufzeit ist es einfach so,
das Ding ist hier erstmal nur deklariert.
Das ist was, was im Quelltext steht. Aber an
der Laufzeitumgebung passiert da noch nichts. Jetzt an dieser Stelle,
und das ist ganz wichtig,
an dieser Stelle wird jetzt die lokale Variable initialisiert,
ihr müsst lokale Variablen initialisieren,
bevor ihr
sie benutzen dürft
Also habe ich hier jetzt, schreibe ich etwas rein,
ich habe, berechne hier auf der rechten Seite
irgendetwas und schreibe das in diese Exemplarvajabe rein.
In diese lokale Variable. Also wenn ich jetzt hier einen Schritt übermache,
dann sieht man, jetzt ist tatsächlich auch die lokale Variable hier vorhanden.
Diese lokale Variable ist jetzt bekannt, hat eine Belegung.
Und anschließend schreibe ich ja den Wert, der da drinsteht,
in meine Exemplarvajable rein. Das ist das,
was jetzt als nächstes passieren wird, wenn ich jetzt Schritt übermache,
dann ist tatsächlich der Saldo auf 30 erhöht.
Okay, wenn ich das fortsetze, dann ist das jetzt hier tatsächlich auch passiert.
Gut, und ich kann tatsächlich dann hier auch abfragen,
gib mir den Saldo und er ist tatsächlich 30.
So, das ist ganz ganz wichtig,
dass ihr euch das klar macht. Exemplar war ja,
haben eine automatische Vorbelegung, formale Parameter haben auch eine automatische Vorbelegung.
Lokale Varianten haben keine automatische Vorbelegung. Ihr müsst erst etwas reinschreiben,
bevor ihr etwas rauslesen dürft. Gut, dann ganz wichtig auch
, man kann eine Variable auch verändern. Ich kann,
und das ist anders als in der Mathematik,
da sind Variablen Variablen, die können variabel beliebt sein,
aber irgendwann haben sie dann einen Wirten,
den ändern sie auch nicht mehr.
Das ist hier anders.
Ich kann hier jetzt eine Variable deklarieren und die gleich
mal initialisieren
Ja, jetzt habe ich eine Variable deklariert,
das kann ich mal fragen, was ist denn der Wert von I?
Der ist null. Klar, weil ich ja null zugewiesen
habe bei der Initialisierung. Aber ich kann jetzt schreiben,
I ist gleich 9. Zack, dann habe ich I auf 9 gesetzt.
Das heißt, ich habe die Belegung der Variablen verändert.
Ganz wichtig, das ist ein Behälter, so eine Variable,
wie dieser Gewürzstreuer. Ich kann sozusagen den Füllgrad in diesem
Gewürzstreuer verändern und dadurch kriegt diese Variable eine neue Belegung.
Wir nennen das Variablen Belegung. Einfach um klar zu machen,
dass da verschiedene Belegungen vorhanden sein können
Gut, die Zuweisung haben wir jetzt schon gesehen.
Also bei der Zuweisung wird ein Ausdruck ausgewertet und sein Ergebnis
einer Variablen zugewiesen. Das haben wir gerade live gesehen.
Ich habe zum Beispiel dieser lokalen Variablen, neuer Saldo,
irgendetwas zugewiesen, was auf der rechten Seite stand.
Also hier stand zum Beispiel Neuer Saldo ist gleich. So,
es steht auf der rechten Seite, steht hier ein Ausdruck.
Ein Ausdruck ist irgendeine Berechnungsvorschrift. Kommen wir noch genauer drauf
. Und die Syntax ist eigentlich ganz einfach.
Man hat eine linke Seite, man hat den Zuweisungsoperator,
man hat eine rechte Seite. Rechte Seite, imperativ,
meist arathmetische und bulsche Ausdrücke, Vergleiche, Zeichen,
Zeichen,
Ketten,
Zuweisendes Operator in Java, ist das Gleichheitszeichen. Ganz fiese Falle.
Kann man leicht verwechseln mit dem Frage auf Gleichheit, diesem Gleichheitsoperator.
Der sieht in Java ja etwas anders aus, kommen wir gleich noch drauf.
In Pascal haben die zum Beispiel diesen Doppelpunkt gleich genommen,
um deutlich zu machen, naja,
das ist irgendwie was anderes als Vergleich,
sondern es ist eher sowas wie eine Zuweisung.
Es gibt auch Sprachen, da hat man so einen Pfeil genommen,
von rechts nach links, damit deutlich wird,
dass auf der rechten Seite wird dem auf der linken Seite irgendwie zugewiesen.
Auf der linken Seite steht üblicherweise eine Variable.
Ihr könnt auf der linken Seite nicht hinschreiben,
i plus
Geht nicht. Das wäre ein Ausdruck. Ein Ausdruck kann nicht
auf der linken Seite einer Zuweisung stehen. Ganz wichtig auch,
Typ Kompatibilität, das heißt, der Typ,
der Variable auf der linken Seite und der Typ des Ausdrucks
auf der rechten Seite, die müssen zueinander passen.
Ihr könnt also nicht schreiben, sowas wie I ist gleich hallo.
Wird nicht gehen, Incompetible Types. Sehr schön. Der Compiler weiß,
was für ein Typ das Ding hat hier auf der rechten Seite.
Das ist das Hallo. Der Compiler weiß auch,
was die Variable für einen Typ hat und kann dann sagen, nee,
also eine Zeichenkette kannst du nicht in einer Intager-Variablen abspeichern.
Hilft uns und klopft uns auf die Finger.
Sehr gut. Zuweisung in der Syntax von Java Level
1. Da habt ihr ja diese, ja, ich weiß,
ich habe da, ich habe geflucht in den Übungen über die,
über die EBNF und über die Syntax-Darstellung.
Ihr werdet das irgendwann hoffentlich zu schätzen wissen,
dass ihr das Zeug mal hier so ein bisschen gesehen habt.
Es ist einfach ein sehr nützlich Syntax-Beschreibung von Programmiersprachen lesen zu können.
Und wenn ihr dann so diese Grundideen von EBNF verstanden habt,
dann könnt ihr von jeder Programmiersprache die Syntaxbeschreibung lesen.
Also das ist eine Investition in die Zukunft für euch.
Okay, ein bisschen genauer hingeguckt bei der Zuweisung, nicht zu genau.
Es ist so, dass wir ja immer von der linken
und der rechten Seite sprechen. Ich habe eben gesagt,
auf der linken Seite muss immer eine Variable stehen.
Also ein Zielbehälter, wo etwas reingeschrieben werden kann.
Diese linke Seite wird auch oft L-Wert genannt. Das ist ein Begriff,
die kommen aus dem Compiler-Bau, also aus der Theorie in
der Informatik über die Art und Weise, wie man Compiler baut.
Und L-Wert ist üblicherweise bezeichnet einer Variablen, der einen Speicherplatz zugeordnet ist.
Dort wird der neuberechnete Wert gespeichert, an einen R-Wert ist
ein Ausdruck. Wie gesagt, was ein Ausdruck ist,
da kommen wir gleich noch genauer drauf.
Und ein R-Wert kann üblicherweise nur rechts vom Zuweisungsoperator stehen.
Ich kann also nicht sowas schreiben wie I plus 5 ist gleich I.
Könnte man ja meinen, dass dieses Gleichheitszeichen irgendwie,
weil es ja so symmetrisch aussieht, wie der Vergleich in der Mathematik,
dass das irgendwie geht, aber das funktioniert nicht.
An Expected Type, Required variable, Found Value,
ja, also das sieht man schon,
das funktioniert nicht.
Hier ist es noch mal vielleicht so, also einem
kleinen Beispiel, A ist gleich A plus 3 mal I.
Also das, was hier auf der rechten Seite steht,
wird ausgewertet, A plus 3 mal I,
was auch immer diese Variablen für Typen haben,
was da für Werte rauskommen.
Aber hier wird aus dem A etwas rausgelesen. Das heißt,
die Belegung wird ausgelesen, dass da drin steht in dem A.
Und das Ergebnis der Berechnung wird dann wieder in A gespeichert.
Also hier ist es die Quelle einer Information.
Hier ist es das Ziel einer Information.
Okay. Insgesamt passiert da also einiges in der Zuweisung,
aber das werdet ihr noch so oft zu sehen bekommen,
dass ihr das auch sicherlich irgendwann gut verinnerlicht habt.
Zuweisung in Java, wie gesagt, mit dem Gleichheitszeichen, ziemlich blöd.
Hier zum Beispiel Antwort ist gleich 40. Vermutlich ist deine Antwort
vom Typ In. Könnte auch ein anderer Typ sein,
da kommen wir noch mal ein bisschen drauf gleich.
Antwort plus gleich zwei ist eine mögliche Schreibweise,
eine verkürzende Schreibweise in Java für Antwort ist gleich, linke Seite.
Antwort plus zwei. Das kann man so verkürzt so hinschreiben.
Hat kleine Optimierung, hat auch kleine Unterschiede in der Semantik.
Wenn ihr das benutzen wollt, benutzt es.
Ich denke, für die Programmieranfänger ist das erstmal schlauer,
sich explizit hinzuschreiben, was denn links und was rechts steht.
Hier ist das so ein bisschen implizit.
Also eher vorsichtig zu handhaben. Hier haben wir etwas,
was interessant aussieht, korrekt,
kriegt zugewiesen das Ergebnis der Berechnung von Antwort gleich,
gleich 42. Okay, also Antwort ist vermutlich eine Intager-Variable.
42 ist eine Intager-Literar, die werden verglichen.
Da kommt ein Wahrheitswert raus, entweder ist das True oder Falls.
Und das wird hier einer Variablen korrekt zugewiesen.
Vermutlich ist korrekt vom Typ Bulien. Bulsch-Variablen,
sowas gibt es tatsächlich auch und die werden wir
uns auch noch ansehen gleich
Also haben wir hier diese Operatoren für Gleichheit und Ungleichheit,
nicht zu verwechseln mit der Zuweisung. Ganz wichtig, haltet das
auseinander. Ihr werdet immer wieder in solche Sachen reinlaufen,
dass ihr aus Versehen statt gleichgleich, wo ihr gleich gleich meint,
gleich schreibt und dadurch verändert sich euer Programm erheblich.
Also bitte darauf achten, nicht verwechseln.
Gut, soviel zur Zuweisung. Jetzt habe ich gesagt,
auf der rechten Seite einer Zuweisung steht ein R-Wert oder auch
ein Ausdruck und jetzt zoomen wir wieder weiter rein.
Wie ist denn so ein Ausdruck aufgebaut?
Was kann denn so ein Ausdruck alles sein
Und ja, wir haben jetzt hier gesehen,
also zum Beispiel sowas wie hier,
A ist gleich A plus 42, da sehen wir,
dass ein Ausdruck aus verschiedenen Bestandteilen besteht,
nämlich aus Operanten und Operatoren.
In diesem Beispiel hier ist der Operator das Plus-Zeichen und
wir haben hier zwei Operanten, nämlich A und die 42.
Das sind die Operanten. Diese Begriffe kennt ihr sicherlich aus
der Mathematik, Operator, Operanten. Was aber ganz wichtig ist,
dass so ein Ausdruck hier eine Verarbeitungsvorschrift ist. Das heißt,
hier sagen wir als Programmierer, hey Compiler, mach mal bitte aus dem,
was ich hier hinschreibe, eine Verarbeitungsvorschrift, damit dann,
wenn das Programm ausgeführt wird, der Computer irgendetwas berechnet.
Hier wird nicht direkt jetzt etwas berechnet im Quelltext,
wenn ich das hinschreibe, sondern erst zur Laufzeit.
Klar, also eine Verarbeitungsvorschrift, die hier gesetzt wird.
Hier steht Adire, die Belegung der Variablen A mit dem
Wert 42. Okay. Das ist aber jetzt ganz wichtig,
dass hier diese Operation, die hier wirklich ausgeführt wird,
abhängig ist davon, was für Typen hier A,
was für ein Typ A hat
Also der Operator ist Plus, aber welche konkrete Operation ausgeführt wird,
da gibt es mehrere Möglichkeiten. Wer kann mir denn mal sagen,
was A, möglicherweise hier oder welchen möglichen Typ kann A haben?
Wer schmeißt mir was in den Kopf, ja? String,
oh, das ist schon fortgeschritten, ja,
also tatsächlich String, ja, also das geht tatsächlich,
ich kann das hier mal zeigen,
ich kann also ein String S ist gleich ein leerer String,
habe ich hier deklariert, Lehrer String,
jetzt kann ich schreiben, S ist gleich S plus Zwei.
Steht das hier mit der auf der Folie?
Erst ist gleich, nee, 42, oh, natürlich.
Erst ist gleich erst plus 42. Kann ich schreiben.
Und dann ist S 42. Das heißt, die Zeichenkette,
die leer war, da wird eine 42 drangehängt.
Also wenn ich jetzt hier das Gleiche nochmal mache,
es ist gleich S plus 42,
dann wird wirklich da S 42, 42,
also wirklich diese Zeichen werden einfach aneinander gekettet.
Eine richtige Möglichkeit, was gibt es noch für Möglichkeiten,
was könnte das noch für ein Typ sein, hier das A?
Intager. Ja, klar, das haben wir ja eben schon gesehen,
habe ich ja auch schon ein bisschen gezeigt.
Also ich kann auch hier jetzt schreiben,
meine Variable I ist gleich
I plus 42. Kann ich hinschreiben. Und dann ist I
51, weil vermutlich vorher die Neuen drin war.
In meinem I. Gut, was kann es noch für ein Typ sein?
Ja. Indiger haben wir schon gehört. Noch ein anderer Typ.
Ja. Double oder Float? Sehr gut. Ja,
das kann auch sein. Also es kann eine Gleitkommazahl sein.
Das schauen wir uns später noch ein bisschen genauer an.
Da oben ist noch ein Vorschlag. Da kommt noch
der Vorschlag, es könnte Cha sein. Ja,
das könnte man vermuten, dass das möglich ist.
Tatsächlich kann ich Ein Char, mir deklarieren, eine Variable,
die einzelne Zeichen aufnimmt und kann die initialisieren mit zum Beispiel
dem Großen A. Kann ich hier so hinschreiben.
Und dann gucke ich mir den Wert,
die Belegung von Char, das ist dann ein kleines Anführungsstreckelchen,
das A. Und ich kann jetzt schreiben, Char plus 2.
Das geht tatsächlich, aber es kommt da raus, 67. Komisch.
Das ist nämlich ein Int. Und das gucken wir uns
heute auch noch an, dass da,
wenn da jetzt ein Char stünde, dann wäre diese Anweisung,
diese Zuweisung insgesamt nicht gültig.
Warum erkläre ich noch
Das ist schon mal so ein kleines Rätsel für die,
die schon vielleicht ein bisschen mehr wissen,
dass sie dann schon mal drüber nachdenken,
warum das mit einem Char hier nicht funktionieren kann.
Die Auflegung gibt es nachher. Gut, also was
haben wir jetzt gesehen? Ein Ausdruck ist irgendwie sowas,
was zusammengesetzt ist aus Operanten, aus Operatoren.
Diese Operatoren können unterschiedliche Operationen bewirken, abhängig vom Typ der Operanten.
Und was man dann braucht, sind diese Operatoren. So,
jetzt gibt es da relativ viele verschiedene Operatoren, die Java anbietet.
Es ist ein fest definierter Satz an Operatoren in Java,
aber jede Programmiersprache hat irgendwie so etwas
wie Operatoren
Und wir unterscheiden, wie gesagt, explizit die Operatoren,
also die Zeichen, die man hinschreibt,
von den Operationen, die damit verknüpft sind.
Bei dem Plus haben wir das gerade gesehen,
das Plus kann bei Int eine Intager-Addition sein.
Es kann bei Streamen eine String-Konkratenation sein, also Zeichenverkettung,
eines Trinkverkettung. Es kann bei Gleitkommazahlen eine Gleitkomma-Addition sein,
eine andere Operation. Da passiert wirklich was anderes bei der
Berechnung. Also unterscheiden wir und was ganz wichtig ist,
wenn wir uns mit Operatoren beschäftigen,
wir gucken jetzt mal so ein bisschen genau hin,
es so für Operatoren gibt und was es vor allen Dingen für Vereinbarungen über Operatoren geben kann.
Da gibt es eine ganze Menge,
wenn wir nämlich so einen relativ komplizierten Ausdruck vor uns sehen,
dann müssen wir ja wissen,
ja, was wird da jetzt in welcher Reihenfolge ausgewertet?
Das ist überhaupt nicht trivial, wenn man da ein bisschen sich mit beschäftigt,
was in einer Programmiersprache da alles so möglich ist.
Wenn ihr so etwas seht, wie,
ich schreibe mal sowas hin, wie 5 plus 6 mal 8,
dann wisst ihr, das ist ein Ausdruck
Und das ist vermutlich, 6 mal 8 ist 48,
plus 5 ist 53. So. Das wisst ihr, weil ihr
aus eurer Mathematikvorbildung mitnehmt, Punktrechnung vor Strichrechnung. Hoffe ich,
dass ihr das macht, dass ihr nicht irgendwie ausrechnet,
A, 5 plus 6 ist 11, 11 mal 8 ist 88.
Also es ist 53. Das ist etwas, was in Programmiersprachen abgebildet ist,
aber deutlich mächtiger als das, was ihr aus der Mathematik kennt.
Also es gibt nicht nur die Grundrechenarten für deprimitiven Typen wie Int- oder Gleitkommazahlen,
sondern auch bei Strings gibt es ja diese Möglichkeit,
das Plus zu verwenden. Und es gibt Sprachen,
da kann man diese Operatoren beliebig überladen und kann sagen,
das ist jetzt eine Operation für zwei komplexe Zahlen,
zum Beispiel, wenn ihr euch komplexe Zahlen selbst definieren wollt.
Das heißt, ihr braucht Vereinbarung, ihr müsst verstehen,
wie so ein Ausdruck ausgewettet wird und da gibt es eben halt Aspekte der Position,
wo die Operatoren stehen, dann ihre Stelligkeit, der Präzedenz und der Assoziationsreihenfolge.
Die gucken wir uns jetzt mal im Detail an.
Das erstens die Position von Operatoren. Also wo steht
der Operator in Bezug auf seine Operanten? Das,
was ihr kennt, ist Infix, also 3x4,
da steht der Operator zwischen seinen beiden Operanten
Es gibt auch Präfix-Operatoren, da steht der Operator davor.
Wenn ihr zum Beispiel jetzt in Java sowas hinschreibt wie minus eins,
dann ist das nicht eine Eins mit einem Vorzeichen.
Das ist also, das ist jetzt kein integral literal,
sondern das ist eine Eins, worauf der Operator Negation angewendet wird.
Das ist ein kleiner Unterschied. Also minus eins ist tatsächlich
die minus eins. Das ist aber tatsächlich ein Operator ist,
dieses minus kein Vorzeichen. Man darf üblicherweise nur ein Vorzeichen
hinschreiben. Ihr könnt aber zwei Vorzeichen hinschreiben.
Minus minus eins. Was ist minus minus eins
Ich höre nichts. Werft es mir in den Kopf.
Eins, ja genau, plus eins. Doppelte Negation,
also der Operator, minus eins wird nochmal negiert und
es wird dann wieder plus eins. Ich langweile euch,
ich weiß, aber das gehört halt so ein bisschen dazu,
dass man sich das sehr genau anguckt.
Postfix, der Operator steht danach, das ist was,
was wir aus der Mathematik kennen,
was ist in Java auch an bestimmten Stellen gibt,
dass der Operator hinter seinen Operanten steht.
Hier zum Beispiel, was es in Java nicht gibt,
drei Fakultät, da steht der Operator tatsächlich hinter seinem Operanten
Dann gibt es die Stelligkeit eines Operators. Auch da ganz wichtig,
er kann einstellig sein, also er hat nur einen Operanten.
Das minus eins war auch,
da war der Operator minus und der Operant war die eins,
einstellig, u näher, zweistellige Operatoren kriegen zwei Argumente oder zwei Operanten.
Das Mal hier bekommt die beiden Operanten 3 und 4. Es gibt auch dreistellige Operanten,
Operatoren, aber das ist dann eher so ein bisschen so,
sagen wir, so ein Spezialgebiet der Programmiersprachen,
das zum Beispiel sowas hier wie If Than Ells.
In Java gibt es eine Abkürzungsform dafür und das
ist dann ein ternärer Operator
Wer ihn verwenden will, kann ihn verwenden, wir empfehlen es erstmal nicht so.
Zum Lernen eher verwirrend. Präzedenz von Operatoren, das ist wieder
ganz wichtig, habe ich eben schon als Beispiel gehabt.
Es gibt eine Vorrangregel, das heißt,
es gibt Operatoren, die binden stärker.
Also hier in diesem Beispiel 3 plus 5 mal 7,
minus 3, da ist es klar,
dass 5 mal 7 zuerst ausgerechnet wird.
Das muss aber in einer Programmiersprache explizit definiert werden.
Also für Java ist das auch definiert,
welche Präzedenzen
die Operatoren haben
Sehr klar definiert. Das heißt, hier ist klar,
das wird zuerst ausgewertet und ja, was kommt dann?
Kommt dann das Plus oder kommt dann das Minus?
Das ist eine andere Frage, die gucken wir uns gleich an.
Wenn ich diese Präzedenz ändern will, dann kann ich explizit klammern.
Das könnt ihr in Java immer machen. Es ist sogar eine gute Idee,
dass immer explizit zu tun, um die Lesbarkeit zu erhöhen.
Damit man einfach als Leser sofort sieht, ja,
ich möchte jetzt hier, dass das zuerst ausgerechnet wird.
Auch wenn die Präzedenzen der Operatoren das eigentlich vorgeben,
ist es immer noch besser, das explizit nochmal zu klammern. So,
ich habe eben schon gesagt, dann gibt es noch diese Frage,
was ist mit Operatoren, die gleichberechtigt sind,
also zum Beispiel hier 5 minus 4 minus 3,
da ist es ja schon wichtig,
ob das jetzt von links nach rechts oder von rechts nach links ausgewertet wird.
Kommt nämlich was Verschiedenes raus. 5 minus 4 ist 1,
1 minus 3 ist minus 2. Wenn ich das aber von rechts auswerte,
dann kommt zuerst 4 minus 3,
das ist 1 und 5 minus 1 ist 4.
Der Unterschied zwischen minus 2 und 4 ist relativ groß. Also,
da muss auch klar sein, wie die Dinge,
wenn sie gleichberechtigt sind, die Operatoren,
ob die von links oder von rechts ausgewertet werden.
Auch das ist komplett festgelegt für Sprachen wie Java
Also hier so eine implizite Klammerung. Wenn das von links
geklammert ist, ist das Ganze linksassoziativ. Es kann natürlich auch
recht assoziativ sein. Letzte Woche hatten wir dieses Beispiel,
hatte ich so angedeutet, A plus B ist nicht das
Gleiche wie B plus A. Syntaktisch ist das was anderes.
Es sieht ja anders aus. Also syntaktisch ist es was anderes.
Semantisch ist natürlich 3 plus 4 das Gleiche wie 4 plus 3.
Das heißt, was da wirklich dann in der Auswertung rauskommt,
ist das Gleiche.
Okay, und hier ist es eben halt auch egal,
wie man das denn klammert
So oder so geklammert werden, in dem Fall,
weil eben halt hier der Operator assoziativ ist.
Die Operation, die Addition von Inns. Gut,
hier jetzt mal so die zentralen Operatoren in Java,
die ihr primär kennen solltet.
Die solltet ihr auf Level 1 alle mal irgendwie gesehen haben.
Ihr solltet wissen, wie man sie benutzt. Alle mal ausprobieren,
alle mal irgendwie in Blue Jay mal eintippen,
mal so ein paar Ausdrücke hinschreiben.
Diese hier, die müsst ihr nicht unbedingt kennen.
Die haben wir damit aufgeführt, weil die so häufig und gerne
von den Leuten benutzt werden, die ja schon Java können.
Mit allen Vor- und Nachteilen, die damit verbunden sind.
Also dieses Plus-Plus und dieses Minus-Minus
Fieses Zeug. Da kann ich euch jetzt mal so ein paar lustige Sachen zeigen.
Also ich habe hier die Variable I, die hat den Wert 51.
Wenn ich jetzt schreibe I plus plus,
dieses plus plus darf ich nur auf Variablen anwenden.
Das heißt, so viel wie erhöhe die Belegung der Variablen I um eins.
Das kann ich so hinschreiben. Und siehe da, I
ist hinterher 52. Toll. Es ist aber etwas gemeiner,
wenn ich nur den Ausdruck betrachte, I plus plus.
Wenn ich mir das jetzt angucke,
was würdet ihr jetzt vermuten, wenn ich jetzt Return mache,
ohne einen Semikolein hinzuschreiben?
Dann ist es ja
ein Ausdruck
Die meisten würden erwarten, dass da eine 53 rauskommt.
Das Ergebnis ist aber, überraschend 52. Und I ist trotzdem
jetzt 53. Oh, das ist ja komisch.
Und das ist genau der Schaden an diesem Postfix-Operator,
das bin ich jetzt eine Variable in J deklariere.
In J ist gleich I plus plus.
Dann hat das folgende Bedeutung, der Postfix-Operator sagt,
nachdem der Ausdruck ausgewertet wird, wird I um eins erhöht.
Nachdem der Ausdruck ausgewertet wurde. Der Ausdruck hat
die Belegung i, also 53 in diesem Fall.
Und dieser Wert des Ausdrucks wird auch J zugewiesen. Das heißt,
nach dieser Zuweisung hat J den Wert 53 und i den Wert 54. Total bescheuert.
J53, i 54. Wenn ihr so etwas braucht,
Liebe, Hardcore-Java-Programmierer, dann würde ich euch bitten,
macht es doch so, dass ihr schreibt,
J bekommt die Belegung, bekommt den Wert von plus plus i.
Wenn ihr unbedingt innerhalb eines einer Anweisung sowohl die Belegung einer Variablen erhöhen wollt,
als auch einer anderen Variante das Ergebnis zuweisen wollt,
dann schreibt das als Prefix
Jetzt ist es so,
die Belegung von Ivid vor der Auswertung des Ausdrucks erhöht,
also Ivid 55, und J wird auch 55 haben.
Also J gleich plus plus I, dann ist J 55
und I ist 55 und alles ist gut.
Also bitte, wenn diesen blöden Operator verwenden, dann nur Präfix.
Sonst habt ihr eine perfekte Gelegenheit geschaffen,
euch irgendwann selbst ins Knie zu schießen.
Lasst es einfach sein. Das hier sind alle Operatoren in Java.
Das ist wirklich alles, was ihr zu Operatoren in Java
wissen müsst. Auf einer Folie, kompakt, großartig.
Ganz einfach für euch zu merken, Man sieht ja alles.
Man sieht hier die Präzedenz. Also zum Beispiel,
dass diese Operatoren hier am stärksten binden und die sich ja am schwächsten.
Also dieses Zuweisungssymbol ist sozusagen das, was zuletzt ausgewertet wird.
Macht ja Sinn. Zuerst wird der ganze Ausdruck ausgewertet und
am Ende wird das dann der linken Seite zugewiesen.
Man sieht aber auch, dass zum Beispiel Stern,
höhere Präzedenz hat als Plus.
Das ist hier in Java einfach so definiert.
Also man sieht hier diese Präzedenzen ausführlich aufgeführt in Rot.
Dann sieht man die Assoziativität. Also dass zum Beispiel mal
Plus geteilt, das assoziiert alles von links nach rechts.
Also es wird von links nach rechts ausgewertet
Aber es gibt auch Dinge, die werden von rechts und links ausgewertet.
Dieser hier, der ist so ein bisschen speziell,
aber zum Beispiel hier bei der Zuweisung ist es so,
dass natürlich von rechts und links ausgewertet wird.
Zuerst rechts und dann links. Das solltet ihr euch quasi irgendwo auf dem Schmierzettel schreiben,
dieses Ding, weil das könnt ihr immer wieder vergebrauchen,
wenn ihr verstehen wollt, was bei einem Ausdruck rauskommt.
Da steht alles drauf, was ihr wissen müsst.
Auch zu den Selbsttests im Kommen sie. Wenn da
ganz komplizierte Ausdrücke kommen, die ihr erst mal glaubt,
nicht lesen zu können.
Mit dieser Folie könnt ihr sie lesen.
Ihr braucht vielleicht
ein bisschen Zeit dafür
Gut, das ist das Zwischenergebnis. Wir haben
jetzt gesehen, in den Rümpfen von Methoden stehen Anweisungen.
Und diese Anweisungen folgen den Prinzipien der imperativen Programmierung.
Wir werden also sequenziell ausgeführt und sie verändern üblicherweise die Belegungen
von Variablen oder sehr häufig. Variablen werden durch Zuweisungen verändert.
Und wir unterscheiden Exemplarvariablen, formale Parameter, lokale Variablen.
Auf der linken Seite ist es Zuwandsoperator steht immer eine Variable,
auf der rechten Seite immer ein Ausdruck.
Und arithmetische und butsche Ausdrücke setzen sich aus Operanten und Operatoren zusammen.
Das ist das, was man wissen muss über Operatoren.
Gibt es dazu noch Fragen
Ich habe jetzt hier wieder, ja, da eine Frage.
Seid ihr alle so weit, wenn es komfortabel aus der Konstante stehen?
Er fragt, ob auf der linken Seite eines,
einer Zuweisung auch eine konstante stehen könnte.
Ja, das ist eine ganz spannende Frage. Das kann sie,
also ihr habt ja die Exemplarvariablen kennengelernt im Java, ja,
also so Exemplarvariablen, die Exemplar-Konstanten sind, mit Final deklariert.
Die dürfen einmalig auf der linken Seite einer Zuweisung stehen und zwar genau im Konstruktor.
Da darf man tatsächlich das im Konstrukt da einmal zuweisen.
Wenn man es nicht schon vorher initialisiert hat,
aber ja, also die Antwort lautet ja,
aber nur im Ausnahmefall einmalig bei der Initialisierung.
Sonst noch Fragen zu Operatoren, Operanten.
Was uns nämlich jetzt noch fehlt, sind die elementaren Typen.
Ich habe jetzt hier schon ganz viel elementare Typen verwendet.
Ich habe hier Int verwendet, habe irgendwelche Intelliterale hingeschrieben,
sowas wie eine 5 oder eine 42.
Und die müssen wir uns auch noch angucken. Dann haben wir
einmal sozusagen so einen kleinen Rundschlag gemacht über die emperative Programmierung zumindest,
was elementare Typen angeht, Ausdrücke angeht, Anweisungen, Zuweisungen.
Da kommt natürlich noch ein bisschen mehr in den nächsten Wochen.
Aber dann haben wir sozusagen erstmal einen sauberen Stand. So,
diese elementaren Typen, die gibt es in jeder Sprache,
also sowas wie ein Typ für ganze Zahlen oder für Zeichenketten oder für einzelne Zeichen,
Bullshit-Variablen, all das gibt es in praktisch allen Programmiersprachen,
in Java auf jeden Fall.
Wir gucken uns erstmal jetzt noch vor der Pause an,
was so allgemein gilt für solche Typen
Und nach der Pause werden wir dann mal ein bisschen uns das angucken,
wie es in Java umgesetzt ist. Was wir bisher jetzt,
und wir sind ja immer noch in einer objektorientierten Lehrveranstaltung,
das heißt, ihr habt ja so ein Grundmodell,
dass so ein System aus Objekten besteht,
diese Objekte irgendwie miteinander kommunizieren und interagieren,
indem sie sich gegenseitig aufrufen.
Objekte sind Exemplare von Klassen. Und in den Klassendefinitionen sind
für diese Klassen festgelegt, was sie für prinzipielle Eigenschaften haben.
Also welches Verhalten sie haben und welche möglichen Zustände für
ihre Exemplare
So, und in dieser Klassendefinition wird eben halt das Verhalten
der Exemplare über Methoden definitiv. In den Methodenrümpfen steht das Verhalten drin.
Und die möglichen Zustände über die Zustandsfelder. So,
was wir jetzt bisher versucht haben, auf Level 1 zu machen,
ist, dass wir für die Typen der Zustandsfelder,
also für diese Exemplarvariablen, haben wir bisher nur Typen gewählt,
die vordefiniert sind in Java.
Also so einfache Typen, so Int und Bulien.
Das heißt, die Objekte, die erzeugt wurden,
wenn man ein Exemplar erzeugt hat,
hatten sehr einfache Zustände.
Die waren nur abhängig von diesen primitiven Typen
Das heißt, die waren nicht abhängig von dem Zustand von anderen Objekten.
Nächste Woche werden wir uns angucken, wie Objekte miteinander verknüpft werden können.
Da kann also ein Objekt, eine Referenz halten auf ein anderes Objekt.
Und dann wird das alles ein bisschen komplizierter. Hier war
bisher die einfache Welt von Objekte, haben einfache Zustände,
die definiert sind über die primitiven Typen, die wir uns jetzt mal genauer ansehen werden.
Diese elementaren Typen. Ich habe jetzt schon mehrfach darüber gesprochen,
dass bei einer variablen Deklaration ein Typ angegeben werden muss.
Und ihr habt schon so ein intuitives Verständnis von,
naja, Int ist ein Typ, Drink ist ein Typ,
aber was ein Typ genau ist, weiß ich eigentlich nicht,
aber ich muss halt irgendwie angeben,
was für ein Typ eine Variable hat,
damit dann der Compiler mir helfen kann, irgendwie Fehler aufzudecken.
So grob ist das, höchstens das, was ihr bisher verstanden haben könnt.
Bei mir haben wir noch nicht gesagt. Wir gucken uns jetzt
das etwas genauer an und wir werden in der nächsten Woche es nochmal genauer uns angucken,
aber das ist etwas,
was ihr auch auf jeden Fall hinter die Ohren schreiben könnt,
weil es einfach sehr nützlich ist, das zu wissen,
ein Typ in einer Programmiersprache und zwar ein jeder legt fest eine Wertemenge,
also eine Menge von möglichen Werten,
die zu diesem Typ gehören
Also Int zum Beispiel in Java, hat nur eine Untermenge
der ganzen Zahlen. Ganz wichtig, dass hier,
können wir uns mal angucken, also Int hat eine Wertemenge,
die geht von minus 2 hoch 31 bis 2
hoch 31 minus 1. Das ist der Wertebereich für Int.
Darüber hinaus können wir die ganzen Zahlen nicht in einem Int repräsentieren.
Der Typ hat einfach eine ganz klar definierte Wertemenge.
Und die zulässigen Operationen gehören auch zum Typ dazu.
Also was darf ich denn mit den Elementen machen?
Ich darf die addieren,
ich darf die multiplizieren
Bei Int ist das aber ganz wichtig, sich klarzumachen,
dass diese Operationen, nicht die Operatoren,
also plus minus sind Operatoren, aber die Operationen,
die gehören zum Typ dazu.
Und die sind bei Int eben ganz zahlige Additionen.
Ganz zahlige Subtraktionen, auch ganz zahlige Divisionen. Ihr kennt
wahrscheinlich hier dieses übliche Dilemma hier, fünf durch zwei.
Die meisten Leute sind erstaunt, was da rauskommt.
Fünf durch zwei, da sagen die meisten Leute hier,
das ist 2,5. Ist in Java aber zwei.
Weil das eine ganz zahlige Division ist. Weil beide Operanten
sind ins Und dann ist auch die Division ganz zahlig.
Wenn ich aber jetzt schreibe, 2.0, 5,
5, 5.0 durch 2, dann ist das 2,5.
Und es ist aber auch ein anderer Typ. Das Ergebnis
hat dann einen anderen Typ. Diesen Zusammenhang werden wir uns
noch mal ein bisschen näher ansehen. Was ganz wichtig ist,
ist, dass ihr die elementaren Typen wissen muss.
Ich sehe die Frage, ich komme gleich darauf,
dass ihr bei den elementaren Typen wissen müsst, welche es gibt.
Bei jeder Programmiersprache guckt man erst mal,
was haben wir denn so als Basissatz da?
Was ist denn vordefiniert
Und da gibt es eben halt üblicherweise Entsprachen, was für ganze Zahlen,
was für reelle Zahlen, für Zeichen und für Wahrheitswerte.
Das ist in fast jeder Sprache irgendwie drin. Und was
auch wichtig ist, dass diese Werte dieser elementaren Typ,
die könnt ihr direkt hinschreiben, was ich gerade hier gemacht habe.
Also ich kann tatsächlich sowas hinschreiben wie 13 und dann sagt der Compiler,
es sieht diese Zeichenfolge im Quelltext, ah,
das ist ein Literal und es hat dem Typ Int,
also jedes Literal hat einen Typ und auch sowas hier wie,
hallo, als Drink, als Zeichenkette, hat einen Typ.
Und das wird auch sofort hier erkannt,
dass es vom Typ String ist.
Da war eine Frage. Ich glaube,
bei Raum rundet er zweier
Er fragt, warum bei 5 durch 2 abgerundet wird und nicht aufgerundet wird.
Ganz einfach, weil die ganz zahlige Division so definiert ist. Das heißt,
sie ist definiert als, wie oft passt denn der Operant
auf der rechten Seite in dem Operant auf der linken Seite hinein.
Das ist einfach so definiert. Also auch wenn man jetzt machen würde,
7 durch 3, dann könnte man ja sagen,
das ist 2, das ist auch nicht,
da würde man auch nicht aufrunden,
machen wir mal irgendwie sowas wie 23 durch
Da würde irgendwie 3, irgendwas rauskommen. Es ist aber
nur 3, obwohl man das auch aufrufen könnte.
Also mathematisch könnte man es aufrufen,
aber die ganz zahlige Division ist eben halt so definiert.
Okay, das ist ganz wichtig, dass ihr diesen Begriff
kennt, literale. Das sind also diese Dinger,
die man wirklich hinschreiben kann, die einen Wert haben.
Und jetzt noch kurz vor der Pause dieser Hinweis auf Zahlen,
wenn ihr euch mit Zahlen in der Programmierung beschäftigt,
da muss man sehr, sehr genau hingucken,
in welcher Sprache man das macht und welche Regeln da gelten.
Es gibt unendlich viele Zahlen, ihr wisst das,
in der Mathematik, Aber mein Rechner hat nur begrenzt viel
Platz und er hat auch nur eine begrenzte Wortlänge.
Und üblicherweise werden Zahlen in solchen Rechnerworten abgelegt. Ein Rechnerwort hat
32 Bit, 64 Bit. Da kann man nur begrenzt
viel Informationen drin ablegen in so 32 Bit. So,
das heißt also, es gibt dann in den meisten Sprachen
sowas wie eine größte ganze Zahl und eine kleinste ganze Zahl,
die in einer Sprache dargestellt werden kann.
Das ist wichtig, dass euch das klar ist.
Das ist also irgendwie einen Wertebereich gibt um die Null rum oder
vielleicht auch nur von der Null. Es gibt auch so Sprachen,
da hat man nur ganze Zahlen, nur natürliche Zahlen,
aber bei den ganzen Zahlen ist es einfach so,
man hat da so um die Null rum so einen Bereich,
in dem kann gerechnet werden
Und zwar auch exakt, aber darüber hinaus.
Ciao, da geht halt nichts. Muss man wissen,
dass es diese Grenzen gibt und sie auch eventuell einhalten.
Das ist noch soweit dann schön, wenn man das weiß,
kann man es hier einhalten. Was schlimmer ist,
dass es bei der Gleitkammer-Arratmetik, also wenn ihr mit gebrochenen Zahlen arbeitet,
also mit 3.0 oder so in Java,
dass dann noch nicht mal mehr die Rechenregeln gelten,
die ihr normalerweise aus der Mathematik kennt,
innerhalb dieses Wertebereichs.
Bei Gleitkammerzahlen ist der Wetterbereich sehr groß,
aber dummerweise ist da ziemlich viel Lücke dazwischen.
Also zum Beispiel sowas wie X plus Y,
minus Y würde ihr immer sagen,
mathematisch gesehen ist das einfach
In der Programmierung mit Java. Nicht unbedingt. Kann ich
euch gleich Beispiele zeigen. Das ist ein fundamentales Problem.
Also wenn man sich mit diesen begrenzten Wörtern beschränkt,
es gibt andere Möglichkeiten, Zahlen zu repräsentieren.
Es gibt Sprachen, die haben keine Festlegung.
Die können beliebig große Zahlen berechnen. In Java ist das
aber nicht so bei Int und Float und so weiter.
Und bei Gleitkammerzahlen ist das, wie gesagt, noch so
ein bisschen unangenehmer. Da gibt es sehr starke Ungenauigkeiten.
Warum werde ich auch gleich noch mal ein bisschen erzählen?
Gerne an Programmieranfänger, der Hinweis,
lasst die Finger von Gleitkammer zahlen,
wenn ihr nicht wisst,
was mit ihnen passiert
Viele Programmieranfänger denken sich, oh, jetzt kann ich hier
keine gebrochenen Zahlen, das geht ja gar nicht.
Fünf durch zwei ist gar nicht zweieinhalb, das ist ja doof.
Dann nehme ich mal lieber Gleitkammerzahlen, da ist das ja viel genauer, fürchterlich.
Also bitte, bitte, auch da wieder, es passiert sehr,
sehr viel hinter den Kulissen. Man muss sehr genau wissen,
was da passiert bei Gleitkomma, Arathmetik, im Rechner.
Und das werden wir hier nicht vertiefen. Wir sind hier
nicht die Lehrveranstaltung, in der diese ganzen Zahlendarstellungen ausführlich behandelt werden.
Aber es gibt einfach gute Hinweise, dass es
auch Helden der Informatik vermieden haben mit Gleitkammerzahlen zu rechnen.
Also zum Beispiel Tech, wenn ihr Latech benutzt, Tech ist,
die Basis für Lattech, da hat er also alles nur mit Festkommazahlen gemacht.
Wer das trotzdem machen will,
dem empfehle ich diesen Artikel, der ist frei verfügbar,
whatevery computer scientists should know about floating point arismatic,
da schlackert man mit den Ohren,
was alles da so passiert und was da so für Rechenungenauigkeiten reinkommen,
wenn man das gelesen hat,
dann kann man möglicherweise etwas mutiger damit umgehen.
Ansonsten erstmal die Finger davon lassen, wir werden auch in
den Übungen da euch so ein paar Beispiele zeigen. Gut,
dann würde ich sagen, wenn jetzt dazu nicht noch Fragen sind,
was ich jetzt erzählt habe, dann können wir jetzt versuchen, Keine Frage soweit.
Machen wir mal eben 5 Minuten Pause. Wir gucken uns
jetzt in einem Überblick an, welche elementaren Datentypen es in Java gibt.
Das ist in Java sehr überschaubar. Ein klarer,
klar definierter Satz von primitiven Typen, die heißen in Java Primitive Types,
primitive Typen oder elementare Datentypen oder Basistypen,
wie immer ihr sie nennen wollt.
Hier steht ungewöhnlich, ist die Festlegung der Wortlängen.
Das ist, vor Java war das ungewöhnlich,
dass eine Programmiersprache festlegt, bei mir ist Int festgelegt auf
32 Bit
Wenn ihr euch in C Plus mal irgendwo einen Compiler schnappt, dann ist das plattformabhängig.
Ob in 32 Bit hat oder 8 Bit oder 64 Bit.
Kommt drauf an, auf welcher Plattform und welcher Compiler.
Das ist in Java in der Sprachdefinition festgelegt. Inzwischen ist das,
sagen wir, relativ üblich, also auch Sprachen,
die danach kamen, haben das genauso gemacht.
Es gibt acht primitive Typen, genau acht,
und zwar vier für ganze Zahlen, ganze Zahlen im Sinne von ganze Zahlen.
Und die heißen Int kennt ihr, 32 Bit,
Hier ist der Wertebereich für Int, 2 hoch,
minus 2 hoch 31 bis 2 hoch 31 minus 1.
Das sind die beiden das Kleinste und der größte Wert.
Es gibt aber noch Long, 64 Bit,
einfach mehr größerer Wertebereich, deutlich größerer Wertebereich.
Und dann gibt es aber auch noch Short und Byte.
Warum es die gibt, hat wieder ganz andere Gründe,
aber manchmal möchte man auch mit weniger Platz auskommen können und dann ist es gut,
wenn man im Typ schon sagen kann,
ich brauche nur die kurzen Dinger.
Dann sieht man hier, dass Byte zum Beispiel Werte hat
von minus 128 bis plus
Dann gibt es zwei primitive Typen für Gleitkommazahlen.
Die heißen Float und Double. Unterscheiden sich dadurch,
wie viele Bits sie verwenden, um einen Wert zu speichern.
Flow 32 Bit, Double 64 Bit. Dann gibt es
einen Bullshenda-Typ, der heißt Bulien und einen Datentyp für Zeichen.
Ganz wichtig ist, dass für all diese Typen ein Standard fährt,
ein Standard wert festgelegt ist. Das heißt also,
für die ganzen Zahlen gibt es einen Standardwert,
finde ich, zum Beispiel eine Exemplarvariable definiere vom Typ Int,
dann ist klar, dass die mit dem Standardwert belegt wird,
wenn das Exemplar erzeugt wird, das ist die Null.
Interessant ist, dass die Null einen Typ hat.
Die Null ist vom Typ Int. Denn die Null L,
das habe ich O getippt, 0L, das ist hier,
wenn man so ein L dranhängt, dann heißt das so viel wie Long.
Dann soll das ein Literal vom Typ Long sein.
Kann ich hinschreiben, dann ist es null vom Typ Long.
Ich kann sogar hinschreiben, 0.0 Und das ist tatsächlich vom Typ Double.
Das ist ein anderer Typ. Das Literal ist von einem
anderen Typ. Da ist eine Frage. Er fragt,
warum ist das in Java so,
dass wenn ich sowas hinschreibe wie 2,5,
dass das vom Typ Double ist und nicht vom Typ Float.
Weil Float würde doch reichen für 2,5. Der Grund ist
genau der, dass dieses Rechnen mit 32 Bit Floats
fürchterlich ungenau ist
Die Gefahr vermeiden will, dass Leute das aus Versehen tun.
Also wenn ihr Mitleidkammerzahlen rechnet, dann nehmt bitte lieber Double und nicht Float.
Bei Float werde ich gleich noch so ein paar Elemente zeigen,
die euch erstaunen werden. Dann gibt es Bulsche Wahrheitswerte,
also hier der Falls ist, wenn ich das literal Fals eintippe,
dann ist das tatsächlich der Wert Fals,
die Belegung einer Bulschen Wahrheit.
Und das ist eine Frage. Da werden wir nicht mit den Rechten,
wenn das nicht gut ist, da packen wir eine Beste.
Ja, ah, warum? Er fragt,
warum gibt es denn überhaupt Float, wenn man mit Float
gar nicht rechnen sollte?
Dass man nicht mit Float rechnen soll,
ist eine Empfehlung von uns
Das heißt, es ist nicht so, dass das irgendwie Quatsch ist, damit zu rechnen.
Man kann damit auch rechnen. Es hat auf manchen Rechnerarchitekturen Vorteile,
mit Floats zu rechnen, weil die halt in 32 Bittwörter gehen.
Wenn ich eine Rechnerarchitektur habe, mit nur 32 Bit,
dann kann ich möglicherweise da Geschwindigkeit rauskitzeln, wenn ich mit Floats rechne.
Aber nur, wenn ich sehr genau weiß,
was ich tue, innerhalb bestimmter Grenzen mit Floats zu rechnen.
Die Ungenauigkeiten bei Float sind relativ schnell groß, die kann ich gleich auch zeigen. Gut,
und dann gibt es aber auch sowas wie literale,
einen Standardwert für Also wenn ich hier, ah, das mache ich aber gleich,
das mache ich gleich, das zeige ich gleich noch.
Also das ist erstmal das, was,
und ganz wichtig, das ist jetzt ein Überblick,
ich mache jetzt hier so eine Art Schnelldurchlauf durch die primitiven Typen von Java,
da gibt es deutlich mehr zu sagen,
aber die zentralen Sachen sage ich hier.
Erstens Zeichen, Zeichen werden im Rechner,
also im Computer, durch vordefinierte Werte eines Zeichensatzes repräsentiert.
Das heißt, wenn ich sowas hinschreibe wie den Großbuchstaben A,
dann ist das vom Typ Char. Aber tatsächlich kann ich Dieses Zeichen,
also das, was da jetzt, dieses A,
was da gespeichert wird in der Variablen tatsächlich,
die jetzt dieses A hält, ist eigentlich eine Zahl.
Und zwar ist diese Zahl der Index in dem Alphabet,
also in dem Zeichensatz. Das heißt,
wenn ich mir jetzt mal hier sage, I ist gleich A,
dann weise ich quasi diesen Char, einer Intvariablen zu.
Das kann ich machen. Dann ist das 65. Das heißt,
das große A ist im Zeichensatz,
den Java verwendet,
das Zeichen an der Position
Und es wird tatsächlich diese Position gespeichert und nicht das A selbst.
Das ist ganz wichtig. Und es ist aber auch wichtig,
dass ihr unterscheidet zwischen diesem vier, in Anführungsstrichen,
und der vier, die man direkt hinschreibt.
Das eine ist die vier. Und das andere ist,
wenn man es dann für Rechnungen berechnet,
zum Beispiel hier eine andere Zahl.
Also vier ist das Zeichen Char 4 und vier ist ein Int.
Und wenn ich jetzt wieder sage, I ist gleich,
Vier. Also das Char-Zuweise, dann kriege ich jetzt wieder
quasi den Index von dem Zeichen Vier im Zeichensatz.
Und das ist eine ganz andere Zahl. Das ist 52.
Also das 52. Zeichen im Zeichensatz ist die Vier.
Das sieht man hier in diesem Teil, weil nämlich Java basiert auf Unicode.
Der Zeichensatz, den Java findet, das ist Unicode.
Und Unicode basiert, zumindest auch bei den ersten 128 Zeichen auf Aski.
Das ist auch ein Zeichensatz, der ist ziemlich alt,
den gibt es schon relativ lange.
Weit verbreitet, besonders auf Heimcomputern früher und so.
Also Aski,
quasi ein Standard-Zeichensatz
Und jeder Askey-Code-Zahl zwischen 0 und 127 entspricht ein Zeichen.
Also das, was wir gerade gesehen haben, ja,
65, Askey 65 ist das große A. Oder die,
was wir gerade gesehen haben, die 4 ist hier,
er hat die 52. Okay.
Das heißt, man kann hier genau sehen,
welche Nummer, welchen Index im Zeichensatz jedes Zeichen hat.
Und das gilt tatsächlich auch für Unicode,
weil der Askey-Zeichensatz ist eine Submenge von dem Unicode-Zeichensatz.
Java benutzt, war eine der ersten Programmiersprachen,
die Unicode verwendet
Und zeichnet sich dadurch aus, dass man eben halt für
ein einzelnes Zeichen nicht mehr 8-Bit verwendet, sondern 16-Bit.
Da ist eine Frage. Da steht ja jeder,
dass die Kochzeit zwischen 0,5 und 25 Spektren zeichnet.
Aber im Zeichensatz geht das jetzt erst bei 30 los,
nicht, dass das die 30, 40, 50 ist.
Ja, also er sagt, ja, hier steht,
dass jeder Usky-Code entspricht, ein Zeichen. Und er sagt,
es geht hier erst bei 30 los, ja,
in dieser Tabelle tatsächlich ist das hier so ein bisschen weggeschummelt,
dass es da drunter noch andere Zeichen gibt,
Masky-Zeichensatz und das sind so Zeichen,
so Steuerzeichen wie Newline und so weiter.
Also das sind so Steuerzeichen, die nicht druckbar sind.
Hier sind quasi nur die Druckbahnzeichen,
also die man wirklich sehen kann, aufgeführt.
Das heißt, hier ist ein bisschen was weggelassen,
was für Zeichensatzzwecke eigentlich weniger eine Rolle spielt.
Es gibt so, wie gesagt, so Standard-Steuerzeichen,
die hier jetzt nicht dabei sind, aber berechtigte Frage.
Okay, also Java verwendet Unicode,
Unicode mit 16 Bit für ein Zeichen
Und damit sagen wir relativ viel schon Geburt,
nämlich theoretisch 16 Bit, 65.000 verschiedene Zeichen.
Tatsächlich erlaubt Java noch mehr, weil sie inzwischen im Unicode festgelegt haben,
dass man bis zu 32 Bit benutzen kann, um ein Zeichen zu kodieren.
Das ist relativ kompliziert. Das ist der Ton auch da, ja.
Das ist relativ kompliziert. Ihr könnt davon ausgehen, erstmal,
dass bei den normalen Zeichen, die ihr so verwendet,
eigentlich immer 16 Bit für ein Zeichen verwendet werden.
So, und warum der Unicode dann auch erweitert wurde,
das war unter anderem auch der Grund,
weil die chinesischen Schriftzeichen schon ziemlich viel Raum einnehmen
Informationen dazu gibt es dann auch im Netz dazu.
Unicode steht für, also UTF hier, UTF 16.
Bei Java steht für und so weiter.
Könnt ihr euch angucken. Was ganz spannend ist,
dass man in Java ein einzelnes Zeichen so schreiben kann, vier.
Aber ich kann auch, dass jetzt in diesem Unicode angehen.
Das heißt, ich kann auch schreiben,
und dann kann ich hier schreiben, backslash u, und dann 00.
Und jetzt, was war jetzt gerade die 53,
weil 52, oh, das ist jetzt kompliziert,
irgendwie 4, 4. Das ist nämlich, mal sehen,
ob das, das ist ein D. Oh, okay.
Da habe ich mich verrechnet, ah nee,
das ist natürlich 3, 4. Ah, ich weiß schon,
dass es 3, 4, da ist die 4. Aha.
Warum jetzt 3, 4? Was ist jetzt dieses
komische 0, 0, 3, 4?
Das sind die sogenannten Hexziffern, die hier verwendet werden.
Also wenn man den Unicode so angibt,
dann kann man hier vier Hexziffern angeben und Hexziffern,
das sind Ziffern im Hexerdezimalsystem.
Die sind in der Informatik unglaublich verbreitet,
weil man genau vier Bit die so in Rechnern ziemlich häufig vorkommen.
Vier Bits zusammenfassen kann. Und vier Bit dann repräsentieren kann durch
ein einziges Zeichen. Durch die Ziffern von 0 bis 9.
Und dann beim Hexer-DC-Mar-System sind es halt 16.
Das ist das Zahlensystem zur Basis 16. Wird dann die 10
mit einem A repräsentiert, die Elf mit dem B und so weiter.
Das heißt, das, was ich hier gerade getippt habe,
war 4 plus 3 mal 16. 3 mal 16 ist 48 plus 4 ist 52.
Also ist das dezimal 52. Also die Hexer-DC mal 34,
ist dezimal 51. Das ist also das 52. Zeichen.
Das ist wieder die 4. Kann ich also auch tatsächlich
so hinschreiben
Gut, dann, das waren die Literale für Zeichen,
für einzelne Zeichen, in einzelnen Anführungsstrichen.
Dann gibt es Literale für ganze Zahlen.
Also, ich kann ja hier hinschreiben, 54. Klar.
Bei den ganzen Zahlen kann ich tatsächlich auch sie anders hinschreiben.
Auch das nur am Rande ganz kurz. Ich kann auch
schreiben, zum Beispiel die 54 haben wir gerade gesehen,
die könnte ich auch Hexer-DC mal hinschreiben.
Dann schreibe ich 0X und dann, was hatte ich
gerade,
Ja, 0X34. Damit sage ich, das Ganze ist jetzt
eine, ein Ititha-Literal, aber Hexer-DC mal notiert.
Der Wert ist dann wieder, 52, na gut.
Klar, dreimal, dreimal 16 plus 4 ist 52,
also wenn ich eine, ich müsste hier 36 schreiben,
so, dann habe ich die 54. Also 54 und 54 ist nicht das Gleiche.
Ich kann dieselbe Zahl unterschiedlich notieren. Das ist ganz wichtig,
dass ihr euch immer klar macht, auf den Folien,
das ist auch hier relativ durchgängig, so, der Wert ist immer rot angezeigt.
Und das, was man hinschreibt, ist blau.
Also so, was man in Java hinschreibt
Ja. Ich kann das Ganze auch optal machen,
ja, also dann auch entsprechend hier jetzt 0-3,
5 mit einer führenden Null, dann ist es optal interpretiert.
Dann ist das 5 plus 3 mal 8, ja,
dann ist das das Gleiche wie die 29.
Das ist alles überhaupt nicht wahnsinnig häufig zu gebrauchen.
Ihr schreibt normalerweise die Sachen dezimal hin und fertig.
Ich will das nur hier der Vollständigkeit halber sagen.
Bei den Gleitkammerzahlen ist das so ähnlich. Ich kann ja
die 5.0 so hinschreiben. Ich kann aber auch schreiben,
5 E
Das ist die 50. Stimmt nicht ganz, das ist nicht
das Gleiche. Also nehmen wir 5e0. Was ist das?
E-0, das ist diese Exponentenschreibweise. Das heißt,
so viel wie 5 mal 10 hoch 0. 10 hoch 0
ist 1, 5 mal 10 hoch 0 ist 5.
Wenn ich die 50 hinschreibe, dann kann ich hier so hinschreiben,
ich kann die 50 als Gleitkammerzahl so hinschreiben.
Ich kann aber auch schreiben, 5e1,
5 mal 10 hoch 1, 10 hoch 1 ist 10,
5 mal 10 ist 50, ist auch 50.
Verschiedene Literale, die man hinschreiben kann,
führen aber auf den gleichen Wert
Ganz wichtig. Gut, dann gibt es
so binäre Operatoren für ganze Zahlen in Java.
Das ist jetzt wieder ganz wichtig, dass er das klar ist.
Wir reden jetzt hier momentan nur über die ganzen Zahlen.
Also, 20 durch 6 ist 3. 20 Prozent 6,
das ist ein anderer Operator, der Modulo-Operator,
das ist die ganzzahlige Division, das liefert den Rest.
Also 20 durch 6 ist 3 Rest 2,
liefern also hier die 2 als Wert.
Und dann gibt es natürlich wieder Präzedenzen und diese Präzedenzregeln
habt ihr auf der anderen Folie gesehen
Also auch, dass hier entsprechend das hier zuerst ausgewertet wird.
Dann gibt es die Vergleichsoperatoren. Da liefert der Vergleich
irgendeinen bulschen Wahrheitswert. Also, was weiß ich,
ist zwei größer als eins plus eins.
Nö, eins plus eins ist zwei. Und zwar ist
nicht größer als zwei. Also liefert das hier forsch.
Falsch als Ergebnis. Und so weiter. Und auch da wieder,
die Präzedenzen liegen fest, was zuerst ausgewertet wird.
Das hier, das Plus bindet stärker als der Vergleich.
Also ist das hier, wird das
zuerst ausgewertet
Sonst käme ja auch teilweise keine Bullschenwerte dabei raus.
Also zwei Größe einfliefert, was Bullschiss plus eins.
Was ist denn Bull plus eins? Kann ich gar nicht
schreiben. Ich kann nicht schreiben, False plus eins.
Kann ich direkt mal probieren. False plus eins.
Juhu. Geht nicht. Es sagt da wieder,
meckert da irgendwie rum, dass die Operanten nicht zueinander passen.
Lässt sich hier nicht größer machen, so ein bisschen größer machen.
Error, Bad, Operantypes for Binary Operators,
bla bla bla.
Genau. Gut
Das ist einfach nur noch mal,
dass ihr euch das in Ruhe angucken könnt.
Dann gibt es Buhlschilliterale. Und da sind wir jetzt an einer Ecke,
die wieder richtig spannend ist, nämlich die Buhlschen Wahrheitswerte.
Man kann tatsächlich sich eine Butsche Variable deklarieren.
Und dann kann ich tatsächlich da auch Bulsche Operationen drauf anwenden.
Das braucht ihr relativ viel, wenn ihr irgendwelche Bedingungen auswerten wollt.
Das sehen wir uns gleich noch mal ein bisschen genauer an.
Ich hole mal so ein bisschen aus, weil das ist etwas,
was ihr ganz viel braucht in der Programmierung.
Und zwar in jeder Programmierung, mit jeder Programmiersprache dieser Welt,
braucht ihr ein Verständnis der Bullshen-Allgebracht.
Da kommt ihr nicht dran vorbei. Das heißt,
ihr müsst euch mit Aussagen Logik ein bisschen beschäftigen.
Das ist nicht so schwierig. Also es sind so ein
paar elementare Rechenregeln in der Bullshen-Allgebracht. Aber die muss man
sich schon in Ruhe angucken. Also letztendlich geht es darum,
dass man systematisch mit so Dingen wie wahr und falsch umgeht.
Also mit wahren Aussagen. Nehmen wir mal so ein Beispiel
. Es gibt eine Aussage hier, ich habe Hunger.
Stimmt sogar gerade, ja. Aber das ist erstmal
nur eine Aussage
Diese Aussage kann wahr sein, sie kann aber auch falsch sein.
Nach dem Mittagessen hatte ich vielleicht keinen Hunger,
jetzt habe ich vielleicht wieder Hunger.
Diese Aussage kann also erstmal für sich genommen wahr oder falsch sein.
Das heißt, ich kann tatsächlich hierhin schreiben, Bulien,
hungrig, ist gleich Falts. Eine bulsche variable Dickerin,
die diese Aussage repräsentiert, ich bin hungrig.
Kann ich hier deklarieren. Also hungrig, hungrig,
kann ich dann abfragen. Wie ist die Belegung dieser Variablen
? Falts. Jetzt kann ich aber auch sagen,
ich habe keinen Hunger. Ich kann das also auch negieren
. Ich kann sagen, na gut,
not hungrig
Dann ist das True. Ganz einfach. Ich kann damit
tatsächlich quasi rechnen. Also mit den Negationen kann ich
die Belegung einer bulschen Variablen negieren. Zweite Aussage,
ich habe Durst. Kann ich auch einfach so sagen.
Ist erstmal eine Aussage. Jetzt können wir die verknüpfen.
Ich habe Hunger und ich habe Durst. Langweilig.
Wen interessiert das, ob ich Hunger oder Durst habe?
Spannend ist, wenn man das irgendwie mit einer Verbindung mit
einer Bedingung verknüpft. Also wenn ich Hunger und Durst habe,
dann nehme ich etwas zu mir. Das ist was,
was man in der Programmiersprache dann irgendwie formuliert mit IF,
hungrig und durstig,
dann mach mal irgendwas
Ist das jetzt eine sinnvolle Aussage, hungrig und durstig?
Man könnte jetzt sagen, bei mir reicht es schon,
wenn ich hungrig bin, dann esse ich schon was.
Ich muss nicht nur erst hungrig und durstig sein.
Also wenn ich Hunger oder Durst habe, dann nehme ich etwas zu mir.
Das ist eine Verknüpfung mit oder, das wird diskunftsjunktion genannt.
Das andere ist die Konjunktion. Okay, damit es
nicht zu langweilig wird, machen wir ein kleines Intermezzo.
Ihr wisst, was eine Blondine ist, oder?
Eine Blondine ist weiblich und blond. Hier ist mal so
ein Beispiel. Was gilt für alle Menschen,
die nicht Blondinen sind
Also zum Beispiel für die hier. Das sind alles keine Blondinen.
Würdet ihr sofort sagen, dass es keine Blondinen sind?
Sie sind, jetzt ist die Frage, die,
die nicht Blondinen sind, sind die nicht weiblich und nicht blond?
Oder sind die nicht weiblich oder nicht blond? Logisches oder
? Erlaubt ja beides. Oder sind sie entweder nicht weiblich
oder nicht blond? Das sind verschiedene Aussagen über Menschen,
die nicht blond sind, nee, die keine Blondinen sind.
Und man merkt schon, so mit diesen logischen Begriffen muss
man so ein bisschen umgehen lernen. Also ganz wichtig,
Nicht weiblich und nicht blond ist hier nur einer, das ist er.
Der ist nicht weiblich und nicht blond. Nicht weiblich oder nicht,
aber entweder nicht weiblich oder nicht blond,
das ist ein exklusives Oder, sind die beiden.
Das ist überhaupt nur eins von beiden.
Also da unten ist nicht exklusiv oder. Und eigentlich,
wenn ich alle zusammenfassen will, das ist hier das Grün umrandete,
dann ist das wirklich nicht weiblich oder nicht blond.
Das heißt, die Negation von weiblich und blond
ist nicht weiblich oder nicht blond
Da kommen wir nochmal genauer drauf. Also die Butsche Agribha
haben wir jetzt schon gesehen, hungrig, hungrig gleich False,
ich kann hier irgendwie durstig, ich kann die verknüpfen.
Was ganz wichtig ist, wenn ihr mit Bullshen-Variablen arbeitet,
und das ist wirklich was, was euch Schwierigkeiten bereiten wird,
kann ich euch versprechen, den meisten Programmieranfängern bereiten,
Butsche-Variablen, Schwierigkeiten.
Benennt die Variablen immer so, wie die eine der Aussagen
dann wirklich sein soll. Also zum Beispiel bei einer Variablen,
ob jemand hungrig ist, sollte sie wirklich heißen, hungrig.
Weil dann weiß man, wenn sie True ist,
dann ist die Person hungrig und wenn sie nicht
hungrig ist,
ist es wahrscheinlich False
Schlechtes Beispiel, wenn ihr eine Bullshit-Variable benennt,
ihr braucht eine Bullshit-Variable, um zu speichern,
ob in einem Spiel, wo Ameisen beteiligt sind,
die entweder links rum oder rechts rumlaufen, also Ameisen,
Linkshände oder links Rechtshänder sind, dann könntet ihr einfach sagen,
wir nennen die Bullshit-Variable Ausrichtung.
So, wenn ich dann jetzt den Quelltext lese und sehe,
Ausrichtung ist gleich true, dann weiß ich nicht,
ist das jetzt ein Linkshändler oder ist das ein Rechtshändler?
Schlauer wäre ihn mit linkshändig zu benennen. True wäre dann,
es ist ein Linkshändler und vorrats wäre es wie ein Rechtshändler.
Also das ist ganz wichtig, dass er die Dinger vernünftig benennt.
Wie gesagt, ihr benutzt Bullshit-Ausdrücke primär für Bedingungen
Das ist das, wo es hauptsächlich verwenden werdet.
Man kann mit Bullshen-Variablen auch ganz spannende Sachen berechnen.
Hier sind so ein paar Beispiele. Auch hier auf der
Folie sind einige Beispiele. Könnt ihr euch in Ruhe nochmal
angucken, wenn ihr das nochmal so ein bisschen nachbereitet.
Das gehe ich jetzt nicht im Detail durch. Was wichtig ist,
dass es für die bullschen Operationen, für diese logisches und,
logisches oder exklusives oder ist hier nicht mit aufgeführt, gibt es Rechenregeln.
Und es gibt vor allen Dingen Wahrheitstafeln. Das heißt,
das Schöne an der bullschen Agebra ist,
der Typ Bulien in Java hat nur zwei Werte,
True und Falls
Und bei jeder Operation kommt entweder True oder Falls
auch dabei raus. Das heißt, man kann fast immer
bei diesen ganzen Operationen vollständig alle Fälle durchspielen.
Und völlig unabhängig von einer Programmiersprache gibt es einfach diese Wahrheitstafeln,
die gelten universell für alles, was ihr mit Programmierung hier machen werdet.
Also Konjunktion, das und, Falts und Falts, Gip Falts.
Falts und True, Gip Falts und so weiter.
Das Gleiche gilt für die Negation, Falts,
die Negation ist True und True is Falts.
Das ist relativ einfach. Und bei der Dissunktion,
bei dem Ohr ist es eben halt auch nochmal wieder,
da gibt es eine Wahrheitstafel.
Diese Wahrheitstafeln kann man dann benutzen, um abzuleiten,
welche Werte denn da rauskommen,
wenn so
ein Ausdruck ausgewertet wird
Was man dazu noch braucht, sind einige Rechenregeln hier,
die bullschen Operationen. Das ist auch universell,
unabhängig von irgendeiner Programmiersprache. Das ist etwas,
was hier in der Mathematik auch sicherlich noch mal thematisieren werdet,
auch in FG1 wird das noch mal drankommen.
Logikregeln, wie man mit Bullschen-Variablen rechnen kann. Da gleichen
so ziemlich die gleichen Gesetze, die ihr auch von Zahlen kennt.
Sowas wie Kommentativgesetze, Distributivgesetze und The Morgan.
The Morgan ist ein ganz cooler Hund. Das, was
wir gerade gesehen haben hier. Eine Blondine ist blond und Weiblich.
Blond und weiblich sind hier diese Variablen. Und wenn ihr
das negiert, dann ist das äquivalent zu Nicht-P oder Nicht-Kuh.
Das ist nicht intuitiv, haben wir gerade schon gesehen.
Also aufpassen beide Morgan. Das ist nicht intuitiv.
Ich mache das nochmal an einem Beispiel. Also angenommen,
wir formulieren, dass wir arbeiten können, wenn es nicht
der Fall ist, dass wir hungrig oder durstig sind.
Also nicht hungrig oder durstig. Dann kann ich hier einfach so meine Wahrheitstabelle hernehmen,
hungrig und durstig, ja, alle möglichen Fälle.
Es gibt dann immer hier alle Kombinationen, False False for True,
True, False to True, für diese beiden Bullshit-Variablen.
Jetzt verodere ich das nach dieser Wahrheitstabelle, die wir vorhin gesehen haben,
also False oder False, Skip False und so weiter.
Dann negiere ich das Ganze, das ist ja einfach nur umgedreht.
Und schon habe ich das, was hier rauskommen würde.
Laut Morgan ist das Äquivalent zu der Aussage,
nicht hungrig und nicht durstig. Wie gesagt,
das ist nicht intuitiv, aber man kann das überprüfen.
Auch hier mache ich eine Tabelle, hungrig und durstig wieder.
Dann werte ich zuerst mal hier nicht hungrig aus,
also hier kommt nicht hungrig, einfach das alles umgedreht.
Dann kommt nicht durstig, einfach diese Spalte einmal umgedreht
Und dann kommt hier das und, das Logische und von diesen beiden Spalten hier.
Und dann sieht man, das ist tatsächlich das Gleiche,
was da rauskommt. Ist nicht intuitiv,
müsst ihr einfach lernen und ein bisschen mit umgehen lernen.
Gleitkommazahlen? Habe ich jetzt schon ein bisschen was dazu gesagt?
Lasst die Finger davon. Warum solltet ihr die Finger davon lassen?
Ein ganz wichtiger Punkt ist, in Java schreibt ihr,
Gleitkammerzahlen dezimal hin. Also, wenn ich hierhin schreibe,
5 E1, dann ist das 5 mal 10 hoch 1,
also 50. Intern werden diese Zahlen aber Binär abgelegt.
Das heißt, die intern verwendete Zahlendarstellung, das ist iTriple-E-Standard 754,
der legt zwei Formate fest, für 32 Bitten für 64 Bit.
Und die sind aber binär. Nun ist es so,
dass nicht alle Zahlen, die dezimal dargestellt werden können,
eins zu eins auch im Binärsystem gut darstellbar sind.
Da gibt es, das ist Mathematik, einfach Brüche.
Und das heißt zum Beispiel, der glatte Dezimalbruch,
0,1, der ist bei uns nicht so gut darstellbar.
Wenn ich jetzt hierhin schreibe, 0.1, dann ist das 0.1,
aber wenn ich schon schreibe 0.1 als Float, dann ist das auch 0.1.
Aber wenn ich jetzt diesen Wert mehrfach aufaddiere,
zehnmal zum Beispiel, dann würde man ja erwarten,
dass da 10 rauskommt, ist aber nicht der Fall.
Ich habe ein anderes Beispiel, warum ich euch sage,
dass es keine gute Idee ist, mit Floats zu rechnen.
Erstmal hier diese Zahl, 9,8, 7,6,5 hier,
das ist also ungefähr 987 Millionen,
ist eine relativ hohe Zahl, ist ein Int.
Die kann ich jetzt auch als Float zahlen mir angeben lassen.
Wenn ich das jetzt mache, Dann kommt da eine ganz komische Zahl raus.
Nämlich irgendwie eh hoch, also eh 10 hoch 8,
ja, 10 hoch 8, 9,876, 6,543, 4. Oha.
Also statt der 21 am Ende sagt er,
hier steht eine 4 am Ende.
Das ist ja komisch. Das heißt,
eine relativ normale ganze Zahl, wo man denken würde,
dass Float die abbilden kann, ist im Float 32 Bit nicht darstellbar.
Das wird noch ein bisschen unangenehmer, wenn ich da jetzt
was drauf addiere.
Dann kommt die gleiche Zahl raus. Ja,
also da und da seht ihr, steht die gleiche Zahl.
Na gut, dann haue ich mal zehn drauf.
Vielleicht kommt da was anderes raus. Jetzt kommt die gleiche Zahl raus.
Ich addiere zehn drauf, es kommt die gleiche Zahl raus.
Ist doch schon ein bisschen erschreckend, oder? Ich addiere nochmal
30 drauf. 30 drauf. Bleibt immer noch die gleiche Zahl.
Ich addiere mal 40 drauf. Jetzt hat sich was getan,
jetzt ist das hier irgendwie statt 4-3-4,
ist es jetzt 4-4 am Ende.
Da hat es also jetzt plötzlich einen Schwung gegeben.
Das liegt daran, dass tatsächlich Um die Null rum,
diese Zahlen relativ dicht liegen, die in einem Flow dargestellt werden können.
Und mit größerem Abstand von der Null liegen die darstellbaren Zahlen
immer weiter auseinander. Und an den äußeren Rändern hier so,
es muss gar nicht so weit weg sein,
hier in dem Bereich liegen die dann so weit auseinander,
dass schon mehrere ganze Zahlen dazwischen passen.
Das sind also ganze Zahlen gar nicht darstellbar.
Das ist ziemlich blöd. Die ganzen Ins in Java passen
in Double rein, in Flowd passen sie nicht rein.
Von daher ist eine automatische Umwandlung von Ins in Flowds
ziemlich ärgerlich
Gut. Also, auch ganz wichtig,
hier noch die Operatoren plus minus mal geteilt.
Gibt es genauso für Gleitkammerzahlen, aber es sind andere Operationen. Gut,
jetzt die letzten paar Minuten, muss ich jetzt nochmal eben verwenden,
auf Typumwandlungen, weil die einfach auch recht wichtig sind.
Diese Zuweisung hier oben in E gleich True.
Seid ihr alle der Meinung, solltet mal nicht hinschreiben können,
dann kommt Piler meckert auch.
True ist ein bullsches Literal, ich kann das einer In-Variable nicht zuweisen.
Andererseits haben wir aber schon gesehen, ich kann es aber
schreiben,
wie Double
D ist gleich
Was da passiert ist, es wird etwas umgewandelt,
nämlich 5 ist ein Intliteral, das darf ich aber einer Double-Variablen zuweisen.
Es wird implizit die 5 umgewandelt in ein Double-Literal.
Das passiert durch eine sogenannte Typumwandlung. Und bei diesem Typumwandlung und Java
gibt es zwei ganz wichtige Unterscheidungen. Es gibt den Fall,
wo das automatisch passiert durch den Compiler,
also hier Double D ist gleich 5, kann ich hinschreiben, dann ist D 5.0.
Da wird das auch automatisch umgewandelt. Das ist genau dann der Fall,
wenn Der Zieltyp größer ist, eine größere Genauigkeit hat als der Quelltyp.
Int ist 32-Bild, Double ist 64, da passt das besser rein.
Also da kann ich immer umwandeln. Es gibt aber einige Beispiele,
und das ist das andere, was ihr gesehen habt,
ist Int-Ears gleich A, das konnte ich ja einfach hinschreiben,
weil da nämlich 16-Bit für einen Char locker in die 32-Bit packen,
die ein E-H,
ein Int hat.
Solche automatischen Umwandlungen können auch durchaus mehrfach auftreten.
Können wir uns gleich mal angucken,
haben wir gleich noch eine schöne Storesi-Aufgabe
Wenn es andersrum ist, wenn ihr in etwas,
was kleiner ist, etwas reinspeichern wollt, was größer ist.
Also wenn ich sowas habe wie I, ne I,
haben wir ja schon,
I hat einen Wert 52. I soll jetzt 5.0 den Wert bekommen.
Da sagt der Compiler, nein, das geht nicht.
Possible does of precision, du versuchst gerade eine 2,
eine 64-Bit-Darstellung in 32-Bit zu speichern.
Was ihr dann machen könnt, ist, sie können sagen,
na gut, ich möchte das auf jeden Fall erzwingen,
dass jetzt dieses da reingeschrieben wird.
Das ist eine Typumwandlung
Die man da erzwingen kann. Man kann sagen,
okay, ich weiß, was ich tue, 64-Bit,
aber ich möchte das jetzt mal in 32-Bit,
schneiden wir das irgendwie ab, was da an Genauigkeit verloren geht.
Und dann geht das, dann kommt da fünf raus.
Das ist ganz zentral. Das könnt ihr machen. Da
muss man natürlich sagen, wissen, was man tut.
Warum ist das hier unten jetzt zum Beispiel nicht zugelassen?
Float F ist gleich 3-1, 4-1
, 5. Er wirft mir das schnell an den Kopf.
Was ist da das Problem? Ist auch eine Gleitkammerzahl,
warum kann ich dir nicht zuweisen an einer Float-Variablen?
Ja. Ganz genau, weil er ist rechts ein Double-Literal
steht,
Links steht nur 32 Bit, passt nicht. Okay. Hier
ist die Zusammenfassung von dem, was ich heute erzählt habe.
Und ich habe jetzt gleich noch ein paar schöne Sturesi-Aufgaben dazu.
Und dann werden wir wieder sehen, wie viel denn jetzt von dem,
was ich so erzählt habe, bei euch wirklich angekommen ist.
Gentlemans, Star Your Engine, hier SE1,
Vorlesung 4. Welchen Ausdruck,
welchen Wert hat der folgende Java-Ausdruck
Bin ich im Netz hier, ich hoffe schon,
ja, sieht gut aus. Könnt ihr auf euren Geräten
diese Frage auch sehen jetzt, ja, ist die sichtbar?
Ja. So, welchen Wert hat der folgende Java-Ausdruck?
Fünf durch zweimal drei. Bitte? Den Code?
Den QR-Code, ja, den kann ich
nochmal zeigen
Ja, 150 Stimmen, also so bei 200 höre ich
auf zu zählen. Kommt, gebt eure Stimme ab.
Nehmt euch ein Herz. Es ist ja anonym. Prima
. So, reicht 200 Stimmen. Die meisten von euch
haben gesagt, es ist sechs. Einige haben gesagt,
es ist 7,5 und fast keiner hat die anderen Werte genommen.
Und das ist natürlich noch relativ einfach gewesen,
weil das die ganz zahlige Division ist
Das ist die ganzzeitige Division. Also 5 durch 2
habe ich ja vorher gezeigt. Okay,
wir machen uns etwas schwerer, was ist das hier?
Welchen Wert hat dieser Java-Ausdruck? 23 Prozent,
6 mal 5. Ah, was war nochmal dieses Prozentzentzeichen?
Wie ist das mit der Präzedenz
Ja, die Beteiligung ist noch recht zögerlich.
Aber ihr dürft ja auch drüber diskutieren.
Es ist, wir sind gleich bei 200 Stimmen.
Okay, das reicht mir erst mal. Mal sehen,
was da so an Antworten kommt. Die meisten sagen 25.
Also 23 durch 6 ist drei Rest 5, 5 mal 5 ist 25.
Und das ist also richtig. Gut. Ja, wir
haben noch einen hier. Der ist ein bisschen komplizierter.
Da müsst ihr erstmal ein bisschen in Ruhe drüber nachdenken.
Ja, ihr seht hier, dieses Int ist ja so dieses Dieser automatische Typumwandlung.
Das ist hier ausnahmsweise auch mal nett von uns geklammert,
dass man also nicht jetzt noch sich noch fragen muss,
wie sind denn die Präzedenzen?
Das sind so typische Klausuraufgaben. Bitte? In der Klausur
nicht, nee. Normalerweise braucht ihr auch keinen Taschenrechner.
Das sind so Zahlen, die können wir noch im
Kopf ausrechnen
Ok, es ist immer noch zögerlich hier.
Ihr traut euch nicht so richtig, eure Meinung abzugeben.
Ich halte das mal an. Wir gucken mal auf die Verteilung.
Die meisten sagen, es ist 17. Und das ist auch richtig
. Warum ist das richtig? 21 durch 6 ist,
weil es ganz, weil es nicht ganz zeitig ist.
Es ist wirklich eine Float-Division. Ist das also tatsächlich
irgendwie 3,5, ungefähr. 3,5. Das mal 5,
3,5 mal 5. Naja, das ist dann Ja,
17,5 und dann hat man abgerundet, weil ja hier Int,
das abgeschnitten wird, hat man eine 17. Okay,
einen habe ich noch.
Einen habe ich noch. Wie viele Typumwandlungen finden in dieser Java-Anweisung statt? Ihr wisst also,
hier wird ja das ausgewertet und dann, wenn zwei Operanten verknüpft werden,
die nicht kompatibel sind, also zum Beispiel drei und,
also drei ist ein Int und das ist ein Zeichen.
Wenn die nicht miteinander verknüpft werden können,
dann muss immer einer umgewandelt werden,
eine Typumwandlung und das macht Java dann auch
So, und wie viele finden jetzt hier in diesem Ding
eigentlich statt? Okay, das ist die letzte Frage.
Wir sind leider mit der Zeit ein bisschen drüber,
tut mir leid. Okay, bei 160, ja.
Okay,
ich halte mal an
So, jetzt bin ich gespannt. Da ist die Verteilung
schon ein bisschen breiter. Aber auch hier wieder,
die meisten sagen, das Richtige, es sind drei.
Die beiden werden, hier wird einmal der Char umgewandelt,
damit eine In-Adition möglich ist.
Hier wird dann der Int umgewandelt, einen Float.
Und zum Schluss wird der Float umgewandelt,
damit er in ein Double passt.
Alles klar,
vielen Dank.