Lehrstuhl für Medieninformatik Universität Siegen Fakultät IV 5 Einführung in Programmiersprachen Version: WS 14/15 Fachgruppe Medieninformatik 5.1
5 Einführung in Programmiersprachen... Motivation: Ziele dieses Abschnittes Unterschiedliche Typen von Programmiersprachen: imperativ-prozedurale Programmiersprachen objekt-orientierte Programmiersprachen deklarative Programmiersprachen Überblick über Programmierumgebungen Literatur: Begrifferklärungen in [Claus], sowie [Ernst] Teile des Kap. 7 [Gumm] Teile des Abschnitts 2.1 [Herold] Abschnitt 7.2 und 7.3 Watt, D.A.: Programmiersprachen - Konzepte und Paradigmen, Hanser, 1996 Fachgruppe Medieninformatik 5.2
5.1 Begriffe Programm: Realisierung eines Algorithmus wird automatisch von einem Prozessor (CPU) ausgeführt konkreter und detaillierter als ein in Worten formulierter Algorithmus genügt einer Syntax, also den Regeln einer (formalen) Programmiersprache Programmieren: Erstellung eines Programms 3 Ebenen: Maschinensprache: Formulierung eines Maschinenprogramms als Folge von elementaren Befehlen (Binär-Code) Lowlevel-Programmiersprachen: Maschinennahe Befehle, hardwareorientiert Beispiel: Verschiedene Varianten von Assembler-Sprachen Highlevel-Programmiersprachen: Komplexe Befehle, problem-orientiert, Abstraktion/Unabhängigkeit von Hardware-Merkmalen Highlevel-Programme werden in Maschinensprache übersetzt von einem Compiler oder Interpreter Fachgruppe Medieninformatik 5.3
5.2 Anwendungsgebiete Anforderungen an eine Programmiersprache: Es sollte leicht sein, einen Compiler zu schreiben. Die Syntax sollte vom Parser (erster Stufe des Compilers) leicht zu lesen sein. historische Entwicklung von sehr einfachen zu immer leistungsfähigeren Sprachen Die Programmiersprache sollte effizienten (schnellen) Maschinencode erzeugen. Darauf muss der Programmierer gegebenenfalls Einfluss haben. Struktur des zu lösenden Problems sollte in die Programmiersprache gut abbildbar sein. Daher haben sich je nach Anwendungsgebiet verschiedene Sprachen durchgesetzt. Der Prozess der Softwareentwicklung sollte möglichst gut unterstützt werden. Mechanismen, um Fehler nicht erst aufkommen zu lassen Gute Strukturierung großer Softwareprojekte Schnittstellen zwischen Teilen, vor allem wenn viele Entwickler(-Firmen) beteiligt sind. Fachgruppe Medieninformatik 5.4
5.2 Anwendungsgebiete Unterschiedliche Anwendungsgebiete führen zu unterschiedlichen Sprachen, z.b.: Büro-Anwendungen (C++, C#,...) Web-Anwendungen (Java, Perl, PHP, Python,...) Wissenschaftlich- technische Anwendungen (C,C++, Fortran,...) Datenbank-Anwendungen (PHP, SQL,...) Graphik-Anwendungen (C++, Assembler, Nvidia Cg,...) Server-Anwendungen/Unternehmenssoftware (C/C++,...) Eingebettete Systeme (VHDL,...) Kaufmännische Systeme (Cobol,...) Visuelle Sprachen (Diagrammsprachen) als Hilfsmittel für den Design- Prozess unter Nutzung graphischer Symbole UML (Unified Modeling Language) UML-Tools zur Code-Generierung Fachgruppe Medieninformatik 5.5
5.3 Zeitliche Entwicklung prozedural deklarativ 1950 imperativ objektorientiert funktional logisch Fortran Lisp 1960 Cobol algol 60 Basic PL/1 Algol 68 Simula 1970 1980 Pascal Ada C Smalltalk ML Prolog C++ Miranda 1990 Eiffel Haskell Java 2000 C# Fachgruppe Medieninformatik 5.6
5.4 Typen von Programmiersprachen Man unterscheidet ganz grundlegend deklarative und prozedurale (bzw imperative) Sprachen. (Terminologie ist hier uneinheitlich). Prozedurale Sprachen: Programm besteht aus einer Folge von Befehlen. Programm gliedert sich in einzelne Prozeduren Weitere Unterscheidung imperativ: Programmablauf durch Abfolge der Programmzeilen und Verzweigungen vorgegeben objektorientiert: Programmablauf durch Signalaustausch zwischen Objekten bestimmt. Deklarative Sprachen: Programm ist eine Beschreibung des Problems. Compiler entwickelt daraus einen Programmablauf auf Maschinenebene. Bemerkung: Trotz dieses syntaktisch ganz anderen Konzepts ist die Programmierung nicht so verschieden, wie es scheint: Es ist nicht so, dass der Compiler das Problem für uns löst. Es handelt sich nur um eine andere Art, den Algorithmus aufzuschreiben. Fachgruppe Medieninformatik 5.7
5.4 Typen von Programmiersprachen Imperativ/Prozedural (z.b. Pascal, C, Basic): Hauptgesichtspunkt: Umsetzung von Algorithmen bzw. Berechnungsvorschriften Kontrollfluss wird durch das Programm gesteuert Sprachelemente: Variablen (hier x, y): Platzhalter für konkrete Werte/Zahlen Zuweisung a:=b Konkrete Werte werden Variablen zugewiesen arithmetische Operatoren Funktionen bzw. Prozeduren, hier: dosomething, writeln Kontrollstrukturen Fachgruppe Medieninformatik 5.8
5.4 Typen von Programmiersprachen Erste Imperative Programmiersprachen (Fortran, Basic): Struktur der Sprache eng an Maschinensprache angelehnt, Befehle sind aber komplexer als in Assembler, deshalb handelt es sich um Hochsprachen. Elementare Befehle sind Zuweisungen: a =b Weist der Variablen a den Wert von b zu. Arithmetische Ausdrücke: c=sqrt(a^2+ b^2) Weist den Wert einer Quadratwurzelberechnung (square root) zu. Sprungbefehle der Programmkontrolle: goto 100 Programmkontrolle springt in Programmzeile 100. Bedingte Verzweigungen: if a<b then 100 springt in Programmzeile 100, falls a<b. Schleifenbefehle do oder for - next (siehe Beispiel auf folgender Seite) Eingabe und Ausgabe: print a Sprünge in Prozeduren (Unterprogramme): Inhaltliche Gruppierung mehrfach aufgerufener Programmteile gosub 200 return Im Unterschied zu einfachen Sprüngen merkt sich die Programmkontrolle, von welchem gosub in die Prozedur gesprungen wurde, und kehrt nach return dorthin zurück. Fachgruppe Medieninformatik 5.9
5.4 Typen von Programmiersprachen Imperative Programmiersprachen (Fortran, Basic): Basic-Beispielprogramm, zwei Varianten mit gleichem Ergebnis. ( Die Programmzeilen-Nummern (100, 200, ) sind Teil des Programmtextes und werden vom Programmierer eingegeben. 100er Schritte, um später noch Zeilen einfügen zu können.) 100 k=0 200 k=k+1 300 print sqrt(k) 400 if k<100 then 200 = 100 for k=1 to 100 200 gosub 1000 300 next k 1000 print sqrt(k) 1010 return Fachgruppe Medieninformatik 5.10
5.4 Typen von Programmiersprachen Strukturiertes Programmieren Problem: E. W. Dijkstra, 1968: Aufsatz Go To Statement Considered Harmful Gefahr von Fehlern beim Programmieren von Spaghetticode in Fortran, Basic, Z.B. Sprünge aus Schleifen oder aus Prozeduren heraus. Wurde zum Problem, als Programme immer umfangreicher wurden. Deshalb: 1. goto Befehl soll nicht verwendet werden 1. Statt dessen Blockstruktur des Programms Schleifen If-then-else for k:=1 to 3 do begin Befehl 1 Befehl 2 end; if k<10 then begin end else begin end; 3. Prozeduren dürfen nur an ihrem Ende verlassen werden. Fachgruppe Medieninformatik 5.11
5.4 Typen von Programmiersprachen Imperativ/Prozedurale strukturierte Programmierung (Pascal, Modula, C): Auszug aus einem Pascal-Programm: procedure writesum(x,y: integer); var z: integer; begin z=x+y; writeln(z); (= write line ) end; Weitere Beispiele siehe vorige Folie: for-schleife, if-then-else mit begin-end. Keine Verwendung von goto Strukturierte Programmierung mit Befehlsblöcken zwischen begin - end. Modularisierung: Programmierer definiert viele Prozeduren und Funktionen (Funktionen sind Prozeduren, die einen Wert an das Hauptprogramm zurückgeben. Bsp: sinus-funktion ). Lokale Variablen in Prozeduren, die nur dort definiert sind, verhindern Verwechslungen. Zeiger auf Variablen (in C sind das ganz direkt die Adressen der Daten im Speicher) erlauben dynamische Datenstrukturen Programmierer kann Variablen zu neuen Datentypen (record, struct) zusammenfassen. Beispiel in Pascal: type 3d_vector = record x,y,z: real; (real = Gleitkommazahlen) end; Pascal: Elegant, sehr präzise Definition von Variablentypen, v.a. in der Lehre verwendet C: Maschinennäher, dadurch sehr effizienter Code. Fachgruppe Medieninformatik 5.12
5.4 Typen von Programmiersprachen. Objektorientierte Programmierung: Probleme: In großen Softwareprojekten gibt es hunderte von Prozeduren und Funktionen. Es werden klare Schnittstellen zur Arbeitsteilung der Programmentwicklung benötigt Deshalb: Programm fasst Variablen zu Einheiten zusammen. Dies sind die Objekte. (Weiterentwicklung der Idee von struct-datentypen) Ein Typ von Objekten (z.b. Vektoren) heißt Klasse. Für jede Klasse werden spezifische Funktionen (Methoden) definiert. Es gibt abstrakte Operationen auf verallgemeinerten Klassen Diese werden für jede konkrete Klasse getrennt definiert Hierarchie von voneinander abgeleiteten Klassen mit Vererbung von Methoden Lokale Variablen innerhalb der Objekte sind gegebenenfalls von außen im Programm nicht zugänglich. Jeder Programmentwickler arbeitet an seinen Objekten, und diese können auf vordefinierte Weise interagieren. Fachgruppe Medieninformatik 5.13
5.4 Typen von Programmiersprachen. Objektorientierte Sprachen (C++, Java): Auszug aus einem C++-Programm: class Vector3D { float x, y, z; float norm();... } Bemerkung: { } entspricht begin-end main() { Vector3D u, v, w; v.x = 1; v.y = 0; v.z = 0; w.x = 0; w.y = 1; w.z = 0; u = v + w; if (u.norm() == 0) printf( Laenge 0 ); } Sprachelemente: Zusätzlich zu denen imperativer Sprachen: Klassen (hier: Vector3D) Objekte (hier: u,v,w): Entsprechen Variablen für einfache Typen Definition eigener Operatoren, hier: norm(), + Fokussierung auf grundlegende Konzepte der Software-Entwicklung: Modularisierung, Erweiterbarkeit, Wartbarkeit, Portabilität Programmierung der Objekte (Klassen und deren Methoden) tritt in den Vordergrund, Programmierung des Befehlsablaufes in den Hintergrund. Befehlsablauf oft nur durch Signale gesteuert, die die Objekte austauschen. Fachgruppe Medieninformatik 5.14
5.4 Typen von Programmiersprachen. Funktional (z.b. LISP, SML, Haskell): Auszug aus einem LISP- bzw. Scheme-Programm: (define (fakultaet n) (if (= n 0) 1 (* n (fakultaet(- n 1))))) Hauptgesichtspunkt: Definition von mathematischen Funktionen Ausführungsreihenfolge wird durch Abhängigkeit von Funktionen, insbesondere die Reihenfolge der Auswertung in den arithmetischen Ausdrücken, implizit festgelegt: Sprachelemente: Funktionen, hier fakultaet (Genauere Erklärung des Berechnungsverfahrens folgen später.) arithmetische Operationen, hier: - n 1 (Ergebnis: n 1). Dabei Präfix-Notation (Operator Operand1 Operand2). Kontrollstrukturen, hier: if-bedingung (bedingte Ausführung) keine sequentiellen Kontrollstrukturen Hinweis: Hier gibt es keine Variablen, Schleifen und Zuweisungen im imperativen Sinn Fachgruppe Medieninformatik 5.15
5.4 Typen von Programmiersprachen. Logisch/Prädikativ (z.b. Prolog): Auszug aus einem Prolog-Programm: umkreist(erde, sonne). (Faktum) umkreist(mars, sonne). planet(b) :- umkreist(b, sonne). (Regel) satellit(b) :- umkreist(b, P), planet(p).?- umkreist(erde, sonne). (Anfrage) Hauptgesichtspunkte: Prädikate, Regeln, Termersetzung Umsetzung der prädikatenlogischen Denkweise Sprachelemente: Fakten, Regeln, Anfragen Motivation: Künstliche Intelligenz durch formales Schließen Eigentliche algorithmische Struktur ist im Compiler Fachgruppe Medieninformatik 5.16
5.5 Programmierumgebung Compiler Sprachen: Benutzer tippt Programm ein Editor Quelltext mit Makros Präprozessor Lexikalische Analyse Syntaktische Analyse Semantische Analyse Code-Erzeugung Code-Optimierung Quellmodul Compiler Binärer Modul-Code Linker Fehlermeldungen Maschinen-Code Maschine Eingabe Debugger-Eingabe Debugger-Ausgabe Die Analyse-Stufen prüfen die Korrektheit des Programmcodes anhand der Sprachdefinition (s. Kap. 7 Formale Sprachen) Das ausführbare Programm (Maschinencode) kann aus mehreren binären Modulen bestehen (s. Absch. 6.16) Fachgruppe Medieninformatik 5.17
5.5 Programmierumgebung Editor: Ein Programm, in dem der Programmierende den Programmtext eingeben und bearbeiten kann. Das Ergebnis ist der Quell-Code im ASCII-Format (eine einfache Buchstabenfolge). Präprozessor bearbeitet automatisch den Quelltext: Einfügen von vordefinierten Quelltextblöcken (Headerdateien, Makros), Ersetzung von Namen durch andere. Ergebnis ist immer noch direkt lesbarer Code, nur länger und unübersichtlicher. Compiler: Scanner: Ersetzung der Operatoren, Namen, Schlüsselworte durch Zwischencode. Parser: Syntaktische Analyse, z.b. Klammerregeln in arithmetischen Ausdrücken. Code-Generator: Semantische Analyse und eigentliche Übersetzung in Assembler. Code-Optimierung zur Beschleunigung des Programms: Verwendung von Registern, Reihenfolge von Speicherzugriffen, Linker: Zusammenfügen des Maschinencodes mit anderen (eigenen oder vordefinierten) Code- Bestandteilen, z.b. Bibliotheken von mathematischen Funktionen. Assemblierer übersetzt den Assembler-Code schliesslich in ausführbare Maschinensprache. Fachgruppe Medieninformatik 5.18
5.5 Programmierumgebung Interpretierte Sprachen: Assembler Sprachen: Editor Editor Quelltext Interpreter Quelltext Assembler Maschinenbefehl Maschine Eingabe Debugger-Eingabe Fehlermeldungen Maschinen-Code Maschine Interpreter: Durchläuft den Quell-Code, übersetzt jeden Befehl in Maschinenbefehl(e) und führt diese direkt aus Beispiele: BASIC, Skriptsprachen (z.b. Perl, PHP, Python etc.) Assembler: Übersetzt eine Folge von Assembler-Befehlen in Maschinen- Code Assembler-Code: Lesbare Darstellung von Maschinencode Fachgruppe Medieninformatik 5.19
5.6 Zusammenfassung Wichtige Erkenntnisse und Inhalte dieses Abschnitts: Historie der Programmiersprachen Gliederung der Programmiersprachen höhere Programmiersprachen niedere Programmiersprachen Typen von Programmiersprachen Imperativ/Prozedural: Direkte Angabe von Berechnungsabläufen Objekt-Orientiert: Abstraktere Sicht auf anwendungsspezifische Daten Funktional: Mathematisch-funktional Logisch: Programmierung mittels Fakten und Regeln Fachgruppe Medieninformatik 5.20