Programmiersprache
[[pl:J%EAzyk programowania]]
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 haben sich 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 (Objectcode, EXE-Datei) oder in einer Laufzeitumgebung (z.B. 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:
- Übernehme Daten von der Tastatur, von einer Datei oder sonstwoher.
- Ausgabe = output
- Gib Daten aus: auf dem Monitor, auf einem Drucker oder in eine Datei
- Mathematische Berechnung:
- Führe eine mathematische Berechnung durch wie Addition oder Multiplikation oder Ähnliches.
- Vergleich und Auswahl
- Überprüfe bestimmte Bedingungen und entscheide anhand des Ergebnisses, welche Befehle als nächstes ausgeführt werden.
- Wiederholung
- Führe eine Befehlsfolge wiederholt durch, 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
- Bedingte Verzweigung
- Abhängig von einer Bedingung wird ein anderer Programmfluß ausgewählt
- Schleifen
- Wiederholen von Programmteilen abhängig von Bedingungen
- Blockbildung
- Zusammenfassung mehrerer Befehle z.B. einer Schleife in einem Unterprogramm
- Umgang mit nicht mathematischen Elementen
- z.B. mit Text, Bildern, Sound...
- Kommentare
- Alle Programmiersprachen ermöglichen es Kommentare in den Programmtext einzufügen.
Jede Programmiersprache hält Vereinbarungen bzgl. 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. Hierbei kann zwischen typsicheren (z.B. C++ oder Java) und typenlosen Sprachen (z.B. JavaScript, Tcl oder Prolog)unterschieden werden. Bei typsicheren 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. 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.
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 (reserved 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 Pascal gezeigt.
Bezugnahmemechanismen und Wiederverwendung
Der Kern der Bezugnahme ist die Benennung von Speicherplatz als sog. 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 obengenannten 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 Backus-Naur Form angegeben, einer formalen Notation.
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 ab ca. 1940 die Entwicklung von Konrad Zuses Plankalkül, die Konzeption der Von-Neumann Maschine und die ersten Sprachen in Amerika: FORTRAN(1954, John Backus), COBOL (1959, Grace Hopper?), LISP (1959, McCarthy) und weitere (s.Tabelle).
Inzwischen ist eine riesige Zahl von Sprachen entstanden und es gibt einen evolutionären Prozess mit gegenseitiger Adaptierung. Eine wichtige Rolle spielen dabei auch die Standardisierungs-Organisationen (ISO). Die vorgenannten Sprachen existieren bis heute.
Kurze Zeittafel
- 1840~ --'Erstes Programm' (Ada Lovelace)
- 1947 -- Plankalkül (Konrad Zuse)
- 1954 -- FORTRAN (John Backus)
- 1959 -- LISP (McCarthy)
- 1959 -- COBOL (Grace Hopper)
- 1960 -- BASIC (Kemmeny, Kurtz)
- 1971 -- Pascal (Niklaus Wirth, Kathleen Jensen)
- 1972 -- C (Dennis Ritchie, Ken Thompson)
- 1975 -- Prolog (Colmerauer et. al.)
- 1980 -- Smalltalk
- 1980 -- Ada
- 1987 -- Perl (Larry Wall)
- 1988 -- Tcl (John Ousterhout)
- 1995 -- Delphi (auf Pascal basierende visuelle Entwicklungsumgebung, Borland)
- 1995 -- Programmiersprache Java (Sun Microsystems)
Siehe auch die ausführliche Zeittafel der Programmiersprachen.
Die Entwicklung hat dahin geführt, dass die Universalisten am weitesten verbreitet sind, d.h. diejenigen Sprachen (wie C, C++), die weitestgehend alle wichtigen Aspekte integriert haben. Hierzu gehören auch neuere Konzeptionen wie die der objektorientierten Programmierung, die Daten-, Prozedur- und Referenzaspekte in dem einzigen Konzept des Objekts vereinigt.
Aktuelle Entwicklungen
Neuere integrierte, visuelle Entwicklungsumgebungen haben deutliche Fortschritte gebracht, was Aufwand an Zeit, Kosten (und Nerven) angeht. Bedienoberflächen lassen sich meist interaktiv gestalten und Codefragmente sind per Klick direkt erreichbar.
Weitere Arbeitserleichterungen sind vorgefertigte Komponenten und Softwarebibliotheken mit wiederverwendbarem Code. Dazu kann objekt-orientierte Methodik auch die Komplexität von Programmen erheblich reduzieren. Diese Techniken markieren gleichzeitig den Übergang von einer eher 'handwerklichen' Kunst zu einem mehr industriell organisierten Prozess.
Besondere Ausprägungen
Maschinensprache
Maschinensprache ist der direkt auf einem Prozessor ausführbare Code und in diesem Sinne keine echte Programmiersprache. Sein Umfang ist architekturabhängig.
Assemblersprachen
Assemblersprachen gehören immer direkt zu ihrer entsprechenden Maschinensprache. Die Maschinenbefehle werden jedoch in einer lesbaren 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.
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.
Prolog orientiert sich in bezug auf Daten- und Evaluationsmechanismus an der Prädikatenlogik.
BASIC, C, COBOL, FORTRAN, Pascal, PL/1 sind Vertreter der prozeduralen Familie, in der Anweisungen hintereinander abgearbeitet werden.
Smalltalk, Eiffel, Modula-3, C++, Java, Delphi/ObjectPascal und Oberon sind objektorientierte Sprachen. Die Datenstrukturen befinden sich bei ihnen in Objektklassen, zu denen auch der jeweilige (auf die Datenstruktur zugreifende) Code (Methoden) gehört. Dadurch wird eine hohe Lokalität erreicht. Objektklassen lassen sich mittels Vererbung erweitern.
APL ?. LISP, ML, Scheme, Sather, Haskell
Bei regelbasierten Sprachen wie OPS-5 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.
Die Programmierung wird erleichtert, da zwischen
- Eigenschaften von Objekten ,
- der Lage von Objekten auf dem Bildschirm und
- dem eigentlichen Code
unterschieden wird. Beispiele: Visual Basic, Visual C++, Delphi (Sprache: Pascal), Kylix (Delphi/C++ für Linux), KDevelop (Sprache: C++)
Anwendungsbezogene Sprachen und Systeme
Datenbanksysteme: dBase, Paradox
Liste der Programmiersprachen
- ABAP
- Ada
- ALGOL (ALGOL-60, ALGOL-68)
- APL
- Assembler (Maschinensprache)
- awk (awk, gawk, mawk, nawk)
- B
- BASIC (True BASIC, VB (Visual Basic), VBA (VB for Applications), VBScript, ...)
- bash
- BCPL
- Brainfuck
- C (C, Visual C)
- C++ (C++, Visual C++)
- C#
- Clipper
- COBOL
- Delphi
- Eiffel
- FORTH
- FORTRAN
- Haskell
- Intercal
- Java (J, Visual J)
- JavaScript (JScript, ECMAScript, DHTML)
- Kylix
- lex (flex)
- LISP
- Logo
- Lua
- Lush
- Miranda
- ML
- Modula (Modula, Modula-2, Modula-3)
- Mumps
- Mycin (E-Mycin)
- Oberon
- Objective-C
- Pascal (Turbo Pascal)
- perl
- PHP
- Pike
- PL/I
- Prolog (Arity Prolog, Turbo Prolog)
- Pure Basic
- Python
- RPG
- Ruby
- Sail ("Stanford AI Language")
- Sather
- Scheme
- Self
- Shell (bash, csh)
- Simula
- SIRON
- Smalltalk
- SML
- SNOBOL4
- SQL
- Tcl
- yacc (Bison)
Alternativen
Programmiersprachen sind nicht die einzige Möglichkeit komplexe Abläufe für den Computer aufzubereiten. Andere Konzeptionen sind etwa Datenbanken und Tabellenkalkulation, oder im hardwarenahen Bereich speicherprogrammierbare Steuerungen.
Programmieren
Programmieren ist eine anspruchsvolle Tätigkeit und erfordert Disziplin, Ausdauer, abstraktes Denkvermögen, Kreativität und hohe Lernbereitschaft.
Unterschiedlichste Aufgaben müssen in die Symbole der Programmiersprache transferiert werden.
Das Programmieren als dieses reine Codieren ist nur ein Teil der Tätigkeit eines guten Programmierers, der zum gesamten Softwareentwicklungsprozess beitragen können sollte:
Analyse, Entwurf, Prototyping, Realisation, Testung, Einführung, Dokumentation, Konsolidierung.
Erheblichen Aufwand nimmt auch das sog. Debuggen ein d.h. die Fehlersuche.
Berufe: Softwareentwickler, Anwendungsentwickler, Systemprogrammierer, Organisationsprogrammmierer,..
siehe auch
Weblinks
- Virtual Museum of Computing (Linksammlung)
- Sammlung von 2350 Programmiersprachen
- Computer Languages History von Éric Lévénez