2. Erstellung einfacher Programme Vorwort Wer programmiert eigentlich heute noch?! Die Frage drängt sich auf, wenn man das Vorlesungsverzeichnis einer Universität mit Fachbereich Informatik durchliest. Sehen Sie selbst: http://www.informatik.uni-stuttgart.de/fak_lehre.html http://wob.iai.uni-bonn.de/Wob/de/view/class152_id1621.html Sehr vereinzelt findet man noch Veranstaltungen wie Programmierpraktika im Grundstudium oder Programmierung. Bei letzterem geht es offensichtlich um keine einzelne Programmiersprache sondern um das Meta-Thema. Der Rest der Vorlesungen scheint sich um dieses für den Laien so eng mit der Informatik verbundene Gebiet nicht zu scheren. Der erste Eindruck täuscht nicht. Programmiersprachen hat man nebenbei zu lernen. Und bitte nicht nur zwei oder drei! Aber keine Sorge! Man geht keinesfalls davon aus, dass heutige Studenten so viel schlauer sind, als vor 10 Jahren. Es hat sich in den letzten Jahren nur gezeigt, dass ein zukünftiger Informatiker viel weniger auf diesem Gebiet gefordert ist. Ein Beispiel aus der Welt der Autos soll uns dies veranschaulichen: Fährt man heute mit dem Wagen in die Werkstatt weil die Zündung unregelmäßig zu sein scheint, dann wird der Motor mit einer Messstation verkabelt und je nach Messergebnis bekommt man ein komplettes Modul ausgetauscht. Von diesem Modul muss der Handwerker nicht wissen, wie es intern funktioniert. Er weiß aber, was es tut und woran man es anschließen muss (Schnittstelle). Auf unseren Fall übertragen: Während vor einem Jahrzehnt Informatiker mit fundierter Programmierfahrung durchaus gute Berufschancen hatten, sind heute Kenntnisse in diesem Maße nicht mehr verlangt. Nur ein kleiner Teil der eingestellten Informatiker beschäftigen sich mit der Formulierung neuer Algorithmen. (Die Skript-Kids, die sehr hardwarenah Viren und Trojaner erzeugen, sollten allerdings tiefgehende Kenntnisse über die verwendete Sprache besitzen. Aber auch hier gibt es fertige Module, mit denen jeder des Lesens kundige Zwölfjährige böses anrichten kann...) Die überwiegende Anzahl der Informatiker wird heute eingesetzt, um vorhandene Hard- und Softwarebausteine (sog. Standardlösungen) zusammenzustecken und den Bedürfnissen des Arbeitgebers anzupassen. Sie müssen das Innenleben dieser Bausteine nicht kennen - sie könnten es gar nicht, da sie eine so große Anzahl von ihnen einsetzen. Sie betrachten nur ihr Äußeres, eine Art Bedienungsanleitung, ihre Schnittstelle zur Umgebung. Sie müssen verstehen, welche Teile dieser Schnittstelle für die gegebene Aufgabe relevant sind und wie sie mit anderen Bausteinen 76 zusammengefügt werden kann. Das traditionelle Programmieren von Verzweigungen und Schleifen, Bits und Bytes, Integers und Charakters, kommt nur am Rande vor. Wenn Sie jetzt das Gefühl haben, dass wir unsere Zeit mit diesem Thema verplempern, so denken Sie nicht weit genug: Es gibt sehr wohl Gründe, auch noch heute über Programmiersprachen nachzudenken. Selbstverständlich nicht, um in einer willkürlich gewählten Sprache Hochleistung zu vollbringen! Unsere Ziele sind eher geprägt von dem Willen, einen Überblick zu erhalten. Wir wollen daher • • • • • • in fünf bis sechs Programmiersprachen „reinschauen“, lernen, welche Sprachen für welche Probleme geeignet sind, in der Lage sein, bekannte Sprachen einordnen zu können, verstehen, was Programmiersprachen leisten, den Umgang mit Schnittstellen und Modulen nachvollziehen können, in zwei Sprache (Delphi, Java) Grundkenntnisse erwerben. Beim Reflektieren über diese Ziel muss man feststellen, dass sich der Informatikunterricht in den letzten Jahren (notgedrungen) erheblich verändert hat. Bei der obigen Liste handelt es sich um den Inhalt des 2.Kapitels! Besucht man Informatik von Klasse 11 bis 13, so werden sieben Kapitel behandelt. Und die meisten davon sind vom Stoffumfang nicht geringer! Es reicht halt nicht, die Programmiersprache, die der Lehrer kann, zwei bis drei Jahre durchzuochsen ☺.... 77 0. Klassifierung der Programmiersprachen Fangen wir doch ausnahmsweise mit einer Aufgabe an: Aufgabe 1 In welchem Jahr wurde die erste Programmierspache für Computer erfunden und wie hieß diese Sprache? Antwort: Die erste Programmiersprache der Welt f r C omputer wurde ebenfalls von Konrad Zuse entwickelt Er nannte sie den Planka lk l Wahrscheinlich geht es schneller, Sie suchen die Antwort im Internet, als dass Sie versuchen die Geheimschrift zu entschlüsseln (obwohl das sehr einfach geht..) Einen wirklich umfassenden Überblick über die Programmiersprachen kann man im Internet durchaus finden. Nur sehen die Bilder, wenn sie nur einigermaßen die Wirklichkeit widerspiegeln sollen, sehr viel komplizierter als mein nebenstehendes Bild aus. Dafür ist die Einteilung mit Sicherheit richtig,- leider ist es mir in dieser Klarheit nicht gelungen, wichtige Sprachen, wie PHP, C# und Perl unterzubringen. Außerdem wird es nach 1996 vollends kompliziert... Das nächste Bild ist aus dem Internet: 78 79 Obiges Bild ( http://goessner.net/learn/inp/2006/lec01/Stammbaum.jpg ) hingegen ist der Realität näher und immerhin ist die Zeit bis 2003 berücksichtigt. Aber seinen Sie ehrlich: Verstehen Sie das Bild vollständig? So komplex das obige Bild auch aussehen mag, es ist dennoch stark vereinfacht. Wer es genauer wissen will, der sieht sich das auf 11 DIN-A-4 Seiten ausgedruckte Diagramm an, das der Informtiklehrer zur allgemeinen Erbauung immer bei sich trägt...☺ Die bunt eingefärbten Kästchen zeigen die Programme, mit denen wir uns beschäftigen werden. Die Einteilung in verschiedene Gruppen ist im ersten Bild besser dargestellt. Hier können Sie auch gut erkennen, was in diesem Kapitel nicht behandlelt wird: • Maschinen- und Assemblersprachen (Kapitel 4) • SQL (deskriptive Sprache für Datenbanken: Kapitel 6) • Objektorientiertes Arbeiten (Kapitel 5) Man kann die Programmiersprachen nach verschiedenen Kriterien Klassifizieren: Klassifikation nach den Generationen Die frühen Programmiersprachen hat man in Generationen eingeteilt. Bei neueren Sprachen hat man diese Einteilung aufgegeben und ist zu einer Klassifikation nach den zugrundeliegenden Konzepten wie Objekt- Funktions- oder Logikorientierung übergegangen. 1. Generation: Maschinensprachen. 2. Generation: Assembler-Sprachen 3. Generation: Problemorientierte prozedurale (=imperative) Sprachen Beispiele: Cobol, Fortran, Pascal, Basic, C, Delphi 80 4. Generation: Deklarative Sprachen Beispiele: SQL 5. Generation: Künstliche Intelligenz Beispiele: Lisp, Prolog, Smalltalk, Haskell Klassifikation nach der Problembezogenheit Dieses Merkmal weist auf die Eignung der Programmiersprache für einen speziellen oder möglichst breiten Anwendungsbereich hin. Eine Klassifikation nach diesem Kriterium sieht so aus: spezielle Progammiersprachen mit den Ausrichtungsbeispielen als - kommerzielle Systeme: COBOL, 4GL1, - wissenschaftlich-technische Berechnungen: FORTRAN, C++, Delphi - Systemprogrammierung: Assembler, C, C++, - künstliche Intelligenz (KI): Lisp, Prolog, Icon, Scheme, Haskell - Publizieren: TeX, PostScript, Framemaker, HTML, XML, - Prozessbearbeitung: Unix-Shell, Tcl, Perl, - universelle Programmiersprachen: wie zum Beispiel PL/I, Ada und Java. Klassifikation nach den Programmierparadigma Einfach formuliert ist ein Paradigma eine Modellvorstellung der Wirklichkeit. Zumeist sind diese Paradigmen gänge Lehrmeinung, was dazu führt, dass ein Paradigmenwechsel, so sinnvoll und richtig er auch sein mag, nur sehr schwer in die Gänge kommt. Ein einfaches Beispiel: Solange das Pardigma bestand, dass die Erde eine Scheibe ist, konnte etwa die Seefahrt über einen bestimmten Entwicklungstand nicht hinaus kommen. Für mehr Erkenntnis war ein Paradigmenwechsel unverzichtbar. Auch Programmierer, die jahrelang nach dem Paradigma der „imperativen“ und „nicht objektorientierten“ Denkweise gearbeitet haben, tun sich furchtbar schwer, einen Paradigmenwechsel hin zum objektorientierten Paradigma durchzuhalten. Selbst nach Jahren fallen sie häufig auf ihre Dankweise zurück. Unter einem Programmierparadigma versteht man also ein bestimmtes Denkmuster beim Programmieren: Man hat eine bestimmte Vorstellungen davon wie etwas funktioniert bzw. funktionieren sollte. Die im folgenden aufgeführte Einteilung orientiert sich an diesem Ansatz der Klassifikation, berücksichtigt aber zusätzlich anwendungstechnische Gesichtspunkte. 81 Ohne Sie weiter zu verwirren, sollte man dennoch erwähnen, dass nicht alle Programmiersprachen eindeutig einer dieser Klassen zugeordnet werden können. So ist bspw. LOGO eine funktionale Programmiersprache, die aber auch imperative Sprachkonzepte besitzt. Java und C++ können als imperative objektorientierte Programmiersprachen klassifiziert werden, denn Java- und C++-Programme bestehen aus kommunizierenden Objekten, die intern mittels imperativer Sprachkonzepte realisiert werden. Wenn Sie zu diesem Thema im Internet recherchieren oder ein Fachbuch lesen, so werden Sie möglicherweise feststellen, dass dort der Ausdruck „imperativ“ nicht vorkommt. Statt dessen steht dort „prozedural“. Daher merken Sie sich: imperativ = prozedural Ebenso gilt: deskriptiv = deklarativ und Lambdakalkül-Sprachen = funktionale Sprachen. (Erklärung aller neuen Begriffe kommt etwas weiter unten) Wie wichtig ein Paradigmenwechsel sein kann, soll Ihnen folgendes AufgabenBeispiel zeigen: Aufgabe 2 Bei einem Dreieck kann man den Schwerpunkt konstruieren, indem man den Schnittpunkt der Seitenhalbierenden bestimmt. Bestimmen Sie in einem beliebigen 5-Eck den Schwerpunkt. Danach bestimmen Sie noch den Schwerpunkt in einem beliebigen 25-Eck!! 82 Was bedeuten all die neuen Vokabeln, wie imperativ, funktional, Assembler etc.? Das Alphabet der Maschinensprache besteht, wie in Kapitel 1 schon erwähnt, nur aus den Zeichen 1 und 0. Diese und nur diese Sprache kann der Computer direkt verarbeiten. Ein solcher 0-1 Code ist speziell auf die verwendete Hardware zugeschnitten. Für uns Menschen ist diese Sprache allerdings schon bei einfachsten Befehlen sehr schwer zu verstehen; wird der Ablauf der Befehle komplizierter, so wird ein Verständis des Sachverhalts nur durch Lesen der 1-en und 0-en schlicht unmöglich. So ist verständlich, dass ein Programm, das von Menschen direkt in Maschinensprache geschrieben ist, äußerst fehleranfällig ist. Zur Illustration hier ein Beispiel für die Maschinensprache geschrieben für den Befehlsvorrat eines Intel Pentium-Prozessors. Beispiel: Addieren der Zahlen 3 und 4: 1O11 OO11 OOOO OO11 ("Übertrage den Wert 3 in das Register BL") 1OOO OOOO 11OO OO11 OOOO 1OO ("Rechne den Wert 4 hinzu") Eine Stufe höher steht Assembler. Das ist eine maschinenorientierte Sprache der 2. Generation (nicht zu verwechseln mit dem Vorgang Assemblieren, dem Umwandeln in Maschinensprache), deren „Lesbarkeit“ jedoch noch sehr zu wünschen übrig lässt. Maschinenorientierte Programme bieten immer noch relativ wenig Komfort, gehen aber sehr effizient mit den Systemressourcen (Speicher und Prozessorleistung) um. Beispiel: Addieren der Zahlen 3 und 4: MOV ("Übertrage") BL, 3 ADD ("Addiere") BL, 4 Noch heute kommt der Programmierung in Assembler Bedeutung zu, wenn der von den Hochsprachen erzeugte Programmcode in bestimmten Teilen des Programms nicht die erforderliche Geschwindigkeit bringt. Bis in die 90-Jahre kam man um diese Art der Programmierung nicht herum, obwohl es schon sehr viele Hochsprachen gab. Das lag daran, dass die Rechner einfach zu langsam waren. Hätte man beispielsweise 1984 das Zeichnen eines Schaubildes in Basic programmiert, so wäre die Tinte des Plotterstiftes längst vor der Vollendung des Bildes eingetrocknet ☺ Wie schon weiter oben erwähnt, werden wir uns im Kapitel „Hardware und Betriebssysteme“ eingehender mit diesem Thema beschäftigen. Eine höhere Programmiersprache verwendet aus natürlichen Sprachen entlehnte Wörter und ist damit für den Menschen verständlicher. Sie ist von der speziellen Hardware weitgehend unabhängig. Derart geschriebene Programme müssen aber vor der Ausführung in Maschinensprache übersetzt (compiliert) oder während der Ausführung Zeile für Zeile in Maschinensprache interpretiert werden. (Sie erinnern sich: Der Prozessor versteht nur 0 un 1........) Einen Übersetzter, der ein Programm direkt ausführt, nennt man Interpreter, einen Übersetzer, der ein Programm in für die Ausführung geeignete Form umwandelt, nennt man Compiler. 83 Interpretation ist ein Einstufenprozess, in dem sowohl das Programm als auch die Eingabe an den Interpreter geliefert wird. Compilation hingegen ist mindestens ein Zweistufenprozess: Das ursprüngliche Programm (Quellprogramm) wird in den Compiler eingegeben, und der Compiler gibt ein neues Programm (Zielprogramm) aus. Dieses Zielprogramm kann erst ausgeführt werden, wenn es in einer für die direkte Ausführung geeignete Form( d.h. in Maschinensprache) vorliegt. Den vollständigen Compilationsprozess kann man vereinfacht so veranschaulichen: Man braucht nicht viel Phantasie, um zu erkennen, dass Programmiersprachen, die einen Compiler mitliefern, deutlich schneller sein dürften. Denn, wenn das Programm fertig ist, kann man es natürlich auch ganz in Maschinensprache umwandeln (assemblieren) und der zeitaufwendige Prozess der „Interpretation“ entfällt. Die höheren Programmiersprachen lassen sich in imperative (= prozedurale) und deklarative (= nicht-prozedurale) Sprachen einordnen: Imperative Programmiersprachen sind gekennzeichnet durch drei Eigenschaften: 1. Sequentielle Ausführung von Befehlen 2. Verwendung von Variablen, die Speicherwerte darstellen 3. Verwendung von Zuweisungen zu Ändern der Variablen-Inhalte. 84 Das Programm beschreibt den Lösungsweg eines Problems. Zu den prozeduralen Sprachen gehören zum Beispiel FORTRAN, PL/1, BASIC, PASCAL und PHP (3. Generation). Imperative Sprachen besitzen einen speziellen, der menschlichen Sprache angenäherten Befehlssatz, um Probleme aus einem bestimmten Anwendungsbereich zu lösen. Sie lehnen sich somit an die Denkweise des Programmierers an. Auch ohne fundamentierte Programmierkenntnisse lassen sich diese Programme leicht nachvollziehen. Die alternative Bezeichnung "prozedural" kennzeichnet den modularen Aufbau der entsprechenden Programme in Prozeduren oder Funktionen. Beispiel: (Pascal) Write('Fahrstrecke='); Readln(kilometer); Write('Benzin='); Readln(liter); verbrauch := liter/kilometer * 100; Writeln('Sie verbrauchten auf 100 km ',verbrauch); if verbrauch > 7 then writeln "Verbrauch zu hoch!"; Zu den nicht prozeduralen Sprachen gehören zum Beispiel: SQL, Haskell, Prolog, NATURAL und diverse Datenbanken. Die Definition des Begriffs „nicht prozedural“ ist fließend. Man stelle sich einfach vor, dass dem Rechner nicht mehr länger mitgeteilt werden muss, wie er das Problem zu lösen hat, sondern nur noch, was zu geschehen hat. Danach werden diese Angaben von dem Programmiersystem in ein Programm umgesetzt. Der Vorteil dieser Sprachen besteht darin, dass für diese Art der Programmierung keine umfangreiche Programmierausbildung notwendig ist. Nichtprozedurale Programmiersprachen werden z.B. für Datenbankabfragen oder Tabellenkalkulationen eingesetzt. Beispiel: select KUNDE from TABLE_1 where ALTER > 18 create ERWACHSENE Die von Delphi verwendete Programmiersprache Object-Pascal gehört zur 3. Generation, aber die visuellen und SQL-Komponenten gehören der 4. Generation an. Delphi ist daher, wie C# und Java eine hybride Programmiersprache. Delphi ist die „Leitsprache“ im Informatikunterricht der meisten Schulen. Wir machen da keine Ausnahme. Mit nicht weniger Berechtigung könnte man allerdings auch Visual C# oder Java verwenden. Sie können sich Ihr eigenes Urteil bilden, da wir weiter unten neben Delphi auch Visual C# und Java auf ein kleines Rechenproblem ansetzten werden. 85 deklarative Programmiersprachen (5. Generation) Wie auf den Bildern der Seiten 72 und 73 richtig dargestellt wird, muss man hier eigentlich zwei Untergruppen nennen: Die funktionalen und die logischen Programmiersprachen. Funktionale Programmiersprachen beruhen auf dem „Lambdakalkül“ der Funktionstheorie. Es wird dabei davon ausgegangen, dass mit drei Basisfunktionen (Verkettung, Iteration, Rekursion) alle anderen theoretisch möglichen Funktionen zusammengestellt werden können. Ein funktionales Programm entspricht im wesentlichen einer Funktion im mathematischen Sinne: also eine eindeutige Beziehung zwischen Definitionsbereich (Eingabe) und Wertebereich (Ausgabe). Eine Funktion wird auf die Eingabewerte angewendet und liefert den Funktionswert als Ausgabe. Der Rückgabewert hängt ausschließlich nur von den Eingabeparameter. (Erinnern Sie sich? Das war Klasse 7!) Aufgabe 3 Die oben genannten Grundbegriffe der funktionalen Programmierung Verkettung, Iteration und Rekursion sollten Ihnen aus der Mathematik bekannt sein. Damit Ihrem Gedächtnis auf die Sprünge geholfen wird, recherchieren Sie im Internet und fügen Sie Ihre Erkenntisse hier ein: In der Mathematik versteht man unter einer Variable etwas anderes als in der "gewöhnlicher" imperativen Programmierwelt. In den imperativen Sprachen sind die Variablen im Grunde genommen Namen für Speicherzellen und Speicherbereiche, deren Inhalt sich zu jeder Zeit ändern kann. In der Mathematik dagegen repräsentiert eine Variable einen konkreten und unveränderbaren (oft unbekannten) Wert, weswegen auch folgende Zuweisung keinen Sinn ergibt: x := x + 1 In der funktionalen Programmierung verzichtet man gerne auf den Begriff einer Variablen; es gibt nur Konstanten, Parameter und Werte. In der Praxis nennt man diese Sicht der funktionalen Programmierung rein funktionale Programmierung. Die meisten funktionalen Programmiersprachen halten aber an einer bestimmten Vorstellung von Variable und Zuweisung fest und sind daher "unrein". Dadurch, dass es keine Variablen und Zuweisungen in der funktionalen Programmierung gibt, kann es auch keine Schleifen geben, da eine Schleife eine Kontrollvariable haben muss, die einen neuen Wert zugewiesen bekommt, wenn die Schleife ausgeführt wird. Die sich wiederholende Operationen schreibt man in funktionaler Form mittels Rekursion, die eine entscheidende Rolle in der funktionalen Programmierung spielt. 86 Funktionale Programmierung besitzt eine Reihe besonderer Vorteile gegenüber der imperativen Programmierung. Diese machen sie vor allem im Bereich der künstlichen Intelligenz, für mathematische Beweissysteme und für Logikanwendungen populär. Zu den Vorteilen zählen die einheitliche Betrachtungsweise von Programmen als Funktionen, die Behandlung von Funktionen als Daten und die Verwendung automatischer Speicherverwaltung. Daher besitzt eine funktionale Programmiersprache hohe Flexibilität, Prägnanz in der Notation und eine einfache Semantik. In der Vergangenheit war der wichtigste Nachteil die Ineffizienz der Ausführung funktionalen Sprachen. Aufgrund ihrer dynamischen Natur wurden diese Sprachen früher eher interpretiert als compiliert, was sich, wie oben dargelegt, negativ auf die Ausführungsgeschwindigkeit auswirkte. Die bekannteste funktionale Programmiersprache ist sicherlich LISP. Heute wird jedoch eher HASKELL oder MONDRIAN verwendet. Logische Programmiersprachen erlauben eine Art der Programmierung, die es ermöglicht, die “Sprache” der Mathematik zur Entwicklung von Programmen zu benutzen. Die mathematische Logik verlangt eine präzise Formulierung von Aussagen, Wissen und Annahmen. Sie bildet die Grundlage für die formale Herleitung von Folgerungen, Wahrheits- und Gültigkeitsaussagen. Das Ziel logikorientierter Programmiersprachen besteht darin, die Problembeschreibung als Programm aufzufassen. Ein Logikprogramm besteht aus einer Menge von Axiomen, die eine reine Spezifikation von Wissen und Annahmen darstellen. Es enthält keinerlei Steuerungsanweisungen. Eine „Berechung“ ist ein konstruktiver Beweis einer Aussage aus den Axiomen des Programms. Logische Programmierung wird häufig auch mit dem aussagekräftigeren Begriff “wissensbasierte Programmierung” bezeichnet. Es wird versucht, auf der Basis möglichst genauen Wissens über einen spezifische Problembereich “angemessene” Schlüsse zu ziehen. Soll ein Problem gelöst werden, so wird dieses als Frage an eine Wissensbasis übergeben. Diese sucht durch Anwendung von Schlussfolgerungen eine Antwort auf die gestellte Frage. Wird eine solche gefunden, so ist auch eine Lösung erreicht. Kann jedoch eine Frage mit dem Inhalt der Wissensbasis nicht beantwortet werden, so gilt das Problem als “unlösbar” im Bezug zur verwendeten Wissensbasis und der Herleitungsstrategie von Schlussfolgerungen. Genau wie die funktionalen Programmiersprachen zählen die logischen zu der Klasse der deklarativen Sprachen. Die Programme aus dieser Klasse beschreiben nicht wie ein Problem zu lösen ist, sonder was das Problem eigentlich ist. Das "Wie" wird dem zugrunde liegenden System der Programmiersprache überlassen. Wegen 87 dieser "Intelligenz" werden solche Sprachen auch als 5.Generationsprachen bezeichnet. Die wichtigste und verbreitetste Programmiersprache dieser Art ist PROLOG. Mit ihr und mit Haskell werden wir uns in den nächsten Abschnitten noch beschäftigen. Aufgabe 4 Sie sollen hier kurze Beschreibungen bestimmer Programmiersprachen recherchieren und aufschreiben. Ein Beispiel: Java ist eine objektorientierte Programmiersprache und als solche ein eingetragenes Warenzeichen der Firma Sun Microsystems. Sie ist eine Komponente der Java-Technologie. Java-Programme werden in Bytecode übersetzt und dann in einer speziellen Umgebung ausgeführt, die als Java-Laufzeitumgebung oder Java-Plattform bezeichnet wird. Deren wichtigster Bestandteil ist die Java Virtual Machine (JavaVM), die die Programme ausführt, indem sie den Bytecode interpretiert. Java-Programme laufen in aller Regel ohne weitere Anpassungen auf verschiedenen Computern und Betriebssystemen, für die eine Java-VM existiert. Sun selbst bietet Java-VMs für die Betriebssysteme Linux, Solaris und Windows an. Andere Hersteller lassen ihre Java-VM für ihre Plattform zertifizieren, zum Beispiel die Firma Apple für Mac OS X. (Wikipedia) Javascript C++ Perl Phyton FORTRAN Eclipse 88 Vergleich Um wenigstens vier der sechs Programmiersprachen besser vergleichen zu können, werden wir in Java, PHP, Visual C# und Delphi je ein Programm schreiben, das eine quadratischen Gleichung lösen kann. Um dies an sich elementare Problem lösen zu können, müssen wir uns in allen vier Sprachen klären, wie man mit • Variablen • Ein-und Ausgabe • Arithmetrische Operationen • Verzweigung (if – else) umgeht. Und Sie werden erfreut feststellen, dass die Unterschiede minimal sind! Da das Problem „quadratische Gleichung lösen“ für Prolog und Haskell ungeeignet ist, müssen wir uns für diese Sprachen etwas anderes einfallen lassen. Sie kennen die „Mitternachtsformel“ zur Lösung einer quadratischen Gleichung der Form x2 + px + q = 0 hoffentlich noch! Aufgabe 5 Erstelle mit Structed ein Struktogramm. Versuche es zunächst selbst. Vergleiche danach mit der abgebildeten Lösung. Gibt es Unterschiede? 89