Alles über die programmiersprache
Alles über Programmiersprachen
Eine Programmiersprache ist eine formale Sprache zur Darstellung (Notation) von Computerprogrammen. Sie vermittelt dem Computersystem durch von einem Menschen geschriebenen Text genaue Angaben zu einer Kette von internen Verarbeitungsschritten, beteiligten Daten und deren Struktur in Abhängigkeit von internen oder externen Ereignissen.
Da digitale Computer intern nur die Werte 0 und 1 verarbeiten, wäre es nach heutigen Maßstäben extrem umständlich und mühsam, die vielen Formen der Informationsverarbeitung als Binärzahlen einzugeben (zu kodieren). Daher wurden in den letzten Jahrzehnten Verfahrensweisen etabliert, nach denen man häufig verwendete Zahlen und Zeichen und häufig verwendete grundlegende Operationen in symbolischen Befehlen angibt. Eine weitere technische Einrichtung übersetzt dann diese Angaben in interne Daten, einfachste Datenänderungsbefehle und Kontrollanweisungen, die der Computer dann schließlich ausführt.
Wird ein Programmtext als Ganzes übersetzt, spricht man in Bezug auf den Übersetzungsmechanismus von einem Compiler.
Der Compiler ist selbst ein Programm, welches als Dateneingabe den menschenlesbaren Programmtext bekommt und als Datenausgabe den Maschinencode liefert, der direkt vom Prozessor verstanden wird (zum Beispiel Objectcode, EXE-Datei) oder in einer Laufzeitumgebung (zum Beispiel JVM oder .NET) ausgeführt wird. Wird ein Programmtext hingegen Schritt für Schritt übersetzt und der jeweils übersetzte Schritt sofort ausgeführt, spricht man von einem Interpreter. Interpretierte Programme laufen meist langsamer als kompilierte.
Eine logische Abfolge von Befehlen in einer Programmiersprache nennt man allgemein Programm, Programmcode oder Quelltext. (Quelltext betont besonders die Lesbarkeit).
Dieser wird von Programmierern verfasst.
Elemente einer Programmiersprache
Die meisten Befehle einer Programmiersprache lassen sich auf 5 Hauptkategorien zurückführen:
Eingabe = input
Daten von der Tastatur, von einer Datei oder anderswo her übernehmen.
Ausgabe = output
Daten ausgeben: auf den Monitor, auf einen Drucker oder in eine Datei
Mathematische Berechnung
Eine mathematische Berechnung, wie Addition oder Multiplikation oder Ähnliches, durchführen.
Vergleich und Auswahl
Bestimmte Bedingungen überprüfen und anhand des Ergebnisses entscheiden, welche Befehle als nächstes ausgeführt werden.
Wiederholung
Eine Befehlsfolge wiederholt durchführen, meist mit einer gewissen Variation.
Eine andere Kategorisierung sieht wie folgt aus:
Arbeiten mit Variablen
Zuweisen, Auslesen und Ändern von Speicherinhalten
Elementare Mathematik
zumindest die vier Grundrechenarten
Kommentare
Die meisten Programmiersprachen ermöglichen es, Kommentare in den Programmtext einzufügen.
Jede Programmiersprache hält Vereinbarungen bezüglich Syntax, Vokabular und Bedeutung bereit für:
Daten und Datenstrukturen
Befehle und Befehlsgruppen
Bezugnahmemechanismen und Wiederverwendung
zumeist eine primäre Designphilosophie
Daten und Datenstrukturen
Um die üblichen Arten von Informationen im Computer abbilden zu können, müssen Möglichkeiten zur Definition von Daten oder Datenstrukturen bereitstehen, auch als Datentyp bezeichnet. Hierbei kann zwischen typisierten (zum Beispiel C++ oder Java) und typenlosen Sprachen (zum Beispiel JavaScript, Tcl oder Prolog) unterschieden werden. Bei typisierten Sprachen sind dies entweder vordefinierte Einheiten für einzelne Zahlen (Byte, Integer, Word, etc.) und Zeichen (Char) oder auch zusammengesetzte für Daten, Wörter, Text, sensorische Information und so weiter (Strukturen, Klassen). Zumeist besteht auch die Möglichkeit, zusammengesetzte Objekte oder Strukturen aufzubauen und als neuen Typ zu vereinbaren (etwa Arrays, Listen, Stacks, ganze Dateien). Die typenlosen Sprachen behandeln oftmals alle Einheiten als Zeichenketten und kennen für zusammengesetzte Daten eine allgemeine Liste (zum Beispiel Perl).
Bei den typisierten Sprachen gibt es solche mit Typprüfungen zur Übersetzungszeit (statisch typisiert) und solche in denen Typprüfungen primär zur Laufzeit stattfinden (dynamisch typisiert, etwa Ruby, Smalltalk). Werden Typfehler spätestens zur Laufzeit erkannt, spricht man von typsicheren Sprachen. Oft wird fälschlicherweise die statische Typprüfung wegen des angenommenen qualitativen Vorteils gegenüber der dynamischen Typprüfung als "sicher" bezeichnet.
Es kann keine allgemeine Aussage über die Tauglichkeit beider Formen der Typprüfung getroffen werden - bei statischer Typprüfung ist der Programmierer versucht, diese zu umgehen, beziehungsweise sie wird erst gar nicht vollständig durchgesetzt (zum jetzigen Stand der Technik muss es in jeder statischen Sprache eine Möglichkeit geben, "Typlose" Daten zu erzeugen oder zwischen Typen zu wechseln - etwa wenn Daten vom Massenspeicher gelesen werden), in Sprachen mit dynamischer Typprüfung werden manche Typfehler erst gefunden, wenn es zu spät ist. Bei dynamischer Typprüfung wird jedoch der Programmcode meist sehr viel einfacher.
Oft kann an den "Bürgern erster Klasse" ("First class Citizens" - FCCs) einer Programmiersprache - also den Formen von Daten, die direkt verwendet werden können, erkannt werden, welchem Paradigma die Sprache gehorcht.
In Java (Objektorientiert)zum Beispiel sind Objekte FCCs, in LISP (Funktional) ist jedes Stück Programm FCC, in Perl sind es Zeichenketten, Arrays und Hashes.
Befehle und Befehlsstrukturen
Konzeptionell ist ein programmierbarer Rechner weit mehr als eine Sammlung von Daten und auch keine starre Rechenmaschine. Vielmehr wird angegeben, wie der Computer mit variablen internen oder externen Daten zu verfahren hat. Elementare Anweisungen geben über Schlüsselwörter (key words) an, WANN WAS WIE geändert werden soll. Jede Sprache enthält eine WENN-DANN-artige Anweisung, die letztlich zusammen mit dem Sprungbefehl (Goto) die Universalität bereitstellt, um allgemein auf vielfältigste Fälle reagierende Programme schreiben zu können. Falls Konstrukte für Schleifen mit Bedingungen (Bedingung zuerst, dann Anweisungsgruppe, oder: erst Anweisungsgruppe und dann Bedingung) zur Verfügung stehen, kann auf den Sprungbefehl vollständig verzichtet werden.
Niklaus Wirth hat dies mit Modula-2 gezeigt.
Bezugnahmemechanismen und Wiederverwendung
Der Kern der Bezugnahme ist die Benennung von Speicherplatz als so genannte Variable. Weitere Bezugnahmen sind Zeiger auf solche Variablen oder Variablengruppen. Auch Befehlsgruppen werden im Programm per Namensaufruf als Prozedur oder Funktionsaufruf verfügbar gemacht. Auf diese Weise wird durch Symbole einerseits eine große Variabilität erreicht und durch Referenz auf vorhandene Programm- oder Datenteile andererseits ein hohes Maß an Wiederverwendbarkeit erreicht. Viele anwendungsbezogene Sprachen integrieren typische Aufgaben als aufrufbare Befehle.
Entwurfsphilosophie
Für die oben genannten Zwecke hat jede Sprache meist eine besondere Philosophie entwickelt. Es wird der eine oder andere Aspekt besonders betont. Mehr Datenstrukturen oder Freiheit in der Notation oder Raffinesse, was Zeigerstrukturen angeht.
Die meisten Sprachen bieten eine gute Funktionalität, fordern aber auch ein hohes Maß an Disziplin bezüglich Fehlerfreiheit. Programmiersprachen sind nicht fehlertolerant, was durch Hilfen aber abgemildert ist. Einige wenige Sprachen bieten große gestalterische Freiheiten bis hin zum sich selbst verändernden Programm: dazu gehört Maschinensprache und auch LISP.
Die Entwicklung von Programmiersprachen selbst ist eine Aufgabe der Informatik. Die syntaktische Definition einer Sprache wird meist in der formalen Notation Backus-Naur-Form sowie Kontextbedingungen angegeben. Eine vollständige Spezifikation einer Programmiersprache in einem einzigen Kalkül ist Forschungsgebiet und erst ansatzweise gelungen.
Besondere Ausprägungen
Im Folgenden werden diverse Klassen von Programmiersprachen, unterteilt nach Anwendungsbereich oder zugrundeliegendem Paradigma, vorgestellt.
Maschinensprache
Maschinensprache ist der direkt auf einem Prozessor ausführbare Code und in diesem Sinne keine Programmiersprache. Jede Prozessorarchitektur hat eine eigene, unterschiedliche Maschinensprache.
Assemblersprachen
Assemblersprachen gehören immer direkt zu ihrer entsprechenden Maschinensprache. Die Maschinenbefehle werden jedoch in einer menschenlesbaren Form geschrieben. Weiter wird mittels Symbolen adressiert, die absoluten Adressen werden vom Assembler errechnet. Auch können symbolische Konstanten benutzt und Makros, die häufig wiederkehrende Befehlsfolgen repräsentieren, definiert werden.
Datenstrukturen
LISP verwendet als konzeptionelle Hauptstruktur Listen. Auch das Programm ist eine Liste von Befehlen, die andere Listen verändern.
FORTH verwendet als konzeptionelle Hauptstruktur Stacks und Stackoperationen.
Logische Sprachen
Prolog orientiert sich in der Beschreibung der Programme an der Prädikatenlogik. Logikorientierte Programmiersprachen haben ungewöhnliche Eigenschaften (Backtracking, Unifikationsalgorithmen), die sie für gewisse Arten von Problemen vorherbestimmt, die mit anderen Programmiersprachen nur sehr schwer zu lösen sind.
Prozedurale Sprachen
AWK, BASIC, C, COBOL, FORTRAN, Pascal, PL/1, REXX sind Vertreter der prozeduralen Familie, in der Anweisungen hintereinander abgearbeitet werden.
Objektorientierte Sprachen
Smalltalk, Eiffel, Modula-3, C++, Objective-C, D, Java, C#, ObjectPascal, Oberon, Ruby und XBase++ sind objektorientierte Sprachen. In objektorientierten Programmiersprachen werden Datenstrukturen und Methoden, die auf diesen Datenstrukturen operieren, in Klassen gekapselt.
Funktionale Sprachen
LISP (Hybridsprache), Logo, ML, Scheme, Haskell
Regelbasierte Sprachen
Bei regelbasierten Sprachen wie OPS-5 oder Prolog werden Regeln gegen eine Datenmenge auf ihre Instanziierbarkeit geprüft. Aus allen Regelinstanziierungen wird eine (mehrere, alle) ausgewählt und die zur Regel gehörenden Anweisungen werden ausgeführt.
Geschichte
Anfänge
Erste Arbeiten stammen bereits von Lady Ada, Countess of Lovelace (1815-1852, Assistentin von Charles Babbage), die als erste das Prinzip der variablen Programmierbarkeit erkannte. Dies entwickelte sich erst spürbar weiter mit Entwicklung der ersten elektronischen Rechenmaschinen und der Verwendung der booleschen Algebra.
Meilensteine sind etwa 1937 Patente von Konrad Zuse, die die Architektur beschreiben, die später als Von-Neumann-Maschine bekannt wird sowie 1945 die Fertigstellung von Plankalkül durch Zuse. Die ersten praktisch eingesetzten Programmiersprachen sind FORTRAN (1954, John Backus), COBOL (1959, Grace Hopper), LISP (1959, McCarthy), ALGOL-60 (1960, Strukturierte Programmierung)) und weitere (siehe Tabelle).
Darauf aufbauend wurde eine riesige Zahl von Progammiersprachen entwickelt, von denen aber die meisten nur Nischenprodukte sind. Es gibt gewissermaßen Sprachfamilien, z.B. C-artige Sprachen, die letztlich auf Algol zurückgehen. In neueren Generationen von spezifischen Sprachen werden erfolgreiche neue Konzepte von anderen Sprachen eingebaut. Die aktuelle Fortran-Vairante ist im Vergleichz zur Urvariante stark gewandelt.
Eine wichtige Rolle spielen dabei auch die Standardisierungs-Organisationen (ISO). Die vorgenannten Sprachen existieren bis heute.
Programmiersprachen werden geschichtlich auch in verschiedene Generationen eingeteilt:
1. Generation: Maschinensprachen Befehle werden direkt in einer Maschinensprache notiert, das heißt als Folge von Zahlencodes. Da sich der Befehlssatz von Rechner mit unterschiedlichen Prozessoren im allgemeinen unterscheidet, sind in Maschinensprache geschriebene Programme nur sehr schwer übertragbar. Die direkte Programmierung in einer Maschinensprache wird heute kaum noch verwendet.
Einige Programmiersysteme für höhere Programmiersprachen gestatten es, Maschinenbefehle in den Quelltext zu integrieren. Die Anwendung beschränkt sich dann auf solche Fälle, in denen es aus funktionalen oder Effektivitätsgründen unumgänglich oder nützlich ist, maschinennah zu programmieren.
2. Generation: Assembler Anstelle von Zahlencodes wird mit Hilfe von symbolischen Bezeichnern (Mnemonic) codiert. Eine Assembleranweisung wird in genau einen Maschinenbefehl umgesetzt. Auch Assemblerprogramme sind deshalb im allgemeinen an einen bestimmten Prozessortyp gebunden.
Makroassembler gestatten die Bildung von parametrisierbaren Befehlsgruppen. Eine Makroanweisung wird im allgemeinen in mehr als einen Maschinenbefehl umgesetzt.
Der Anteil der Assemblerprogrammierung ist im Sinken. Der Möglichkeit der Erstellung effektiver Programme steht die erschwerte Wartbarkeit von Assemblerprogrammen gegenüber. Maschinennahe Programmierung - die Domäne von Assembler - kann heute überwiegend durch höhere Programmiersprachen abgedeckt werden.
Einige Programmiersysteme für höhere Programmiersprachen gestatten es, Assemblerbefehle in den Quelltext zu integrieren.
Die Anwendung kann sich dann auf die Situationen beschränken, in denen es aus funktionalen oder Effektivitätsgründen notwendig oder nützlich ist, maschinennah zu programmieren.
3. Generation: höhere Programmiersprachen (high level language) Sprachen der 3. Generation unterstützen unmittelbar die Notation von Algorithmen, sie sind weitgehend anwendungsneutral und maschinenunabhängig.
Erste höhere Programmiersprachen entstanden ab Mitte der fünfziger Jahre (FORTRAN, COBOL, ALGOL-60). Weitere Sprachen dieser Generation sind zum Beispiel PASCAL, MODULA-2, PL1, C, ADA, BASIC, SIMULA.
4. Generation: Fourth Generation Language (4GL) Sprachen der 4. Generation sind anwendungsbezogen (applikative Sprachen). Sie stellen i.a. die wichtigsten Gestaltungsmittel von Sprachen der 3.
Generation zur Verfügung, zusätzlich jedoch Sprachmittel zur Auslösung von relativ komplexen, anwendungsbezogenen Operationen, beispielsweise zum Zugriff auf Datenbanken und zur Gestaltung von Benutzeroberflächen (SQL).
5. Generation: (Very High Level Language, VHLL) Sprachen der 5.Generation gestatten das Beschreiben von Sachverhalten und Problemen. Sie kommen vor allem im Bereich der KI (künstliche Intelligenz) zum Einsatz. Die Wahl des Problemlösungsweges kann (entsprechend dem Sprachkonzept) dem jeweiligen System (weitgehend) überlassen werden.
Bekanntestes Beispiel für eine Sprache der 5. Generation ist PROLOG.
00-Generation: Objektorientierte Programmiersprachen Objektorientierte Programmiersprachen passen nicht in das bisherige Generationen-Modell. Sie werden daher in der Literatur oft als "00-Generation" bezeichnet.
Liste der Programmiersprachen
A++ ; ABAP ; Ada ; ALGOL (ALGOL 60, ALGOL 68) ; APL ; AppleScript ; ARS++ ; Assemblersprache ; Autocoder ; awk (awk, gawk, mawk, nawk) ; B ; BASIC ; bash ; BCPL ; BeanShell ; Befunge ; Brainfuck ; C ; C++ ; C# ; Clarion ; Clipper ; COBOL ; Comal ; Delphi; EASY ; Eiffel ; ELAN ; FORTH ; FORTRAN ; Gambas ; Groovy ; Haskell ; Intercal ; Io ; Java ; JavaScript (JScript, ECMAScript, DHTML) ; Jython (JPython) ; Kylix ; LabVIEW ; lex (flex) ; LISP ; Logo ; Lua ; Lush ; Miranda ; ML ; Modula (Modula, Modula 2, Modula 3) ; Mumps ; Mycin (E-Mycin) ; Oberon ; Object REXX ; Objective-C ; Occam ; OPL ; Pascal (Turbo Pascal) ; Perl ; PHP ; Pike ; PILOT ; PL/1 ; PL/SQL ; Plankalkül (Konrad Zuse um 1945) ; Proges (Andy Schürr) ; Prolog (Arity Prolog, Turbo Prolog) ; Pure Basic ; Pure data ; Python ; REXX ; RPG ; Ruby ; Sail ("Stanford AI Language") ; Sather ; Scheme ; SDL (Specification and Description Language) ; Self ; Sevag (Siemens Eingabe-,Verarbeitungs-,Ausgabegenerator) ; Shell (sh, ksh, bash, csh) ; Simula ; SIRON ; Smalltalk ; SML ; SNOBOLA ; SQL ; Tcl ; VHDL ; Visual Basic (VBA (VB for Applications), VBScript, ..
.) ; Xbase ; yacc (Bison) ; Zer0 Tolerance
Anmerkungen: |
| impressum | datenschutz
© Copyright Artikelpedia.com