So, es ist Viertel nach. Ich würde euch bitten,
die Plätze einzunehmen, das Rauchen einzustellen, euch anzuschnallen.
Eine weitere atemberaubende SE1-Vorlesung. Ja,
herzlich willkommen zur sechsten Vorlesung von SE1. Ich bin darauf hingewiesen worden,
dass wir das Licht ein bisschen heller machen sollten.
Ist das jetzt hell genug? Ich habe das immer so gemacht,
dass ich am Anfang abgedunkelt habe, um anzudeuten,
ich möchte jetzt anfangen.
Jetzt habe ich wieder ein bisschen hochgefahren,
reicht das aus jetzt oder soll ich es noch
ein bisschen heller machen?
Das ist okay so
Es gibt keine Proteste. Gut. Sehr schön. Bevor ich anfange,
möchte ich ein paar Worte sagen zu SE1 im Generellen.
Es ist ja so, dass ich hier
immer so als Gallionsfigur vorne stehe und vorturne.
Aber SE1 besteht eben halt nicht nur aus mir.
Zum einen gilt einfach, dass diese Veranstaltung jetzt zum neunten Mal läuft.
Das heißt also, das, was ihr hier so geboten bekommt,
ist das Ergebnis von der Arbeit von mindestens acht Jahren.
Eigentlich sogar mehr, weil wir die Konzepte teilweise
schon in anderen Lehrveranstaltungen vorher ausprobiert haben
Und das ganze SE1 wäre so, wie es jetzt ist,
überhaupt nicht denkbar, überhaupt nicht möglich,
wenn es nicht ziemlich viele Leute geben würde,
die dazu beigetragen haben.
Es sind inzwischen weit über 2000 Studierende durch dieses Modul durchgegangen.
Das ist für sich genommen schon eigentlich ziemlich bemerkenswert,
weil so viele große Veranstaltungen gibt es in der Informatik nicht.
SE1 ist mit Abstand die Teilnehmerstärkste. Auch an der Uni
gibt es natürlich ähnlich große Veranstaltungen,
aber in der Informatik ist das
schon ziemlich ungewöhnlich
Wir haben aber auch inzwischen schon über 100 Betreuer gehabt in SE1.
Also Personen, die euch in den Übungen im Übungsbetrieb,
in den Präsenzübungen betreut haben. Das sind sowohl wissenschaftliche Mitarbeiterinnen und Mitarbeiter
als auch, und in letzter Zeit verstärkt, studentische Hilfskräfte.
Also studentische Betreuer sind absolut essentiell, sonst könnten wir diesen Übungsbetrieb gar nicht stemmen.
Also auch ohne die wäre das nicht denkbar. Außerdem haben wir ziemlich viele Leute,
die bei uns in der Arbeitsgruppe, Softwarearchitektur,
da mitgewirkt haben, auch Leute,
die gar nicht mehr bei uns an der Uni jetzt arbeiten.
Das sind auch zahlreiche, zwei besonders prominente
für euch möglicherweise
Jetzt Christian Speeh, der den Übungsbetrieb organisiert,
der Ansprechpartner ist für alle Fragen und Nöte, die ihr habt.
Und Fred Winkler, der auch substanziell hier zu den Aufgaben beigetragen hat,
die ihr dann in den Übungen lösen sollt.
Ja, und nicht zuletzt auch Heinz Zürichhofen,
der steht immer auf der ersten Folie drauf,
er taucht hier nicht auf in SE1,
er hält auch keine SE1-Vorlesung mehr.
Aber ohne seinen Unterstützung, gerade in den ersten Jahren hätte
ich hier auch nicht das so aufziehen können,
wie ich es denn aufziehen wollte.
Und insgesamt ist das einfach so,
dass dieses Zitat sehr,
sehr gut passt
Dass man das Glück eigentlich nicht delegieren kann. Also ich
kann nicht sagen, jemand anderes soll mich jetzt glücklich machen.
Ihr könnt auch nicht delegieren, dass ihr was lernt.
Ihr müsst selber was lernen und lernen und auch das Glücklichwerden überlernen
, ist dann ein Produkt einer Kommunikation. Das heißt,
wir haben ja hier in SE1 das Konzept der Kommunikation ganz weit nach vorne geschoben.
Das wollte ich nun mal gesagt haben. Außerdem sind die Online-Selbsttests
ziemlich erfolgreich gestartet. Ihr habt sie jetzt seit einer Woche im Betrieb,
die seit zwei Wochen jetzt inzwischen schon,
und er wurde schon über 300 Mal ausgeführt.
Das muss nicht heißen, dass 300 Personen den Test gemacht haben,
weil manche machen das vielleicht auch mehrfach
Aber das ist ein ganz großartiges Ergebnis. Als wir die Online-Tests
im letzten Jahr eingeführt haben, da hat sie keiner gemacht.
In den ersten Wochen. Wir hatten das so begleitend gedacht,
am Ende eines Levels, jetzt gleich den Selbsttest machen,
hat nicht funktioniert. Technische Hürden, so banaler Kram wie,
es ist in einem anderen System,
wir haben das jetzt alles hier in Komsi, toll.
Es läuft super. Das heißt, alle sollten jetzt Level
1 fit sein. Schlagartig wird es ruhiger. Okay,
dann machen wir doch mal einen Test dazu.
Ich habe hier zufällig Storesi dabei
Und wir können ja mal eine Level 1-Frage stellen.
Also hier SC1, Vorlesung 6, Laden.
Welchen Wert hat der folgende Java-Ausdruck? Ich starte die Abstimmung.
Seht euch diesen Ausdruck an. Das ist Woche 4,
primitive Typen in Java. Welchen Typ hat hier das Ergebnis?
Das sieht man vielleicht relativ schnell. Also einfach welchen Wert
hat der gesamte Ausdruck am Ende? Da sind hier viele
Antwortmöglichkeiten, A, 0, B,12, C,13 oder D,17.
Und ich würde euch jetzt bitten, hier eure Meinung abzugeben.
Ich glaube, so eine ähnliche Aufgabe ist auch in dem
Online-Test drin. Und wenn ihr den Online-Test gemacht habt,
dann habt ihr möglicherweise an manchen Stellen gestutzt.
Das ist das Ziel, dass ihr stutzt und dann sagt,
hm, das sollte ich nochmal nachlesen.
Also es ist alles keine Hexenkunst. Es ist auch alles
im Skript erklärt, warum das so ist, alles nachvollziehbar.
Also mehr als 100 Stimmen hätte ich schon gern.
Sehr gut. Dann ist das doch schon mal gut.
Gibt schnell eure Stimme ab. So, und jetzt beenden wir
das mal. Mal gucken. Also ob jetzt sozusagen der
Effekt eingetreten ist, ja, so viele Online-Tests wurden gemacht.
Das heißt, so die einfachen Fehler werden nicht mehr gemacht.
Wir gucken mal auf die Verteilung
Okay. So, ihr seht, das ist fast schon gleich verteilt,
ja, 30 Prozent, 26, 40 Prozent.
Und es ist zum Heulen, es ist zum Heulen.
Ja, die richtige Antwort ist Diesel hier.
Das heißt, die Minderheit von euch hat das richtig gemacht.
Das ist ausgesprochen schade. Ja. Was passiert hier?
13,0. Hier steht 13,0. Und hier steht 4. 13,0 hat den Typ,
dass alles jeder Teilausdruck in Java hat einen Typ.
Und dieser Typ hier ist Double.
Und dann steht hier durch
Zwei Operanten, unterschiedliche Typen, der eine wird umgewandelt, automatisch.
Und zwar wird der Int in einen Double umgewandelt.
Also kommt hier 4,25 raus. 4,25 mal 4 bis 13,
13,0. Double, immer noch Double. Und dann wird hier
eine Typzusicherung gemacht, also eine Typumwandlung, da wird gesagt,
hier, macht mal aus der 13.0, macht mal bitte
eine 13. Also kommt da 13 raus.
Handwerkszeug, Handwerkszeug. Gut oder nicht gut. Dazu später
mehr. Letzte Woche habe ich was erzählt zu Referenzen
Heute ein ganz anderes Thema. Wieder imperative Grundlagen.
Also Dinge, die in jeder strukturierten Programmiersprache gelten,
in jeder Imperativen, auch in jeder objektorientierten Programmiersprache.
Und zwar geht es uns zum einen um das genaue Betrachten von Verzweigten Anweisungen,
also wo sozusagen bedingt irgendwas passiert, abhängig von irgendeinem Ausdruck.
Und wir wollen uns ansehen, wie man Wiederholungen programmiert.
Das geht in Java klassisch mit Schleifen. Nächste Woche werden wir
auch noch einen anderen Mechanismus sehen, wie man Wiederholungen programmieren kann,
aber dazu dann in der nächsten Woche mehr.
Außerdem werde ich heute noch was sagen zu statischen und dynamischen
Anteilen von Java-Programmen. Das kommt dann nach der Pause,
genau wie die Schleifen, die kommen auch erst nach der Pause.
Kontrollfluss. Ich habe den Begriff Kontrollfluss schon eingeführt. Ich habe gesagt,
das muss man sich so vorstellen, als wenn,
man kann sich das wirklich so vorstellen,
als wenn der Prozessor, wie so ein kleiner Roboter,
durch euren Quelltext läuft und jede Zeile nach der anderen ausführt,
sozusagen da, wo der gerade ist,
da ist dieser rote Pfeil, diese Pfeilspitze,
da ist er gerade.
Es gibt also immerhin nur genau eine Anweisung, die
gerade ausgeführt wird. Das ist eine Vereinfachung im richtigen Java-Programm
gibt es das Konzept von Nebenläufigkeit, das heißt,
dass Objekte durchaus auch parallel an irgendetwas arbeiten können
Wir vereinfachen das hier in SE1 und SE2, betrachten nur sequenzielle Programmierung.
Das heißt, ihr könnt wirklich davon ausgehen, dass immer,
dass die Programmausführung der Kontrollfluss an einer Stelle ist. So,
willst du dir das jetzt vorstellen, dass dieser so durchfließt,
wie so ein, wie Wasser eigentlich,
der fließt da so durch und hat dann so,
so und jetzt gibt es verschiedene Möglichkeiten,
wie man den Kontrollfluss genauer betrachten kann.
Man kann genau hingucken innerhalb einer Anweisung, das haben wir gerade gemacht.
Wir haben einen Ausdruck gesehen, wir haben gesehen,
der Ausdruck, den muss man wirklich sich genau überlegen,
was wird wonach ausgewertet,
wo kommt da jetzt eine implizite Typumwandlung,
das ist also wirklich eine Art Kontrollfluss innerhalb eines Ausdrucks
Im Kleinen ist das Kontrollfluss. Die Reihenfolge der Auswertung und
die Typen der Auswertung. Dann zwischen den Methoden,
das haben wir auch schon gesehen, Methoden, Aufrufe,
da wird die Kontrolle mal übergeben an eine andere Methode,
da wird dann etwas gemacht.
Am Ende wird irgendwas zurückgegeben, wird zurückgesprungen zum Aufrufer und so weiter.
Und zwischen den Anweisungen einer Methode, also im Rumpf einer Methode,
das, was da so steht, da greifen Kontrollstrukturen.
Und diese Kontrollstrukturen, die wollen wir uns heute
etwas genauer angucken
Zum Hintergrund nochmal, es gibt klassisch schon relativ alte Darstellungsformen für
den Kontrollfluss. Also wie die Anweisung in einem Programm,
nicht nur objektorientiert, sondern imperativ, dargestellt werden kann.
Eine Darstellungsform sind Flussdiagramme. Eine einfache Anweisung,
die man im Java-Quertext hier hinschreiben kann,
wird hier dargestellt als so ein eckiger Kasten,
also zum Beispiel Drucke X aus.
Und dann ist es tatsächlich so, da gibt es einen Pfeil,
der reinfließt, hier rot markiert.
Und wenn das ausgeführt wurde, fließt das weiter.
Dann kann ich solche Anweisungen natürlich
sequenziell hintereinander leben
Also A, Simicola und B zum Beispiel. A,
gefolgt von B, also Kontrollfluss hier rein, bei A,
raus, bei B, rein und so weiter.
Sehr einfach. Dann gibt es sowas wie Fallunterscheidungen, das heißt,
in dieser Raute da wird jetzt eine Bedingung geprüft und abhängig davon,
ob die Bedingung zutrifft, wird im Jahrfall A ausgeführt,
im Neinfall wird A übersprungen.
Dann gibt es auch noch IF-Bedingungen, trifft zu,
dann mache A, ansonsten mache B,
also dann auch tatsächlich zwei Möglichkeiten, zwei Anweisungen,
die da ausgeführt werden.
Und auch hier kann der Kontrollfluss eben halt entweder durch A oder durch B fließen,
also man kann sich das immer so vorstellen,
dass da irgendwie so entlang der Pfeile
irgendwas passiert
Genauso hier mit der Wiederholung, die wir uns ja heute genauer ansehen werden.
Also wir haben hier wieder den Kontrollfluss, der hier reinfließt.
Das wird eine Bedingung abgeprüft. Irgendeine Bedingung X, eine Bullshit-Bedingung
. Wenn die zutrifft, dann geht das hier raus.
Es gibt also immer so zwei Ausgänge bei so einer Raute.
Dann wird A ausgeführt und dann ist das hier so andere,
dann geht der Kontrollfluss wieder nach oben.
Aha. Geht also wieder in diese Bedingungsprüfung rein.
Und jetzt kann das hier mehrfach durchschleifen und irgendwann gilt diese Bedingung X nicht mehr.
Und dann geht dir Kontrollfluss hier weiter und zu den nächsten Anweisungen,
die danach stehen. Das ist eine sehr häufig anzutreffende Darstellungsformen.
Eine andere sind die Strukturgramme, die sind aus einer Zeit,
als man nicht so schöne Kästchen zeichnen konnte mit Computern,
also so richtig Pfeile mit Rauten und so.
Das war halt für die grafischen Möglichkeiten von Computern oft
noch nicht so leicht zu machen.
Also wurde dann auch eine vereinfachte Form gewählt,
sowas wie das hier. Also einfach nur Kästchen,
die dann aneinandergesetzt werden oder so Bedingungen dann in so komischen Kästchen drinstehen.
Und dann gibt es tatsächlich die beiden Möglichkeiten,
die da gewählt werden können, stehen da drunter.
Und hier auch schon angedeutet, solange eine Bedingung zutrifft,
dann führe die Anweisung A aus
Diese Darstellungsform werden wir gleich nochmal aufgreifen, wenn wir uns schleifen,
genauer ansehen. Gut. Jetzt ist es so,
diese Kontrollstrukturen, die wir uns gleich ansehen werden,
da gibt es schon eine ziemlich lange Diskussion darüber.
Es ist in den 60er Jahren intensiv daran geforscht worden,
was ist denn sozusagen überhaupt berechenbar, was ist überhaupt darstellbar mit Flussdiagrammen?
Und dann kann man auf die Aussage, naja,
also so mit Flussdiagrammen kann ich eigentlich alles ausdrücken, was irgendwie berechenbar ist.
Und dann gab es Leute, die haben dann gesagt,
okay, wir haben eine andere Darstellungsform, sogenannte D-Diagramme.
Und diese D-Diagramme, legen auch fest, was man tun darf.
Und die Diagrammdefinition ist einfach eine einfache Aktion,
ist ein D-Diagramm, A und B, wenn die D-Diagramme sind,
dann ist auch A gefolgt von B ein D-Diagramm.
Dann diese bedingten Sachen und diese Schleife.
Das sind alles D-Diagramme und dann nichts anderes ist ein D-Diagramm.
Wirklich nichts anderes. Das heißt, was da gezeigt wurde,
ist, dass ein bestimmtes Konstrukt, das in Programmiersprachen zu
der Zeit total selbstverständlich war, nicht mehr notwendig ist.
Das wurde da theoretisch gezeigt. Dieses Konstrukt, das würde ich
euch gerne zeigen, Ich habe hier so ein kleines Beispiel.
Ich möchte eine Klasse haben, die mir die druckbaren Aske-Zeichen
auf die Konsole ausgibt. Also ihr wisst,
die druckbaren Aski-Zeichen liegen so von Aski 32 bis 126.
Also wenn ich jetzt hier einen Charakter mir deklariere und den
die 32 zuweise. Das ist dann wieder schon implizit,
muss man aufpassen.
Die 32 ist ein Int-Literal
Der Compiler sieht, das Literal ist aber zur Übersetzungszeit
schon erkennbar, passt in einen Char rein.
Deswegen lässt er das zu. Das heißt, jetzt habe ich
hier einen Char, der belegt ist mit einem Leerzeichen.
War das 32. Zeichen im Zeichensatz, ist ein Leerzeichen.
Jetzt kann ich schreiben Plus Plus CH,
kann also sozusagen die Belegung der Variablen CH erhöhen,
dass sie das nächste Zeichen enthält.
Dann ist das ein Ausrufezeichen. Aha. Also ich kann
auch mir jetzt eine Variable in I deklarieren,
die soll den Wert von dem Zeichen bekommen.
Also jetzt wieder, oho, der Char wird umgewandelt in
einen Int
Kann ich so machen und dann kann ich fragen,
welchen Wert hat denn jetzt I?
33. Also das ist das 33. Zeichen des Zeichensatzes ist ein Ausrufezeichen.
Jetzt kann ich hier nochmal Char erhöhen. Dann ist es
irgendwas anderes, dann kann ich es noch mehr erhöhen.
Dann sieht die Raute und so weiter. Das heißt,
ich kann jetzt mir ein Programm schreiben,
in dem die ganzen Aski-Zeichen ausgegeben werden.
Die einfachste Möglichkeit ist, ich sage hier irgendwie,
Char-CH ist gleich 32, genau wie es gerade hier gemacht
haben.
Dann sage ich System Out
Printeln, CH. Ja, das Zeichen wird einfach
nur auf die Konsole ausgegeben. Und dann sage ich plus
plus CH. So, und jetzt kann ich sagen,
naja, wie oft muss ich das jetzt machen?
Naja, bis zum 127 kopiere ich das mal hier.
Zack, zack. Ja, und so weiter.
Könnte ich jetzt ja 127 Mal hinschreiben. Ja,
nicht 127 Mal, sondern irgendwie 96 Mal oder was,
keine Ahnung. Also ungefähr von 32 bis 127. Damit könnte
ich erreichen, dass alle diese Zeichen ausgegeben werden.
Das kann ich jetzt übersetzen. Ich kann mir hier
ein Exemplar erzeugen
Und kann hier sagen, zeige mal druckbare Aski-Zeichen,
dann zeigt er mir hier die ersten so Ausrufezeichen, Anführungsstriche,
Raute, Dollar und so weiter, zeigt er mir an.
Okay, lässt sich machen. Ist aber nicht
so fürchterlich schlau, wie ihr sicherlich euch denken könnt.
So, jetzt, wir vollziehen ein bisschen nach,
wie die Welt der Programmierung sich entwickelt hat.
Jetzt könnte man nämlich sagen, naja, machen wir
es nochmal so. Ich setze hier ein Label hin.
Label 1, Doppelpunkt. Sowas kann man tatsächlich in Java
hinschreiben.
Das ist übersetzbar
Verdaulich. So ein Label kann man einfach hinschreiben. So,
jetzt hat also diese Anweisung, System Outprintal, ein Label.
Und jetzt könnte ich ja hier in dieser Zeile schreiben,
if, cha, kleiner 10727. 127, 127. Dann soll er
nochmal diese System Outprintal ausführen. Also das Zeichen wird ausgegeben,
dann wird das Zeichen erhöht, das nächste Zeichen wird gewählt.
Und solange, cha, kleiner als 127 kann man sagen, Go-To-Label
Klar, dass das funktionieren würde, oder? Also ich frage ab,
ob wir schon am 127. Zeichen sind und wenn das nicht
der Fall ist, springen wir nochmal hoch.
Also wir springen hier hoch. Und führen das. Das heißt,
was wir hier gerade programmiert haben, ist eine Schleife.
Mit einem Go-To. Das Blöde ist, das lässt sich
nicht übersetzen. Go-To gibt es in Java nicht. Und
wir werden jetzt auch gleich sehen, dass das anders geht,
deutlich eleganter als hier mit so einem alten Go-To.
Warum ist das so? Warum ist das Go-To nicht
in Java drin zum Beispiel
Der Hauptgrund ist, man kann mit so einer Go-To-Anweisung
beliebig in so einem Quelltext hin und her springen.
Ich kann da überall Labels hinsetzen, kann dann irgendwie querspringen.
Es ist sehr leicht möglich, damit unglaublich schlechten Code zu schreiben.
Der gute Herr Dikestra, der hat mal in einem der berühmtesten Leserbriefe,
die es in der Informatik gibt, geschrieben, Go-To-Statement,
Considered Harmfall.
The Go-To-Statement Edith Stance is just to primitive,
it's too much in invitation to make a mass of
once program
Mit diesem Leserbrief hat er unglaublich die Gemüter verstört in der Informatik.
Die haben also gesagt, das kann ja nicht wahr sein,
was du da erzählst. Das geht ja gar nicht
ohne Gute, ohne Gute können wir nicht programmieren.
Es geht ohne Gotto, das ist theoretisch nachgewiesen worden,
habe ich auf der vorigen Folge schon gezeigt.
Java kommt auch ohne Gotto aus, also geht es wirklich.
Aber das war noch nicht in allen Köpfen angekommen.
Und er hat ja eben halt tatsächlich relativ viel sich dann
auch, also relativ klar sich dagegen ausgesprochen.
Es ist auch tatsächlich nicht notwendig. Der gute Herr Deixtra
ist inzwischen verstorben, schon seit etlichen Jahren.
Das ist einer der ganz Großen in der Informatik.
Also wenn ihr den Namen mal irgendwo lest und der wird hier auch wieder auftauchen,
am Ende des Semesters vielleicht nochmal was zu seinem,
zu seinem berühmten Algorithmus sagen, kürzeste Wege in Grafen.
Ein sehr ungeduldiger Mensch, wahnsinnig belesen, wahnsinnig produktiv,
hat unglaublich viel Output produziert, aber er war auch jemand,
der sehr an formale Methoden geglaubt hat, geglaubt hat.
Er meinte also,
die Informatik wäre nur eine Fortsetzung der Mathematik und er wollte das Programm beweisbar sind,
formal beweisbar und hat unter anderem gegen Programmtesten gewettert,
Programmtesting can at best show the presence of Aeros,
but never their absence.
Das ist richtig
Aber das heißt nicht, dass man deswegen nicht testen sollte.
Und das war aber dann jahrelang die Meinung in der Informatik.
Herr DAX sagte einen großen Einfluss auf die Informatik und nicht immer nur den Besten.
Es gibt noch mehr Anekdoten zu ihm, wie spare ich
mir jetzt aus Zeitgründen? Was ich sagen wollte ist,
wenn wir heute im Imperativ programmieren,
dann sind die klassischen Kontrollstrukturen, Sequenz, Hauswahl und Wiederholung,
die wir eigentlich eben auch schon gesehen haben in den Darstellungsformen.
Sequenz kennt ihr schon,
die Auswahl habt ihr schon so ein bisschen wahrgenommen,
gucken wir uns heute genauer an mit so einem IF zum Beispiel.
Das habt ihr schon benutzt,
obwohl die es noch gar nicht richtig von mir
vorgestellt bekommen habt
Sprachen mit genau diesen Couchstruktur-Kontrollstrukturen, heißen auch strukturierte Sprachen.
Und das ist eben die enge Beziehung dann auch zur strukturierten Programmierung. So,
und die Idee ist eben tatsächlich bei der strukturierten Programmierung,
dass man sich beschränkt auf genau diese Dinge, Sequenzauswahl und Schleifenkonstrukte.
Und nichts anderes zulässt. Man braucht nicht so etwas
wie ein Gotto. Das heißt, quasi die Gene,
die Aminosäuren, quasi die ganz basischen Einheiten,
die wir hier so in unserem Programm haben, sind genau diese.
Und damit kommen wir auch aus. 40 braucht man noch
Prozeduren und später sehen wir uns dann noch abstrakte Datentypen an.
Eigentlich habt ihr solche Datentypen schon gesehen, nämlich die Klassen,
die ihr schreiben könnt, die ihr selbst definieren könnt,
sind auch solche abstrakten Datentypen.
Aber darum geht es heute nicht. Bevor ich jetzt auf
die bedingten Anweisungen und die Schleifen komme,
dann muss ich noch so zwei Begriffe einführen.
Zusammengesetzte Anweisungen. Das ist einfach nur English Compound Statements.
Das ist ein Begriff, der sich durchgesetzt hat,
wenn man mehrere Anweisungen als eine logische Anweisung auffassen will.
Also hier Statement 1 bis Statement N werden geklammert mit
irgendwie zwei Schlüsselwörtern oder mit Klammern, zum Beispiel Allgäu,
Beginn und End oder in Pascal.
Und dann ist das, was zwischen Beginn und End steht,
wird logisch als ein Statement aufgefasst
Das ist ganz nützlich. Die werden also einfach nur sozusagen
mit einer Schleife zusammengebunden. Etwas reicher ist das Konzept von Blöcken
. Das heißt, Blöcke sind zusammengesetzte Anweisungen, ergänzt,
um möglicherweise lokale Variablen. Das kennt ihr aus Java schon,
dass man in so einem Block ja auch Variablen deklarieren kann.
Also hier haben wir zum Beispiel zwei Variablen vom Typ in A und B,
da wird irgendwas mit denen gemacht hier, Punkt, Punkt, Punkt.
Und dann wird hier eine Bedingung ausgefüllt. FA,
kleiner B, dann wird hier irgendwie eine Tempvariable eingeführt,
lokal, die ist hier in diesem Block definiert
Block lokal und dann wird irgendwie hier so eine Belegung der Variablen ausgetauscht.
Also Tempvid Arzt, das ist der Inhalt von Azo gewesen,
dann wird der Inhalt von BA zugewiesen und dann wird der Inhalt von Temp wieder B zugewiesen.
Dadurch werden die beiden Belegungen der Speicherplätze getauscht. Sprachen,
die sowas haben, heißen auch Block strukturiert,
muss man ein bisschen aufpassen,
der Begriff ist relativ scharf definiert, blockt strukturierte Sprachen erlauben,
dass man so Dinge schachteln kann und auch geschachtelt dann Variablen deklarieren kann.
Aber sie erlauben eigentlich auch, dass man Prozeduren in Prozeduren schachteln kann.
Das ist was, was ihr in Java nicht könnt.
In Java kann man keine Methoden in Methoden schachteln.
Das geht nicht
Geht nur Methoden nebeneinander innerhalb einer Klasse. Das heißt,
die Methoden sind in einer Klasse geschachtelt, aber Methoden ineinander geht nicht.
Sprachen wie Pascal können tatsächlich Prozeduren in Prozeduren schachteln.
Gut, jetzt kommen wir zur Fallunterscheidung.
Und das ist eine sehr wichtige Anweisung, eine sehr zentrale,
weil man damit praktisch elementar fast alles steuern kann,
was in der Programmierung passiert.
Also Vollunterscheidung. Es gibt zwei Wegforschungsvertweigungen und Mehrwegverzweigung.
Die Zweiwegverzweigung ist das IF. Da gibt es genau zwei
Möglichkeiten. Entweder trifft die Bedingung zu,
die da geprüft wird oder sie trifft nicht zu
So taktisch sieht das so aus, if,
dann in runden Klammern muss dieser Ausdruck da stehen,
das muss da stehen.
Das ist also hier in der Syntax vorgeschrieben.
Dann kommt ein Statement und dann ist optional,
kann man noch ein Els angeben mit einem anderen Statement.
Und ganz wichtig, diese Expression hier über die Syntax hinaus
muss vom Typ Bolien sein.
Man darf da nicht irgendwie schreiben, if, 5. Geht nicht.
Höchstens fünf größer, x oder so. Dann ist es
eine Bedingung und dann ist es auch etwas,
was in dieser runden Klammer stehen darf
Okay. Hier haben wir mal so ein Beispiel.
If are kleiner B, dann soll das Minimum gleich A sein.
Ansonsten soll das Minimum gleich B sein. Das ist eine
ziemlich blöde, ziemlich blödes Beispiel für eine bedingte Anweisung.
Hat die mal eine Idee, warum ich das blöd finde?
Was könnt ihr euch da jetzt irgendwie dran auffallen?
War vielleicht noch nicht so, weil ich euch jetzt erstmal
das Bewusstsein dafür schärfen werde.
Okay, ich habe zufällig ein weiteres Java-Projekt.
Ein BlueJ-Projekt
Und zwar die Selektion, hier, Textanalysierer. Ich habe hier eine Klasse,
die werdet ihr auch in den Übungen zu sehen bekommen.
Also ein Textanalysierer, der bietet hier so Dienstleistungen an,
um Texte zu analysieren. Und die einfachste Dienstleistung,
die er mir anbietet, ist, eine Methode, hier ist Frage.
Ich übergebe eines dringen, eine Zeichenkette und diese Methode soll entscheiden,
ob das Ding eine Frage ist oder nicht.
Wann ist eine Zeichenkette eine Frage? Aber wenn am Ende
ein Fragezeichen steht, ganz einfach. Wenn am Ende
ein Ausrufezeichen steht oder ein Punkt oder sonst irgendwas,
ist es eben halt keine Frage. Das heißt,
was man hier sieht, einfach im Quelltext ist,
hier wird eine lokale Variable deklariert,
ist Frage,
die wird mit Falls initialisiert
Dann wird hier von dem Text, der übergeben wird, die Länge abgefragt.
Das ist etwas, was wir uns nächste Woche ansehen werden.
Da sehen wir uns ausführlich Strings an. Strings in Java
. Habt ihr auch schon implizit an vielen Stellen verwendet?
So richtig viel lernen werdet ihr nächste Woche drüber.
Da kann man auch viel falsch machen mit Strings.
Leider. Hier aber ganz einfach, die Länge wird in
einer Variante länger abgespeichert, die Länge der Zeichenkette.
Dann ist die letzte Position in dieser Zeichenkette Länge minus eins.
Ist sonst Drinkspezifikum, also die werden von null Beginn indiziert,
diese einzelnen Zeichen der Zeichenkette.
Also ist das letzte Zeichen Länge minus eins. So,
und dann wird hier das Char, letztes Zeichen ausgelesen,
also Text Char-Ed, also von der Zeichenkette,
das Zeichen an der Position ganz hinten.
So, und wenn das ein Fragezeichen ist,
dann ist Frage gleich True und dann Return ist Frage.
So, also das ist sehr ausführlich,
das kann man alles auch viel knapper hinschreiben, ja,
das ist hier sehr auseinandergezogen.
So, das kann man so einfach ausführen. Ja,
also ich mache mir mehr so einen Text analysiere,
ist Frage und dann sage ich hier mal irgendwie,
hallo, Ausrufezeichen.
Ist das eine Frage? Sagt er False. Gut,
dann sage ich, stelle ich nochmal eine Frage,
ist denn hallo?
Ist das
eine Frage
Ja, ist eine Frage. True, wunderbar. Ich bin
so begeistert von diesem Tool, von diesem Text analysiere,
dass ich jetzt sage, ich möchte den jetzt erweitern.
Der Textanalysierer, die Objekte dieser Klasse sollen einen Zustand bekommen.
Also wenn ich so einen Text analysiere, jetzt mehrfach frage,
dann soll der mitzählen, wie viele Fragen wirklich,
wie viele Dinge wirklich fragen waren.
Also einfach die Anzahl der Fragen zählen. So,
ihr seid ja jetzt geübte Java-Programmierer, habt ja schon Exemplarvariablen rauf und runter gesehen.
Also wenn ich jetzt hier sage, private in-Fragezähler,
Das kann ich hier so hinschreiben. Dann wisst ihr,
ich müsste jetzt einen Konstruktor schreiben, in dem dieser Zähler initialisiert wird.
Schenke ich mir jetzt, damit es schneller geht.
Sollte man aber natürlich tun. Ich weiß ja,
dass der auch jetzt initialisiert wird mit dem Wert Null.
Das heißt, wenn ich jetzt ein Exemplar erzeuge, hat der diese Exemplar variable Fragezähler. So,
jetzt kann ich hier in meinem Ist-Frage ja einfach sagen,
naja, wenn es eine Frage ist,
da möchte ich eben tatsächlich jetzt hier zusätzlich an dieser Stelle
im Kognit sich irgendwie an die richtige Stelle komme,
da so, da möchte ich jetzt Fragezähler Möchte ich da erhöhen?
Was mache ich das jetzt? Ich mache es mal
so ganz ausführlich. Frage, Zähler, oh ja,
ich weiß, ich sehe das schon.
Ihr lacht schon, ich höre euch schon lachen.
Fragezähler plus 1. Ihr meint, ich habe das nicht gesehen.
Aber ich habe das gesehen. So, also auch hier
der Fragezähler. So, also hier wird einfach jetzt,
wenn das letzte Zeichen an Fragezeichen ist, dann wird er der Fragezähler erhöht.
Großartig. Lässt ihr das übersetzen? Super, toll.
Ich habe mein Programm mal eben erweitert darum.
Jetzt kann ich mir hier so einen Textanalysierer bauen.
Ja, kann jetzt hier sagen, Mensch,
gib mir doch mal
Hallo. Hallo, Fragezeichen. Ja, True. Und
jetzt gucke ich mal hier auf das Exemplar. Und dann
hat er tatsächlich jetzt hier den Fragezähler um eins erhöht.
Super. Ganz großartig. Dann habe ich hier noch irgendwo
das Ding, das schließe ich mal.
Gut, jetzt nochmal ein Test. Ich teste nochmal zur Vollständigkeit
halber. Mit Hallo. Das ist ja keine Frage.
Also da kommt jetzt Falls zurück. Wunderbar. Dumme Reise
. Hat er jetzt hier oben den Zähler erhöht.
Obwohl das keine Frage war. Hat er den Zähler erhöht
? Jetzt bin ich ein bisschen verwirrt
Ich wundere mich. Ich wundere mich. Ich wundere mich
nicht wirklich. Ich hoffe, ihr wundert euch.
Was ist das Problem an dieser Stelle? Hat die mal
eine Idee, was da jetzt gerade schiefgelaufen ist?
Nur die erste Bedingung nach dem Prophet, die zweite nicht mehr.
Und das heißt, müsste man vielleicht der Kammer jetzt mal weiter.
Okay, also was er sagt, ist,
nur die erste Anweisung nach dem IF,
das ist Frage gleich Tu, die gehört zu der bedingten Anweisung.
Dieses hier, Fragezähler ist gleich, Fragezähler plus 1,
das gehört nicht dazu. Ich habe jetzt hier extra was
gemacht, was ich jetzt mal eben wieder anschalte.
Ich habe dieses Block-Highlighting von Java, von Blue Jay,
von dem Entertor ausgeschaltet. Blue Jay macht ja dieses wunderbare Blockhalle.
Ich zeige das mal. Einstellung hier, Struktur, Hervorhebung,
zack, fahre ich mal auf volle Lotte hoch. So,
und jetzt sieht man hier, ja, grün,
die ganze Klasse, gelb, die Methode, weiß,
die Anweisung im Rumpf der Methode, blau, die IF-Anweisung.
Und dann sieht man hier, ist Frage gleich zu,
das gehört zum IF. Das hier ist einfach falsch angerückt
. Das steht eigentlich, steht das hier.
Und wird immer gemacht, egal, ob letztes Zeichen,
Fragezeichen ist oder nicht
Das heißt, korrekterweise hätten wir es so machen müssen,
dass wir jetzt hier an dieser Stelle geschweifte Klammern setzen und
dann aus diesen beiden Anweisungen eine zusammengesetzte Anweisung machen,
damit diese zusammengesetzte, also beide Anweisungen,
in dem Fall ausgeführt werden, dass die Bedingung zutrifft.
Okay? Okay, das ist auch mehr oder weniger das,
was hier an diesem Beispiel passiert.
Also wir haben hier einen sehr einfachen Java-Code,
If-Summe gleich gleich null oder Summen gleich gleich null,
dann if-count gleich null,
dann Result gleich 1,
Else Result
gleich null
Nehmen wir mal an, die Belegung der Variablen,
vorher sieht es so aus. Summ hat den Wert,
null, Count hat den Wert eins, Result hat den Wert zwei.
Welchen Wert hat dann Result am Ende?
Wer werft mir mal einen Wert an den Kopf?
Ja? Null. Aha. Okay, andere Vorschläge?
Zwei. Also hier schon mal keine Einigkeit.
Das ist ja schon mal ein Hinweis,
dass da irgendwas faul ist
Okay, ich kann es euch verraten.
Hier ist das gleiche Programm anders hingeschrieben.
Hier ist das Els aber jetzt eingerückt unter das If.
Und hier ist das Els eigentlich unter dem If.
Zu welchem If gehört es denn? Ja, blöd.
Das da oben ist nicht richtig. Das ist nicht
richtig eingerückt. Tatsächlich gehört dieses Els zu dem If.
Ist halt so. Das nennt sich Dengling Els.
Also sozusagen man hat ein If eröffnet und jetzt könnte ja
irgendwo ein Els kommen. Und wenn dann es kommt,
dann muss man immer überlegen,
wo gehört das Els denn dazu
Das ist tatsächlich ziemlich doof. Vorsicht bei diesen geschachtelten IF-Anweisungen.
Ein Els-Zweig bezieht sich immer auf die letzte noch offene IF-Anweisung.
Ohne Els-Zweig. So, und auch hier wieder,
was man machen kann, man kann explizit klammern.
Ich sage hier, statt dass ich das so hinschreibe,
schreibe ich das mit unseren geschweiften Klammern hin.
Wunderbar. Dann ist sofort klar,
dass ich dieses Els hier auf das IF bezieht.
Es geht gar nicht anders aufgrund der Klammerung. Das heißt,
auch hier wieder diese geschweiften Klammern zu setzen, ist gut.
Dazu haben wir Quelltextkonventionen, diese hier bei gewöhnlichen Auswahlanweisungen,
IF-Anweisungen, sollte ein Gegebenheit für anderes Els stets in einer eigenen Zeile stehen.
Das ist das eine. Und dann verwende immer Blockklamotten.
Formal ist es in Java so, man muss da
keine Klammern hinschreiben, wenn es nur eine Anweisung ist.
Aber es tut nicht weh, die Klammern immer hinzusetzen.
Man ist einfach auch robuster, wenn man dann noch eine zweite Anweisung hinzufügen will.
Da muss man nicht die Klammern erst einfügen,
wie wir es gerade in dem anderen Beispiel gesehen haben,
in Blue Jay. Schreibt die Klammern einfach immer hin,
dann seid ihr immer auf der sicheren Seite.
Das ist softwaretechnische Erfahrung, formal, fordert Java das nicht.
Als Quelltextkonvention sagen wir, macht es immer und ihr werdet
viel besser damit fahren.
Ihr werdet viel weniger Fehler machen in eurer Software.
Soweit, so gut. Jetzt haben wir
die einfache Verzweigung gesehen, abhängig von einer bulschen Bedingung.
Also bulsche Bedingungen haben ja genau zwei Werte, True of
Falls. Dann kann man also sagen, entweder,
wenn die Bedingungen zutrifft, mache was, oder Els was anderes.
Jetzt gibt es aber auch so etwas, wo man mehrere Dinge tun will.
Also abhängig von einer auf der Tastatur gedrückten Taste soll in
einem Spiel eine von mehreren Prozeduren aufgerufen werden.
Ihr kennt das vielleicht, früher gab es so Spiele,
die musste man mit der Tastatur spielen,
vor diesen ganzen geilen Controllern, die man heute so hat.
Also irgendwie ASD, NF und dann noch die Leertaste mit
diesen Tasten soll man irgendwas machen. Und abhängig,
welche Taste gerückt wird, soll irgendeine Prozedur aufgerufen werden, irgendeine Methode.
So könnte ein Java-Programm dafür aussehen. Switch, gedrückte Taste,
das scheint irgendeine Schar-Variable zu sein. Dann gibt es hier Case A,
wenn es das A ist auf der Tastatur,
dann bewege Spieler nach links, nach links, D,
Bewegespieler nach rechts, A, D, S,
irgendwie nach unten und W, also das sind also diese A,
S, D, ja,
man kann das auf der Tastatur ganz gut sehen.
Und Leertaste da unten, vollrundende Rakete ab.
Also ich kann da irgendwie mein Flugzeug hin und her bewegen,
Asteroids zum Beispiel. Asteroids ist ein bisschen anders,
da muss man sich drehen,
Ist erstmal ganz einfach. Man hat da verschiedene Fälle,
die dann hier ausgeführt werden. Als Case Label in so
einem Switch Case in Java, schreiben wir ausschließlich Konstanten hin.
Da dürfen keine Variablen stehen. Da muss immer eine Konstante
stehen. Hier eine Character-Konstante. Also häufig ist das
immer Pforst von Typ Int oder Char im Java.
Okay, was passiert, wenn die Break-Anweisungen führen,
wenn man an diese Break-Anweisungen würde, nicht da stehen?
Weiß jemand schon, was da passieren würde? Ja. Okay,
er sagt, er führt, also in dem Fall,
dass jetzt gedrückte Taste,
belegt es mit A und dann tatsächlich hier dieser Case-Label A angesprungen wird,
wird hier Bewegespieler nach links ausgeführt.
Wenn da kein Break steht, wird einfach das nächste ausgeführt.
Aha, hier steht Bewegespieler nach rechts. Das heißt,
er wird nach links bewegt und gleich wieder nach rechts bewegt.
Und dann würde hier ein Break stehen und dann wäre nichts passiert.
Das heißt, mit diesem Break bewirkt man das wirklich,
wenn dieser Fall abgearbeitet ist, die anderen Fälle nicht mehr berücksichtigt werden.
Das ist ein sehr relativ komisches Konstrukt. Also es gibt Leute,
die kritisieren das an Java, die sagen,
das Switch ist doof mit dem Break, weil ich muss das ja explizit hinschreiben.
Viel schöner wäre das doch, wenn das implizit immer da rausgesprungen würde.
Wir werden gleich Beispiele sehen, wo das auch teilweise
nützlich ist
Dass man nicht immer da automatisch rausspringt aus dem Case Label.
Wenn wir mal ein weiteres Beispiel. Für eine auf der Tastatur
gedrückte Taste soll ausgegeben, ob sie einen Vokal liefert oder nicht.
Also eine Abbildung von einem Tastendruck, von einem Zeichen auf einen Buhl.
Vokal oder nicht Vokal. Kann so aussehen. Char,
Buchstabe, irgendwie liest ein Zeichen von der Tastatur,
wie immer das funktioniert. Bulien, das Ergebnis,
was wir liefern wollen, ist das ein Vokal?
Falls, initialisiert, lokale Variablen. So, dann mache ich
einen Switch. Also Switch über die Belegung von dieser Varianten
Buchstabe. Und wenn das ein A, ein A,
ein E, ein E und so weiter ist,
dann ist Vokal
gleich true
Aha, also kann man anscheinend auch mehrere Case-Label untereinander schreiben.
Und wenn irgendeiner von diesem Case-Label zutrifft,
dann wird genau bis zum nächsten Break gelaufen,
da ist kein Break, also wird hier, ist Vokaltruhe ausgeführt.
Und wenn es keiner dieser ist, dann ist es eben
halt, dann bleibt, ist Vokal als variable falls.
Ja, dann ist es hier so ein bisschen nett gemacht,
könnt ihr euch in Ruhe angucken.
If is Vokal, kein Vokal oder ein Vokal,
haha, ist aber nur so ein Detail.
Spannender ist die Frage, was passiert denn jetzt?
Wenn zwei Case-Label denselben Wert haben. Ich kann da ja
vielleicht mal wieder ein Blue-Jay-Projekt zeigen
Das hier. Hier haben wir das Gleiche nochmal hingeschrieben.
Also ist Vokal, Case A, E, I
und so weiter. Was glaubt ihr, was passiert,
wenn ich jetzt aus Versehen hier unten statt einem U ein A-Hinschreibe.
Also derselbe Case Label, dieselbe Konstante kommt zweimal vor.
Was würdet ihr sein, was passiert? Was wäre so
euer, eure Schätzung? Ja. Ich würde sagen,
wir kommen Fehler groß, dass ihr sagt,
es sind nicht zwei gleiche Sachen
Okay, er sagt,
er schätzt, da kommt ein Fehler, eine Fehlermeldung,
kommt die bei der Übersetzung oder kommt die bei der Laufzeit?
Er sagt bei der Übersetzung. Sehr gut geraten. Tatsächlich,
wie ich das jetzt übersetze, dann sagt er hier,
Diplikit Case Label. Das kann der Compiler erkennen.
Er sieht, da ist zweimal derselbe Case Label,
das ist Blödsinn, den zweimal hinzuschreiben.
Fehlermeldung. Auch da wieder, was der Compiler statisch sieht,
da kann er auch was zu sagen.
Da kann er dann auch eine Meldung rausgeben.
Also machen wir es mal wieder korrekt hier.
Also machen wir da ein U draus.
Das ist dann wieder okay
Okay. Sehr schön. Weiteres Beispiel. Für einen Monat im Jahr,
den der Benutzer durch eine ganze Zahl benennen soll,
soll ausgegeben werden, wie viele Tage der Monat hat.
Also ich gebe an Monat eins, wie viele Tage hat er?
Sagen wir, Januar ist der erste Monat,
ist 31 Tage und 12 hat irgendwie auch 31 und so weiter.
Was möchte ich haben? Also eine Abbildung von irgendwie einer
Monatszahl auf, die Anzahl der Tage.
Lässt sich sehr schön mit einer Switch-Anweisung programmieren.
Mein Monat ist irgendwie das, was der Benutzer irgendwie angeht,
aber von dem Monat, wo er es wissen will,
dann eine lokale variable Tage
So, Switch über diesen Monat,
den der Benutzer angegeben hat, wenn es 1, 3,
5, 7, 8, 10, 12 ist,
also das Wissen über die Anzahl der Tage im Monat hier rein programmiert,
dann 31 und dann hier 4, 6, 39,
Case 2, 28, Default, tagegleich minus 1.
Also das ist irgendwie, wenn jemand 35 angibt als Monat,
den gibt es ja nicht, den 35. Monat,
dann ist das irgendwie minus 1. Gut,
ist nicht vollständig, ich weiß, Schaltjahre,
Vorsicht, also hier Februar hat auch manchmal 29 Tage,
egal.
Hier geht es erstmal darum, dass man mal zeigt,
was man mit so einem Switch
alles machen kann
Okay, links angegedeutet, hier der Kontrollfluss. Also wir kommen da runter,
hier kommt der Switch, dann wird geguckt,
was für ein Wert steht denn zur Laufzeit in der variablen Monat.
So, und wir nehmen mal an,
der Benutzer hat eine Sieben eingegeben,
also er möchte vom siebten Monat wissen,
wie viele Tage der hat, dann wird wirklich quasi da runtergesprungen.
Das ist wie so ein Go-To.
Es wird wirklich jetzt zu dem Case Label 7 gesprungen.
Da geht es dann los mit der Ausführung,
da kommt nur lauter Case Label, also geht es hierhin,
bis Tage wird gleich 31 gesetzt und bis zum Break.
Und das Break sagt,
geh raus aus dem Switch
Wir gehen raus aus dem Switch und können hiermit System Out printeln,
das ausgeben. Der Monat, Monat hat Tage, Tage.
Während diese Variablen ausgegeben. Okay. Was passiert,
wenn jetzt keiner der Fälle zutrifft und man diese Default-Anweisung nicht hätte?
Ich habe ja hier so einen Default stehen,
das ist wirklich ein Schlüsselwort in Java,
was so viel sagt, wenn keiner der anderen Fälle zutrifft,
dann gibt es eine minus eins aus.
Was wäre jetzt, wenn das Default fehlen würde?
Wäre das ein Problem oder wäre das kein Problem?
Wer ist denn meins, das wäre ein Problem?
Wer ist denn meines wären Problem? Okay,
wer ist der Meinung, das wäre kein Problem?
Die Mehrheit
Beide haben recht, in gewisser Weise.
Es ist wie bei einem If mit einem Elz.
Wenn ihr keinen Elz-Zweig angibt, nicht so schlimm.
Wenn die Bedingung nicht zutrifft, wird ihm nichts ausgeführt.
Auch hier, wenn keiner der Case-Label zutrifft, wird nichts ausgeführt.
In dem Fall haben die ein Recht, die sagen,
es ist okay, wenn kein Default angegeben ist.
In diesem konkreten Beispiel ist es leider so,
dass die lokale Variable Tage, ihr wisst ja,
lokale Variablen, muss man initialisieren.
Die wird hier nicht initialisiert, die wird hier einfach nur deklariert.
Dann wird sie in verschiedenen Fällen,
wird sie belegt,
also initialisiert quasi
Und wenn der Defaultfall fehlen würde, dann würde hier unten versucht,
aus der variablen Tage was rauszulesen,
obwohl sie noch gar nicht initialisiert ist.
Das heißt, der Compiler würde meckern. Zufällig habe ich
das ja auch hier. Also ich kann mal hier,
damit es mir auch glaubt, das auskommentieren, auskommentieren,
übersetzen. Variable Tage, might not have been initialized.
Also hier wird die Belegung von Tage zurückgegeben.
Tage ist eventuell nicht initialisiert, also geht das nicht.
Also wir machen hier mal einen
Oh, das war nicht so schlau, ups,
das war auch nicht schlau.
Naja, ich wollte eigentlich das hier wieder einkommentieren.
Jetzt kann ich es wieder übersetzen und es macht das Richtige.
Okay, soviel zum Switch. Ich will nicht übertreiben mit
dem Switch, weil das ist irgendwie ein ziemlich kruder Mechanismus.
Dieses Beispiel zum Beispiel könnt ihr euch in Ruhe nochmal ansehen.
Es steht ja auch im Skript. Das ist so ein Beispiel,
wo man sieht, dass durch mehrere Case Label durchgelaufen wird,
kann durchaus sinnvoll sein für die Berechnung von einem bestimmten Wert.
Das ist so eine kleine Hausaufgabe, könnt ihr euch
in Ruhe angucken. Wollen wir jetzt hier nicht vertiefen.
Selektion mit Switch, also mit dieser Auswahlanweisung
Allgemeines Schema, Switch, eine Expression. Und was da
üblicherweise stehen darf, ist ein End-Expression oder auch eine Char-Expression.
Man darf seit Java 1,7 auch über Strings switchen.
Tatsächlich darf da eines Dringausdruck stehen. Das ist natürlich toll
. Und dann müssen natürlich auch hier wieder als Case-Labels,
als diese Werte konstanten stehen, also String-Konstanten,
da ist es ziemlich mächtig und ziemlich cool.
Und man kann eben halt mit diesem Breakdown dafür sorgen,
dass dann auch da rausgesprungen wird und Default sagt,
was, wenn keiner der anderen Fälle zutrifft.
Das ist also eine Mehrwegverzweigung und es ging über dem IF
natürlich ein bisschen anders
Mehrere Ausdruckstypen, nicht nur Bulien, bei Ifnor Bulien,
hier tatsächlich verschiedene Typen, können das Steuern da oben,
diese Ausdruck kann von verschiedenen Typen sein.
Es kann einer oder es können auch mehrere Fälle ausgewählt werden.
Wir haben da so mehrere Caseleben und es kann sein,
dass wirklich auch mehrere Caselabel ausgeführt werden.
Und statt es statt eines eindeutigen Elffalls gibt es einen Standardfall,
für alle nicht explizit benannten Fälle. So,
also in Java werden alle nach einem passenden Label folgenden Anweisungen durchlaufen,
auch wenn der nächste Label oder der Default Label erreicht wird.
Um dies zu vermeiden kann, die Auswahl und Weise mit Break verlassen werden.
Alternativ kann ich natürlich auch aus so einer Switch-Anweisung mit einem Return
rausspringen. Ich kann ja mitten in einer Methode sagen,
so return, da wird die ganze Methode beendet
Auch so kommt man dann natürlich raus aus so einem Switch oder mit einem Throw.
Ihr habt das möglicherweise schon gesehen mit Throw, was weiß ich,
Illegal Argument Acception, kann ich eine Acception werfen.
Das ist momentan der Mechanismus, den ihr bisher kennengelernt habt,
um die Programmausführung zu unterbrechen. Im Sinne von,
wie ist irgendwas fehlerhaft, ich schmeiße meine Acception.
So, in einer Switch-Anweisung darf jeder Case-Label nur einmal vorkommen
und wenn kein Case-Label zutrifft und kein Defort-Label fahren ist,
wird die gesamte Switch-Anweisung übersprungen.
Okay, das ist eigentlich schon alles,
was ich sagen wollte zum Switch und da haben wir doch
jetzt mal wieder ein bisschen Stumresi
Welchen Wert hält die Variable X nach Ausführung des folgenden Java-Quelltextes?
Ich habe also hier eine Variade I, die wird mit zwei vorgelegt,
dann habe ich eine Variable X, die wird mit null vorgelegt.
Dann habe ich einen Switch, das über die Belegung von I switcht,
also abhängig von I irgendetwas tut,
und dann haben wir hier drei Case-Label, Case 1,
Case 2 und Default.
Ja, und welchen Wert hat die Variable X
nach Ausführung des folgenden Java-Quelltextes
Jetzt bin ich aber voll gespannt. Also weil es ist dann
immer so, ich habe das ja gerade alles erzählt.
Also ganz frisch jetzt. Und dann bin ich einfach gespannt,
ob das jetzt, ob ich es gut erklärt habe.
Es liegt natürlich dann an mir,
wenn ich es nicht gut erklärt habe,
wenn das jetzt noch von vielen falsch gemacht wird.
Okay, also wir haben jetzt
so 128 Stimmen super.
Ich halte mal an
Wir gucken uns mal die Verteilung an. Nicht schön,
nicht schön, nicht schön. Ja, also ziemlich viele sagen zwei,
dann sagen man ein paar sagen vier und ziemlich viele sagen sechs.
Die richtige Antwort ist sechs. 37,5 Prozent. Also etwas mehr
als ein Drittel. Also tatsächlich haben auch ziemlich viele jetzt
wieder das nicht richtig gemacht. Was ist das Problem?
Es ist überhaupt kein Problem. Es ist nur so,
ja, IS2, SwitchE, also wird zu diesem Case Label gesprungen.
Also wird X um zwei erhöht. Also hat X den
Steht da kein Break. Also wird der Default-Fall auch
noch ausgeführt. Also X ist gleich X plus 4,
also ist der Wert 6. Kein Break.
Break, wichtig, sonst geht es einfach durch.
Okay. Gibt es noch Fragen jetzt zum Switch oder zum IF?
Ja. Aber das ist im Case auch im Blog auch.
Er fragt, ob man nach dem Case auch einen Blog aufmachen kann.
Ja, das kann man. Tatsächlich könnte ich auch jetzt hier zum Beispiel sagen,
ich mache da eine geschweifte Klammer auf und dann eine geschweifte Klammer zu.
Ist nur relativ unüblich. Also dieses Switch ist schon ziemlich komischer Mechanismus,
man ja wirklich sozusagen da irgendwo hinspringt und dann ab da wird alles ausgeführt.
Also ist das mit den Blöcken dann fast egal,
aber man kann natürlich dann da noch lokale Variablen deklarieren.
Also man kann da auch noch einen Block aufmachen, ja, kann man.
Okay, sonst noch Fragen hier zum Switch, ja?
Wie lange ist der Block? Wenn das was ist? Er fragt,
ob der Fehler mit dem doppelten Case Label auch auftritt,
wenn zwischen den beiden Case Label ein Break steht.
Also wir können ja hier mal simulieren, also nehmen wir
hier mal, ich nehme hier mal die zwölf.
Dann steht ja zwischen den beiden Case Labeln, steht ja dann ein Break.
Macht das einen Unterschied? Nee, macht keinen Unterschied.
Duplicit Case Label. Der Compiler sieht, das Ding ist doppelter,
macht er nicht. Sonst noch Fragen. Ich finde das immer toll,
wenn man live zeigen kann, dass das nicht funktioniert.
Großartig. Ich liebe Blue Jay. Wenn keine Fragen
mehr sind, dann machen wir fünf Minuten Pause.
Dann würde ich gerne weitermachen. Ich muss es mal positiv
anmerken, dass ihr wirklich sehr diszipliniert seid.
Also das fällt mir positiv auf. Das war in
den Jahren vorher tatsächlich schon
deutlich anders
Ich sage, es geht weiter, dann ist es auch
relativ schnell ruhig. Das finde ich prima.
Gut. Jetzt. Schleifen. Motivation. Schleifen kommt man
relativ schnell drauf, dass man sowas haben möchte.
Wir haben eben das Beispiel gesehen mit diesen druckbaren Aski-Zeichen.
Hier ist das Beispiel, wie man dieses wiederholte Ausgeben eines Zeichens,
die ganzen Aski-Zeichen von 32 bis 126 auf der Konsole ausgeben kann.
Das ist hier mal so angedeutet, wie das aussehen könnte.
Ein anderes Beispiel, wir wollen wiederholt ein Passwort einlesen,
solange die Eingabe
noch nicht korrekt ist
Das ist in Software ziemlich häufig so, dass man irgendwie sagt,
okay, gib mir ein Passwort und prüfe ich mal.
Und wenn das das richtige Passwort ist,
dann kommst du durch und wenn es das Falsche ist,
dann versuchen wir es halt nochmal.
Und hier ist so einfach mal angedeutet, wie das aussehen kann.
Man hat also dieses so lokale Variable String Passwort,
dann steht hier du, irgendetwas, System Outprint Passwort,
dann liest Zeile von Benutzer, Wild Passwort,
nicht Passwort Equals.
Also solange das Passwort nicht gleich dem Passwort ist,
macht das nochmal. Also solange soll hier das
hier weiter ausgeführt werden. Das gucken wir uns einfach
mal an
Ich habe hier ein entsprechendes Bluejay-Projekt, dass mir das macht.
Das sieht so aus, genau das,
was hier auf der Folie steht, Stringt Password,
also hier verlange Passwort, Stringt Password, System Outprint Passwort,
Passwort ist gleich Liest, Zeile von Benutzer,
Wild Not Passwort, Equals, das Passwort.
Und dann irgendwann, wenn er durch ist,
System Outprint, du darfst eintreten. So, ja,
dann gucken wir doch mal, ob wir hier mal uns
zum Schleifendreher geben lassen und jetzt mal hier sagen,
verlange Passwort.
Wie heißt das Passwort
Hallo? Nee, funktioniert nicht. SE1. Nee, passt auch
nicht. Ja, ihr könnt es ja nicht wissen,
weil wenn ihr euch den Quelltext anguckt,
dann steht da irgendwie lokale Variable das Passwort.
Und die ist hier nicht zu sehen. Die habe ich
ganz unten hingeschrieben. Damit ihr sie nicht sehen könnt.
Bald ist Weihnachten. Zintstern. Du darfst eintreten. Habt
ihr gesehen, dass tatsächlich diese Schleife mehrfach durchlaufen wurde,
dieser Schleifenrumpf an dieser Stelle
Also das, was hier auf der Folie steht,
System Out Print wurde mehrfach gemacht, bis irgendwie etwas zutraf,
also solange diese Bedingung zutraf, wurde das wiederholt.
Hier war das so, das ist auf jeden Fall einmal ausgeführt worden.
Hier ist es so, dass das eventuell nicht unbedingt ausgeführt wird,
das gucken wir uns nochmal genauer an. Okay,
Computer, also die Dinger, mit denen ihr ja umzugehen,
lernt, die ihr kontrollieren lernen sollt.
Wir sind ziemlich gut da drin, beliebig oft irgendwas
zu wiederholen
Die sind ziemlich doof. Also Computer sind einfach doof,
kann man sagen. Aber sie sind damit sehr schnell.
Also sie sind unheimlich schnell sehr doof. Und ich finde
das Zitat auch von dem Gunther Duck ganz schön.
Der normale Mensch hat heute mehrere Rechenpower zu Hause.
Das Zitat ist schon wieder Jahre alt. Heute würde man sagen,
der normale Mensch hat mehr Rechenpower in der Hosentasche,
in seinem Handy als Houston, als es ein Apollo-Problem hatte.
Und die sind damit zum Mond geflogen. Also das ist schon national.
Aber da waren eben halt auch ziemlich viele Menschen beteiligt.
Da sind ja nach wie vor die schlaueren Wesen auf diesem Planeten.
Solche Wiederholungsanweisungen, die man da programmieren kann, die erlauben,
dass man Dinge Keinmal, einmal oder auch mehrfach ausführt.
Und diese Konstrukte, die es in imperativen Sprachen gibt,
dazu, die werden auch umgangssprachlich Schleifen genannt.
Jetzt gibt es so mehrere Fragen, die man sich stellen muss,
die man so mal genauer hinguckt, wie denn diese Schleifenkonstrukte funktionieren.
Wie ist denn so eine Wiederholungsanweisung aufgebaut? Wie wird die Wiederholung
kontrolliert und wo steht der Kontrollmechanismus? Also die Grundidee ist,
ich möchte etwas nur einmal hinschreiben und mehrfach ausführen lassen.
Natürlich kann man auch sagen, wenn ich Anweisung A
viermal ausführen will, schreibe ich sie einfach viermal hin.
Da haben wir ja am Anfang auch so gemacht,
das kann man so machen, ist aber Schon dann nicht mehr zweckmäßig,
wenn ich nicht genau weiß, während ich das Programm schreibe,
wie oft es denn zur Laufzeit wirklich ausgeführt werden soll.
Denn statisch stehen da fünf Anweisungen,
aber es kann ja dynamisch von ganz unterschiedlichen Dingen abhängen,
wie oft etwas ausgeführt werden soll.
Also wollen wir das Ding textuell nur einmal hinschreiben,
Anweisung A und dann drumherum legen wir eine Kontrollstruktur.
Hier grün angedeutet, zum Beispiel wiederhole viermal und dann
ist hier das so geklammert mit Ende der Wiederholung.
So, und so sieht eigentlich eine imperative Schleife immer aus.
Man hat irgendwie einen Schleifenrumpf, das sind die Anweisungen,
die wirklich wiederholt werden sollen.
Und wir haben eine Schleifensteuerung, die das Ganze quasi umklammert
Zwei Bedingungen, zwei Begriffe, die ganz zentral sind,
schleifen Rumpf, meistens einen Block, schleifen Steuerung,
irgendwie Mechanismen aus der Sprache.
Die Schleifensteuerung kann sehr unterschiedlich aufgebaut sein,
kann eine feste Anzahl von Wiederholungen festlegen, eine variable Anzahl,
die von dem Inhalt einer Variablen abhängig ist oder von einer Bedingung.
Okay, was gibt es so für Schleifenarten? Es gibt
zum Beispiel sowas, führe genau viermal aus, Anweisung 1.
Kann man sich ganz gut vorstellen, dass die Schleifensteuerung sagt,
viermal etwas machen und dann die Anweisung 1 ist da
so der Schleifenrumpf
Oder es wird irgendeine Variable N berechnet,
dann wird Führe N mal aus, also abhängig von dem,
was N für eine Belegung hat, wird dieser Block hier mehrfach ausgeführt.
Das sind sogenannte Zählschleifen, wenn man damit auf der Basis von Zähler,
Variablen oder auch von Zählern sagt, so oft soll es ausgeführt werden.
Das nennen wir mal Zählschleifen hier. Gut,
dann haben wir hier so was, solange eine Bedingung B zutrifft,
das ist eine abweisende Schleife, in dem Sinne,
alle diese Schleifen, die hier zu sehen sind,
sind abweisende Schleifen.
In dem Sinne, dass es sein kann,
dass wenn da steht,
führe genau null mal aus,
dass eben halt diese Anweisung eins
gar nicht ausgeführt wird
Oder auch hier, wenn N mit null belegt ist,
wird eben halt diese Amazon gar nicht ausgeführt.
Oder wenn die Bedingungen schon gleich zu Anfang nicht zutrifft,
wird die Anweisung 4 auch gar nicht ausgeführt.
Wenn das der Fall sein kann, dass der Rumpf
gar nicht ausgeführt wird, ist es eine abweisende Schleife.
Anders ist es bei dem Beispiel mit dem Passwort,
was wir gerade gesehen haben,
da wird ja mindestens einmal ein Passwort eingelesen und dann wird geprüft,
ob es das richtige Passwort ist.
Und dann ist es tatsächlich so,
dass das eine nicht abweisende Schleife ist oder eine endgesteuerte Schleife.
Also da wird erst am Ende geprüft,
ob der Rumpf nochmal ausgeführt wird.
Man mindestens einmal wird der Rumpf ausgeführt.
Einfach nur Begriffe
Und diese Dinger hier, die mit Bedingungen arbeiten,
die heißen auch bedingte Schleifen. Gibt eben halt in
verschiedenen Sprachen unterschiedliche Konzepte, wie man das machen kann.
In Java kann ich schon mal so ein bisschen verraten,
ist eigentlich fast alles letztendlich eine bedingte Schleife.
Außer auch die Zählschleifen sind implizit eigentlich bedingte Schleifen. Okay,
ich habe jetzt schon so diese beiden Varianten hier gezeigt,
also abweisen und nicht abweisende Schleifen,
ist hoffentlich intuitiv klar geworden, ist Begriffshandwerkszeug,
was wir euch hier so beibringen,
damit ihr
überschleifen reden könnt
Diese Begriffe sind tatsächlich von uns hier so festgelegt.
Die haben wir natürlich auch versucht, so ein bisschen uns anzulehnen an Begriffe,
wie sie auch woanders auftauchen. Aber sie sind einfach nützlich,
um über Schleifen Typen reden zu können, welches denn so gibt.
Also kopfgeschleute Schleifen sind diese Abweisenden und die anderen,
die nicht abweisenden, auch vielleicht Fuß- oder Endgesteuert.
So, dann die Sache mit den bedingten Schleifen. Da ist es wieder ganz spannend,
sich zu überlegen, naja,
wenn also die Ausführung des Schleifen Rumpfes abhängig ist von einer bestimmten Bedingung,
dann ist erstmal wichtig, dass man sich sagt,
nach jeder Ausführung des Schleifenrums oder auch vor jeder Ausführung des Schleifenrums,
je nachdem,
ob am Anfang oder am Ende
die Bedingung steht
Wird diese Bedingung erneut überprüft. Also das ist ganz wichtig
. Bei dem Switch war es eben so,
die Bedingung wird einmal überprüft und dann wird irgendwo darunter verzweigt und dann,
selbst wenn man dann in dem Code, der da steht,
diese Variable, die da oben abgefragt wurde, verändert,
ändert das nichts mehr an der Verzweigung.
Also es wird wirklich einfach stumpf dahin gesprungen und dann so,
bei den Schleifen ist es ein bisschen anders.
Bei den Schleifen ist es so, wenn der Rumpf ausgeführt
wird, dann wird erneut geprüft.
Das heißt, die Bedingung wird jedes Mal neu ausgewertet.
Jedes Mal wird die Bedingung erneut überprüft. Bei jedem Schleifendurchlauf.
So, jetzt gibt es zwei Möglichkeiten. Man kann entweder sagen,
führe den schleifenden Rumpf aus, solange die Bedingung noch zutrifft,
Oder führe den Rumpf aus, bis eine Bedingung zutrifft.
Das sind zwei verschiedene Arten, die man schleifen formulieren kann.
Die einen nennen wir positiv bedingte Schleifen, also so,
da ist eine Bedingung. Und wenn die zutrifft,
dann wird der Rumpf ausgeführt, positiv bedingt, positiv,
ja, Rumpf ausführen. Und die anderen nennen wir zielorientiert,
bedingt, also mache das, bis etwas zutrifft.
Mal an einem Beispiel. Also ein relativ eingängiges Beispiel ist
ein einzelnes Zeichen, soll so lange eingelesen werden,
bis es entweder ein J oder ein N ist.
Also ich möchte jetzt vom Benutzern eine Antwort haben,
er soll entweder Ja oder Nein sagen
Okay, fachliche Anforderungen kann ich direkt umsetzen in so Pseudo-Code,
also so hier grün, meinen Schleifen rum, wiederhole,
Schleifenrumpf, Einlesen eines Zeichens CH,
bis das Zeichen gleich J ist oder das Zeichen gleich N ist.
Das eine oder das andere. Wunderbar. Kann ich ja
so hinscheiden. Liest sich auch ganz gut. Wiederhole eine
seines Zeichens bis das gleich J oder gleich Endes.
Das Blöde ist, so können wir es in Java nicht hinscheiden.
Weil in Java gibt es nur positiv bedingte Schleifen,
also nur Schleifen, bei denen es so ist,
dass wenn die Schleifenbedingungen zutrifft, Dann wird der Rumpf nochmal ausgeführt.
In diesem Fall ist es so, wenn die Bedingung zutrifft,
ist es ja zu Ende. Also das ist ja hier,
mache das so lange, bis die Bedingung zutrifft.
Das heißt, wenn ich das jetzt in Java hinschreiben will,
dann muss ich das negieren, dann muss ich diese Bedingung umkehren, logisch negieren.
Das heißt, ich mache aus, wiederhole bis das hier zutrifft,
schaue gleich gleich J oder Cha gleich, gleich N,
mache ich dann, wiederhole so lange,
und jetzt sieht der Ausdruck so aus, Char,
ungleich J,
und Char
Das ist wieder mal so ein Paradebeispiel,
wo man erst mal wieder stutzt und sagt, okay,
scheint Äquivalent zu sein.
Das hier ist eine zielorientiert bedingte Schleife, bis die Bedingung zutrifft.
Können wir in Java so nicht hinschreiben? Also müssen wir
es positiv formulieren. Und da müssen wir diese Bedingungen sozusagen einmal umdrehen.
Und dieses Umdrehen dieser ganze rote Ausdruck hier ist ja ein bulscher Ausdruck,
wenn man den negiert, dann greifen die ganzen Regeln der Bulschen Algebra.
Und in diesem Fall die de morganischen Regeln. Also hier genau diese,
wenn ich sowas habe wie Not P. Orcu,
dann ist das das Gleiche wie Not P. End Not Coo
Mal wieder, man braucht das Zeug. Gut, Zählschleifen
. Zählschleifen sind die Schleifen, wo man tatsächlich eine bestimmte
Anzahl von Wiederholungen festlegt durch eine variablere, eine konstante.
Meistens sind die dann tatsächlich auch abweisend, weil dann diese Variablen
ja auch dann gleich mit dem Wert Null anbelegt sein kann.
Zählschleifen verfügen üblicherweise über einen Schleifenzähler. Also hier so ein Beispiel in Pascal,
um Gottes Willen, also so variable I vom Typ Intager,
VI gleich 1 zu tennen, um mal zu zeigen,
dass es wirklich Sprachen gibt,
wo man so Zählschleifen direkt hinschreibt von 1 bis
Beginn Right on Hallo und Durchlauf Nummer I. Und da sieht man auch,
dass dieser Schleifenzähler, dieses I, was hier deklariert ist,
ne, das da deklariert ist,
dass das auch im Rumpf ausgelesen werden kann.
Also man kann es auch verwenden im Rumpf. Was gefährlich ist,
wenn man das im Rumpf dann auch noch verändert.
Also das ist dann immer so, will man das tatsächlich so haben?
So, jetzt gucken wir uns mal an,
welche Schleifen gibt es denn in Java?
Und da gibt es eben halt genau drei Arten.
Eigentlich gibt es vier, die vierte gucken wir uns erst
in ein paar Wochen an. Es gibt die Wildschleife,
die ist, und erstmal habe ich ja schon gesagt,
alle sind positiv bedingt.
Also bei allen Schleifenarten im Java ist es so,
wenn die Bedingungen zutrifft, wird der Rumpf nochmal ausgeführt.
Bei den Abweisenden hier bei Wire und bei Four ist es tatsächlich so,
wenn die Bedingung zutrifft, dann wird es ausgeführt,
das Statement der Schleifenrumpf.
Und hier genauso. Die Vorschleife gucken wir uns noch genauer an.
Bei der Dualstreife ist es einfach so, sie ist endgesteuert.
Also das Statement wird auf alle Fälle einmal ausgeführt und dann
wird erst geprüft, ob es nochmal passieren soll.
Aber auch da die Bullshit Expression positiv bedingt im Sinne von,
der Rumpf wird nochmal ausgeführt, wenn die Bedingung zutrifft.
Wenn nicht so ein Biss formulieren will,
muss ich
die Bedingung umdrehen
Okay, diese Vorschleife, die ist so ein bisschen tricky,
die ist komplex, da seht ihr schon daran,
dass die syntaktisch auch schon deutlich aufwendiger formuliert ist mit ganz vielen optionalen Sachen.
Die gucken wir uns jetzt mal ein bisschen genauer an.
Die schieben wir hier nochmal mit rüber. Die ist einfach
sehr flexibel. Also die gesamte Schleifensteuerung kann zwischen den Runden
Klammern stehen. Also hier, die gesamte Schleifensteuerung heißt,
für die ganze Schleife, der Schleifenzähler kann da deklariert werden.
Also zum Beispiel hier möchte ich die Ziffern von null
bis 9
Also 4 and E, hier wird eine Variable in
diesem Schleifenkopf, in der Schleifensteuerung hier deklariert.
Ist also auch nur innerhalb der Vorschleife sichtbar aus innerhalb des Rumpfes.
I gleich null. Dann wird hier geprüft, ist I,
kleiner 10 und dann wird hier dieses I auch erhöht.
Denn die ganze Steuerung dieser Variablen ist also hier in dem
Kopf und in dem Rumpf wird dann wirklich irgendwas gemacht.
Dieser Rumpf wird eben halt mehrfach ausgeführt. Das habe ich
hier dabei und das müssten wir uns mal angucken,
weil das ganz spannend ist
Ihr seht hier, ich habe diese Drucke alle Ziffern.
Also das ist so mehr oder weniger das Gleiche,
was auf der Folie steht, vor mit den, und so.
Das habe ich jetzt hier etwas anders hingeschrieben,
weil ich euch was zeigen will,
weil nämlich jetzt der Debugger uns etwas sehr schön zeigen kann und das ist total schlau,
diese einzelnen Teile der Voranweisung auf verschiedenen Zeilen zu haben,
weil der Debugger Highlight hat ja immer die Zeile,
in der er gerade was macht.
Und das machen wir mal hier so einen Haltepunkt hin.
Ich setzen das ganze Ding mal so ein bisschen weiter hier rüber.
Wir brauchen noch gar nicht die ganze Breite,
können wir das hier mal so
ein bisschen rüberschieben
Und jetzt möchte ich hier mal den Schleifendreher ausführen.
Sag also hier, drucke alle Ziffern. Sag mal,
dann haben wir hier den Debugger. Jetzt seht ihr hier,
wir sind an dieser Stelle, wo Inti gleich,
also bei der Initialisierung von dem Fonds.
Also hier wird erstmal die Variable I deklariert. Ihr seht,
die ist noch nicht als lokale Variable Sichtler im Debugger.
Wenn ich jetzt Schritt über mache,
dann wird als nächstes hier I kleiner gleich zehn geprüft,
aber man sieht jetzt hier, I ist als lokale Variable vorhanden.
Also I ist null. Okay, jetzt,
und das ist ganz wichtig, wird die Bedingung geprüft.
Und wenn die Bedingungen zutrifft, und das wird sie ja,
weil Null ist ja kleiner als zehn, dann wird der Rumpf ausgeführt.
Also es wird nicht hier dieses Plus-Plus-I gemacht. Also wenn
ich jetzt sage Schritt über, dann schwuppdiwupp wird tatsächlich dieser Rumpf hier ausgeführt.
Also I, die Prüfung hat gegeben, es ist keiner als 10,
also wird jetzt System Outprinting aus. Wenn ich jetzt Schritt über mache,
wird das auch ausgegeben, kommt auf die Konsole raus,
also hier schwupp ist die Konsole, wir können ein bisschen kleiner machen,
dass wir das auch sehen hier, das ist das Fonds, so.
Und wenn ich jetzt hier sage Schritt über,
jetzt ist aber dahin gesprungen, das heißt,
nach dem Rumpf wird jetzt hier dieses Plus-Plus-I ausgeführt.
Dann sieht man hier, I ist jetzt erhöht worden
Und jetzt wird diese Initialisierung nicht nochmal gemacht.
Es wird nur einmal gemacht, diese Initialisierung. Jetzt wird
ja die Bedingung geprüft. Eins ist kleiner als zehn,
also wird hier System Outprintant gemacht und so weiter und so weiter.
Ihr seht also,
es wird hier in einer relativ komischen Reihenfolge werden die Dinge ausgeführt,
der Rumpf, dann wird anschließend das Ding erhöht,
dann wird wieder geprüft und so weiter.
Und dann können wir das hier ein bisschen weitermachen.
Bis zur neun. Ja, so,
jetzt ist hier die IS9, also wird es ausgegeben.
Jetzt wird I erhöht, IS10, jetzt wird I geprüft,
IS910, nein, 10 ist nicht kleiner als 10,
also wird hier rausgesprungen und fertig
Also man kann tatsächlich diese Vorschleife sich sehr schön veranschaulichen,
im Debugger von Bluegeot,
wenn man diese Teile der Vorschleife auf verschiedenen Zahlen schreibt,
habe ich vor einem Jahr entdeckt, ihr seid die ersten,
die das in der Vorlesung live sehen,
ich habe das letztes Jahr erst nach der Vorlesung als Tipp bekommen,
das ist sensationell, also coole Sache das.
Ja, aber das ist ein relativ komplexes Konstrukt, da kann man relativ viel mit falsch machen.
Endlosschleifen brauchen wir uns jetzt nicht noch groß ansehen,
sind meist ungewollt und deshalb unbeliebt,
häufig ist das so, man macht irgendwie einen Programmierfehler,
eine der einfachsten Inselschleifen ist diese hier,
Wild True, Irgendein Rumpf wird dann endlos wiederholt,
weil True ist immer true und dann wird diese Schleife auch immer ausgeführt.
Oder auch hier sowas. For, ja, da wird
irgendwie endlos nichts ausgeführt, weil hier steht sozusagen, da steht nichts.
Das ist auch ein ziemlich kurzes, ziemlich kurze Endlosschleife.
Ja, dann hier noch dieser Hinweis. Also früher hatte Apple
ja dieses Logo von diesen Karten, von der Maps-App.
Und da haben sie so einen Kartenausschnitt von Cupertino,
wo sie selber mit ihrem Firmensitz sitzen momentan noch.
Und da diese Straße, die heißt Infinite Loop.
Witzig, die haben, okay, ist Informatikerhumor.
Gibt es erstmal noch jetzt Fragen zu schleifen, oder?
War das soweit erstmal ganz nachvollziehbar? So. Okay, er fragt,
kann man denn bei der Vorschleife auch zwei Variablen deklarieren?
Und die Antwort ist ja, ihr könnt tatsächlich hier
mehrere Variablen deklarieren und in dem Rumpf auch benutzen.
Also das ist wirklich sehr mächtig,
wenn ihr hier mehrere Variablen haben wollt, dann könnt ihr
hier mit Komma getrennt auch diese Wirrvariablen im Rumpf eurer Vorschleife deklarieren.
Das werdet ihr auch in den Übungen noch sehen.
Wir geben euch so ein bisschen Quelltext vor,
wo das dann auch drin vorkommt.
Kommt in Übungen noch dran. Sonst noch eine Frage
zu schleifen
Das scheint, doch da ist eine Frage, ja.
Gibt es überhaupt einen anderen Schritt, wenn wir schreiben plötzlich plus die,
die Plus und Plus in dem Verschreibung? Okay, er fragt,
ob es einen Unterschied gibt, wenn ich an dieser Stelle hier,
statt plus plus I, I plus plus schreiben würde.
Den Unterschied habe ich hier mal verdeutlicht,
wenn das innerhalb eines Ausdrucks passiert,
für dieses Beispiel macht es keinen Unterschied,
weil das ist nicht explizit festgehaltene Konvention,
dass wir es eher mit dem Prefix-Operator machen,
als mit dem Postfix-Operator, Postfix-Operator zu komischen Fällen Ergebnissen führen kann.
Das habe ich hier demonstriert in Vorlesung 4, glaube ich.
Guckt euch das nochmal an, das Video. Ansonsten einfach
sich merken, präfix plus plus ist hübscher als postfix.
Sonst noch Fragen. Hat nicht so viel mit Schleifen zu tun,
sonst noch ganz nach. Das war's. Gut,
dann machen wir nochmal eben so ein paar Folien,
bevor wir dann nochmal so eine Storesi-Frage stellen. Also,
was ihr jetzt schon ein paar Mal von mir gehört habt,
ist, dass Programme so statische Eigenschaften haben.
Also ich habe schon ein paar Mal gesagt, der Compiler kann euch Feedback geben.
Also zum Beispiel, dass ein Case-Label hingeschrieben wird.
Das kann der Compiler erkennen zur Übersetzungszeit. So,
und diese Begriffe Übersetzungszeit und Laufzeit, die sind sehr zentral,
die müssen sehr gut verstanden sein,
wenn man mit Programmierung irgendwie gut auskommen will.
Und zwei Begriffe, die wir uns genau angucken wollen,
die da so ein bisschen in die Richtung gehen,
auch sind Sichtbarkeit und Lebensdauer.
Okay. Laufzeit und Übersetzungszeit. Einfach nochmal ein bisschen explizit gemacht.
Zwei zentrale Begriffe. Laufzeit ist nicht die Zeit,
die euer Programm braucht, um ausgeführt zu werden,
sondern das ist generell der Zeitpunkt oder die der Zeitraum,
in dem euer Programm läuft.
Nicht die Dauer, sondern einfach der Zeitraum. Das ist
die Laufzeit. Die Zeit, zu der das Programm läuft.
Die liegen überschiedlich, die Übersetzungszeit. Und auch das ist nicht gemeint im Sinne von,
wie lange braucht denn der Compiler, um das zu übersetzen,
was ihr schreibt, sondern das ist der Zeitpunkt,
wenn der Compiler es gerade tut.
Also zur Übersetzungszeit schaut der Compiler auf euren Quelltext.
Und auch ihr schreibt euren statischen Quelltext und das ist alles Übersetzungszeit.
Compile-Time. Also da kann man die ganzen statischen Eigenschaften eines Programms betrachten.
Da steht eine Klassendefinition und die kann ich mir statisch angucken.
Also ich habe hier eine Klassendefinition, die kann ich mir
ganz statisch angucken, kann irgendwelche Aussagen treffen.
Wie viele Zeilen sind das? Wie viele Methoden sind das
, die da stehen? Wie viele Kommentare stehen da?
Wie lesbar ist das? Welche Syntaxregeln gelten denn da?
Und welche Sichtbarkeitsregeln gucken wir uns gleich noch an?
Und das muss man halt ganz klar unterscheiden von dem,
was zur Laufzeit passiert. Laufzeit ist das, was passiert,
wenn das Programm läuft. Einfach ein ganz anderer Zeitpunkt.
Und da geht es um die dynamischen Eigenschaften. Also vor
allen Dingen erstmal, was macht das Programm denn überhaupt?
Das ist dann
die Semantik
Es gibt so Programme, da kann man das schon aus dem Quelltext direkt ablesen.
Das sind dann sehr einfache Programme. Bei heutiger Software ist es aber fast immer so,
dass man erst zur Laufzeit sagen kann,
was das Programm wirklich tut,
weil Software heutzutage sehr stark interaktiv ist und je nachdem,
was ein Mensch an Input liefert,
macht die Software etwas und dann ist also so ein Wechselspiel zwischen Computer und Mensch und dann ist eben die Semantik dessen,
was passiert sehr, sehr stark dynamisch.
Wie viele Objekte werden erzeugt? Das ist oft
erst zur Laufzeit, steht das erst fest.
Welche Lebensdauer haben die Objekte? Also wie lange existieren die
? Welche Methoden werden aufgerufen? Welche Methoden es gibt,
steht im Quelltext statisch, aber welche Methoden aufgerufen werden,
Das kann ja Methoden geben, die werden nie aufgerufen.
Oder welche Daten werden manipuliert? All das sind Fragen,
die werden zur Laufzeit entschieden und sind da wichtig.
Wir können uns das nochmal überlegen, wenn wir uns einfach mal
nolokale Variable angucken. Ich weiß nicht, ob wir hier
gerade mal so ein Beispiel haben mit der lokalen Variablen.
Haben wir jetzt hier doch, hier ist dringend Passwort,
ist eine lokale Variable. Bei diesem Fall lange Passwort da oben.
Was wissen wir zur Übersetzungszeit über lokale Variable? Naja,
wir können uns das angucken und sehen, das Ding hat einen Namen,
das Ding hat einen Typ und hat eine Sichtbarkeit.
Das heißt also, diese Variable hier,
Passwort ist nur innerhalb dieses gelben Rumpfes
der Methode sichtbar
Aber was wissen wir meist erst zur Laufzeit über eine lokale Variable?
Naja, also die Belegung, die kann ja bei jeder
Ausführung anders sein. Am Anfang hier natürlich noch gleich,
aber dann wird sie ja, wird ja,
der Benutzer gibt irgendwas ein und dann wird das neu belegt.
Und das ist also dynamisch, welche Belegungen diese Variable hat.
Die Lebensstory, ja wie oft braucht denn der
blöde Benutzer und das richtige Passwort einzugeben?
Das kann irgendwie 20 Mal dauern oder auch nur einmal.
Oder auch formaler, wenn man technisch hinguckt,
wo steht denn diese Variable im Speicher?
Das ist auch etwas, was erst zur Laufzeit irgendwie entschieden wird.
Anderes Beispiel. Es gibt eine Aussage,
die Return-Anweisung ist immer die letzte Anweisung in einer Methode
Kann man so einfach mal so sich auf der Zunge zergehen lassen.
Nehmen wir mal dieses Beispiel. In Max,
also ich habe zwei Variable, zwei formale Parameter A und B
und ich möchte den Größeren der beiden als Ergebnis liefern, also den Maximalwert.
So, if a größer Beet and Return A, else,
Return B. Quelltext gut lesbar, schön mit geschweiften Klammern,
können wir nachvollziehen. Aber hier würde ich ja sagen,
das Return A ist ja nicht die letzte Anweisung.
Sondern das Return B ist hier irgendwie textuell die letzte Anweisung.
Na gut, gemeint ist zur Laufzeit,
ist die Return-Anweisung immer die letzte Anweisung einer Methode
Das ist einfach so. Das heißt,
wenn der Compiler auch nach so einer Return-Anweisung irgendetwas stehen sieht,
dann sagt er, das kann man gar nicht mehr erreichen.
Ich weiß nicht, ob wir hier ein Beispiel haben,
wo ich das mal zeigen könnte, haben wir irgendwas mit Return?
Nee, haben wir nicht. Naja, leider nicht.
Gut, habe ich jetzt hier nicht gebaut.
Also wenn ich jetzt hier tatsächlich dahinter schreiben würde,
eine Variable I deklarieren würde dahinter, dann würde er sagen,
kann ich erreichbar. So, was man machen könnte,
ist zur besseren Lesbarkeit, das muss man nicht so machen,
aber was kann man so machen?
Man kann sagen, ich deklariere meine Ergebnisvariabler gleichen Namen sogar,
wie diese Methode heißt. Also wenn die Methode Max heißt,
dann habe ich eine Ergebnisvariable,
die nenne ich genauso vom Typ des Ergebnisses hier.
Das darf man in Java so machen. Und dann mache
ich meine Bedingungen und dann wird also diese ergebnisvariabliche belegt und
am Ende habe ich dann tatsächlich hier meinen Return Max.
Dann ist es wieder so, dass sowohl dynamisch,
dass die letzte Anweisung ist, das war da oben auch so,
aber auch statisch sozusagen die Return-Anweisung die letzte ist.
Das ist immer ganz schön, wenn das zusammenpasst.
Erhöht die Lesbarkeit, man muss das nicht tun.
Manchmal ist es auch einfach lesbarer,
wenn so ein Return gleich zum Anfang passiert und man
gleich wieder rausspringt aus einer Methode
Gut. Sichtbarkeitsbereich. Wichtiger Begriff, Englisch, Scope,
Scope of a variable, also der Sichtbarkeitsbereich einer Variablen.
Auf eine bestimmte Variable kann ich nur in einem,
in ihrem Sichtbarkeitsbereich zugreifen. Das ist tatsächlich etwas,
was statisch ist. Eine statische Eigenschaft einer Variable.
Im Quelltext direkt sichtbar, direkt feststellbar. Man hat hier
so ein bisschen so ein Nebel und da kommt irgendwie so
ein Moo und wahrscheinlich sind das Kühe.
Man kann es kaum erkennen, kann man das eigentlich da erkennen?
Ganz schwach. Gut,
ist auch nicht
so wichtig
In der Objektorientierung ist es einfach so, die Methoden,
die bilden gegenüber ihrer Umgebung einen eigenen Sichtbarkeitsbereich.
Das heißt, in einer Methode könnt ihr lokale Variablen deklarieren und da auch verwalten.
Und alle im Rumpf einer Methode deklarierten Bayern sind nur im
Rest des Methodenrumpfes, aber nicht außerhalb der Methode sichtbar.
Also ich habe jetzt hier vielleicht nochmal die Bagger zu.
Ein Beispiel, guck mal, sag mal den Schleifendreher an.
Ich möchte jetzt hier zeigen, dass eine lokale Variable,
ich kann zum Beispiel hier Eine variable In-I-Deklarieren und die mit zwölf initialisieren.
21. Ja, ja, ja, ich weiß.
Das kann ich machen. Das geht sogar deshalb,
weil nämlich dieses I hier nur lokal ist innerhalb dieses Rumpfes, dieser Schleife.
Das heißt, ich kann hier das I wieder deklarieren.
Das könnte ich aber nicht andersrum machen. Wenn ich jetzt sage,
hier, dieses I möchte ich gerne vorher deklarieren,
In-I gleich 21 und dann mache ich hier drinnen geschachtet nochmal ein I,
dann wird der Compiler meckern.
Variable E is already defined in Method Drucker alle Ziffern. Das heißt also,
ich habe hier eine lokale Variable und dann wird hier in
dem rumpft dieser Vorschlag für ein weiteres E deklariert.
Er sagt ja, hm, das ist vermutlich ein Fehler,
den du da machen willst.
Das ist keine gute Idee. Das heißt, dieses E ist tatsächlich,
als ich es da unten deklariert habe, war es,
von dem Zeitpunkt der Deklaration an für den Rest des Rumpfes sichtbar.
Und wenn ich es da drüber deklariere,
natürlich auch schon in dem Schleifen rum von dem Fonds.
Das heißt also, im Rest des Methodenrumpfes. Die Umgebung
einer Methode ist in ihrer Objekt- und Hinsprache, ist das die Klasse.
Das heißt, die Exemplarvariablen kann ich in allen Methoden zugreifen.
Und diese Sichtbarkeitsbereiche von Klassenmethoden sind ineinander geschachtelt.
Das kennt ihr natürlich auch. Ihr seht das ja
hier immer
Wenn man das so schön farblich in Blue Jay sieht.
Also diese Sichtbarkeitsbereiche, für diese Gelben sind in den gesamten
Grünen Sichtbarkeitsbereich geschachtelt und dann wieder da drin, möglicherweise mehrere geschachtelte Blöcke.
Und das haben wir ja auch schon gesehen,
dass diese Blöcke geschachtelt werden können.
Hier ist nochmal was mit den Sichtbarkeitsbereichen. Dieses Beispiel habe ich,
glaube ich, auch nochmal im Blue Jay hier irgendwo.
Sichtbarkeit hier, dieses Beispiel. Ups, ich mache das
nochmal zu, weil ich ja hier was fragen will.
Wenn ihr diesen Quelltext seht,
wenn ihr so ein bisschen SE1 jetzt schon gemacht habt,
was fällt euch hier ganz besonders negativ auf?
Also was springt einen förmlich an? Was ist hier ganz schrecklich?
Das ist hier ganz schrecklich. Das X hat keinen Unterstrich
. Er sagt es, er benennt es genau richtig.
Dieses hier ist ja eine Exemplarvariable. Und bitte deklariert eure
Exemplare ja immer mit einem Unterstrich. Das ist zumindest in
der SE1, in der SE2 wollen wir das so.
Hier ist es mit Absicht so gemacht,
weil ich zeigen will, dass hier jetzt mehrere Methoden stehen,
also Start und M1 und M2 und im Rumpf von M2
wird hier eine Variable X Typ Double deklariert.
Und hier wird dann X 1.5 zugewiesen. Also 1,5 ist
ein Double Literal und das wird der Varianten X zugewiesen.
Das kann man so machen. Das sieht ungefähr so aus.
Also hier sind die Sichtbarkeitsbereiche hier in M1 ist ein neues X
deklariert und da ist eben halt X dann das X sichtbar.
Das überdeckt das weiße X hier. Und in einem Zwei,
da kann ich tatsächlich X einen Wert 5 zuweisen,
dann wird dann, da wird Bezug genommen auf das weiße X,
also auf das, was hier die Exemplarvariable ist.
Ist total blöde und verwirrend. Das sieht man schon daran,
wenn ich jetzt hier einfach mal die Deklaration auskommentiere,
dann wird nämlich, also ich kann es erst mal,
es war übersetzbar, habt ihr gesehen,
wenn ich jetzt das hier auskommentiere,
dann wird hier plötzlich auf ein anderes Ex zugegriffen.
Also plötzlich ist dieses X, bezieht sich jetzt auf das X,
auf die Exemplarvariable da oben und dann ist es auch nicht mehr übersetzbar.
Dann sagt der, possible does of precision, naja,
ich will ein Doppelliteral, ein Double-Literal einer Int-Variablen zuweisen.
Geht ja nicht, wissen wir. Aber wenn ich das jetzt hier wieder einkommentiere,
also so, dann geht das plötzlich wieder, weil dann sagt er,
naja, X ist ja jetzt hier eine andere Variable.
Also einfach, die ist eine Deklaration,
hat die andere überdeckt
Das ist etwas, was ziemlich gefährlich ist.
Und deswegen sagen wir, macht die Exemplare ja immer,
wir nennen sie immer mit einem Unterstrich,
dann passiert das nicht mehr so leicht.
Okay, selbst wenn ihr die Dinger mit Unterstrich benennt,
kann man trotzdem noch was falsch machen.
Hier ist ein Beispiel, was wir schon ganz oft im Übrigensbetrieb hatten,
die Uhrenanzeige, habt ihr vielleicht schon programmiert?
Ja, hier sind die Dinger ganz brav mit Unterstrichen deklariert.
Und dann sollten sie im Konstruktor initialisiert werden,
also Stunden mit einer neuen Nummeranzeige und Minuten mit einer neuen Nummeranzeige.
Und dummerweise haben sie dann aus Versehen Nummernanzeige nochmal davor geschrieben
Also das Ding hier nochmal erneut deklariert. Wenn das da vorsteht,
wenn der Typ nochmal davor steht,
dann hat man jetzt an dieser Stelle hier zwei neue lokale Variablen deklariert,
Stunden und Minuten, die werden kurzzeitig irgendwie initialisiert und am
Ende des Rumpfes des Konstruktes sind die wieder weg.
Und die Exemplarvariane bleiben völlig unverändert. Also auch das hilft
nicht viel. Also es ist zwar schon hilfreicher,
das mit den Unterstrichen zu machen,
aber man kann immer noch sich ins Knie schießen.
Es gibt leider ziemlich viele Möglichkeiten dazu. Okay,
Sichtbarkeit der Elemente einer Klasse, in Java kennt ihr schon,
Public legt fest, dass es für einen Klienten sichtbar ist.
Private, es ist nur innerhalb der Klasse sichtbar
Wir so für Exemplarvariablen, aber auch für private Hilfsmethoden.
Protected und Default kommt erst in der SE2. Lebensdauer ist etwas,
wo man sagen muss, das haben wir jetzt eben schon gesehen.
Diese lokale Variable X in der einen Methode gerade hat ja
die andere überdeckt, die diese Exemplarvariable hat noch gelebt,
aber sie war nicht sichtbar.
Sie war überdeckt. Das heißt, die können durchaus auseinanderlaufen,
Lebensdauer und Sichtbarkeit. Bei Objekten ist es tatsächlich so,
dass die Lebensdauer davon abhängig ist, ob noch Referenzen auf sie existieren.
Ganz wichtig letzte Woche, ich brauche immer eine Referenz,
um mal auf ein Objekt zugreifen zu können.
Wenn ich keine Referenz mehr habe, wenn keine Referenz mehr
existiert auf ein Objekt, Ich kann das Objekt auch weg.
Also wenn ein Objekt für niemanden mehr sichtbar ist über eine Referenz,
dann brauchst du es auch nicht mehr länger zu leben.
Andersrum kann man sagen, solange ich eine Referenz habe,
bleibt das Objekt immer am Leben.
Ich werde nie in Java die Situation haben, dass ich
über eine Referenz nicht mehr auf ein Objekt zugreifen kann.
So eine Dengling References, das gibt es in Java nicht.
So, das zusammengefasst, die Lebensdauer werden wir nochmal
ein bisschen ausführlicher und in den nächsten Wochen angucken.
Jetzt habe ich nochmal eine Frage. Und zwar habe ich
hier eine folgende Java-Methode
Relativ kompliziert aus. Es ist eine Vorschleife, im Rumpf
einer Methode. Und dazu habe ich eine kleine Sturissi-Frage.
Stimmt gar nicht. Ich gehe jetzt nochmal zurück.
Erstmal diese hier. Welchen Wert hält die Variable? X
nach Ausführung des folgenden Java-Quellentextes. So, da haben wir
eine kleine Wildschleife. Also X wird hier null initialisiert,
solange dann das gleiche Xplus 1. Was kommt da wohl raus?
Welchen Wert hält die Variable X nach Ausführung des Quellentextes
Folgende Möglichkeiten. Integer-Min-Value. Falls ihr nicht wisst,
was Integer-Min-Value ist, ich kann euch das mal zeigen.
Also ich kann hier tatsächlich mal hinschreiben.
Integer.min. Value. Ist also irgendwie eine relativ kleine Zahl.
Die kleinste. Oder es gibt eine Endlosschleife. Oder
der Wert ist null. Oder das Programm bricht ab,
weil es einen Überlauf gibt. Oder es ist Integer-Max-Value.
Integer-Max-Value gibt es auch als Konstante genau wie Integer-Min-Value
Was glaubt ihr, was kommt da raus?
Cool, wir haben schon wieder unsere 100,
30 Antworten gleich zusammen hier.
Ja, gut,
ich halte das mal an
Okay. Wir gucken auf die Verteilung. Okay,
also ziemlich viele glauben, dass es eine Endlosschleife ist.
Also ungefähr dritte Glaube ist eine Endlosschleife. Dann gibt es ein Fünftel,
die glauben, es gibt einen Abbruch mit einem Überlauf.
Und dann gibt es auch einige Sachen,
es gibt ein Intiger Max Value,
dann sagen einige sagen Intiger Min Value und dann ein paar sagen sogar,
es ist null.
So, es ist nicht so, dass die richtige Antwort die ist,
die am wenigsten gewählt wurde. Das ist schon mal beruhigend,
aber nicht so beruhigend, weil es ist die,
die am zweitwenigsten gewählt wurde
Woran liegt das? Die Variable X bekommt den Wert null.
Die Belegung null. X ist größer gleich null, also
wird die Wahlschleife ausgeführt. Es wird X um 1 erhöht.
Und das wird so lange gemacht, solange X größer null ist.
Irgendwann ist der Wert Integer Max Value, also der größte
positive Wert. Das ist immer noch größer als null.
Also wird der Schleifenrumpf nochmal ausgeführt. Dann wird einer
drauf addiert und dann sind wir plötzlich bei Integer Min Value
Das ist ein negativer Wert. Ein Überlauf ist kein Unfall
. Ein Überlauf in Java führt nicht zu einer Exception.
Manche glauben das, dass es eine Exception gibt,
wenn eine Variable so überläuft.
Ist nicht der Fall. Das ist einfach ein Zahlensystem,
das Zweierkompliment und dann fängt er einfach wieder hinten an.
In dem Moment ist das natürlich die Zahl kleiner als null,
also wird die Schleife abgebrochen.
Deswegen ist das hier Intiger Min-Value. Okay,
einen habe ich noch. Hier ist die Abstimmung und hier
ist die Folie dazu.
Hier ist die Schleife
Ja. Welches Ergebnis liefert diese Methode, wenn bei einem
Aufruf als aktueller Parameter der Wert 5 Uhr geben wird?
Also P sei mit der Belegung 5 belegt. So,
und jetzt wird hier diese Vorschleife ausgeführt und was meint ihr,
was kommt da raus?
10, 15,
20 oder
Die Antworten kommen noch recht zögerlich. Erste Stöhner erreichen mich
ja vorne. Ja, es ist tatsächlich so,
wenn man, wenn man so ein Programm im Kopf ausführen will,
das ist nicht so leicht.
Ihr könnt das natürlich jetzt einfach abtippen und dann in Blue Joy einfach ausführen.
Aber das wäre geschummelt. Und in der Klausur könnt ihr
das auch nicht
Okay, jetzt kommt zu einem Ergebnis,
werft mir einen Wert an den Kopf.
100 Antworten hätte ich gerne, damit wir hier so eine
gewisse Masse haben. Entscheidet euch für eine der vier,
ja, wir haben 100 Antworten, sehr schön.
Ich halte das mal an. Ja, 125,
ja, das reicht. Gut, wir gucken mal auf
die Verteilung. 60 Prozent sagen,
es ist
Ist das die richtige Antwort? Es ist die richtige Antwort
. Was passiert hier? Result wird auf null gesetzt,
dann haben wir hier eine Schleife, die sagt,
wir fangen erstmal bei Inti gleichen Null an und solange I kleiner ist als P. Also I,
kleiner als P, das heißt 0-1,
2, 3, 4. Das heißt,
fünfmal wird dieser Rumpf durchlaufen.
Fünfmal mit dieser Rumpfrühe laufen.
Und jedes Mal wird hier das I verdoppelt,
also am Anfang null verdoppelt
Dann eins verdoppelt, zwei verdoppelt und so weiter.
Also die Summe von eins bis vier bis zehn,
das verdoppelt, ist 20. Wunderbar, sehr schön.
Dann haben wir heute wieder eine großartige Punktleidung hingelegt.
Wenn keine Fragen mehr sind, dann machen wir Schluss für
heute.
Vielen Dank