Wie Computer Befehle abarbeiten, haben wir im letzten Teil der “Wie Rechner rechnen”-Serie gesehen – Grundlage hierfür waren die Instruktionen, Bitketten, welche die durchzuführende Aufgabe codieren. Da das Programmieren mit Bitketten allerdings nicht sonderlich komfortabel war, wurden die Assemblersprachen eingeführt, die mit sogenannten Mnemonics, kurzen Wörtchen, die Programmierarbeit vereinfachen. Damit konnte man schon ganz vernünftig programmieren, aber etwas umständlich war es immer noch; vor allem mit größer werdenden Programmen ging mit Assembler die Übersicht schnell verloren. Der Weisheit letzter Schluss war Assembler also auch nicht; im Laufe der Jahre wurden daher die verschiedensten höheren Programmiersprachen entwickelt, die das Problem der Übersichtlichkeit lösen sollten. Ich möchte hier keinen geschichtlichen Abriss darüber geben, welche Sprache wann entstanden ist – wen das interessiert, der möge sich selber darüber informieren. Vielmehr soll es in diesem Artikel darum gehen, die grundlegenden Prinzipien von Programmiersprachen im Allgemeinen darzustellen.
Allen Sprachen ist gemein, dass sie einen Aufsatz auf Assembler darstellen und die Assembler-Funktionalität gewissermaßen auf komfortable Art und Weise einkapseln – ähnlich, wie Assembler vorher die Nutzung der Bitketten-Instruktionen vereinfacht hat. Nun war die Entwicklung von Assembler relativ einfach, da es im Grunde lediglich notwendig war, die ohnehin schon vorhandenen Bitketten-Instruktionen durch besser lesbare Befehle zu ersetzen; man konnte also fast eine 1-zu-1-Abbildung durchführen (ganz so einfach ist es natürlich nicht und Assembler kann auch noch mehr Dinge; als Analogie soll es hier aber genügen). Für den nächsten Schritt in der Entwicklung von Programmiersprachen sollte es dann aber schon ein wenig mehr sein.
Das wichtigste zu lösende Problem war die allgemeine Lesbarkeit der Anwendungen. Mit Assembler konnte zwar alles wunderbare ausgedrückt werden, aber wirklich intuitiv war es nicht unbedingt. Schauen wir zum Beispiel einmal auf den folgenden Code:
(2) sub al, var2
(3) mov var3, al
Hier wird nicht anderes gemacht als zwei im Speicher stehende Zahlen voneinander zu subtrahieren und das erhaltene Ergebnis an einer dritten Stelle zu speichern. Aus der Mathematik kennt man hierfür eine weitaus verständlichere Form der Notation:
var3 = var1 - var2
Ist doch so viel besser lesbar, oder? Gut, in der Mathematik hat obige Schreibweise eine etwas andere Bedeutung, nämlich, dass
var3
dem Wert von var1
vermindert um den Wert von var2
entsprechen soll – es ist damit mathematisch gesehen eine Zustandsbeschreibung. Da Computer mit so etwas aber in der Regel nicht klarkommen, wird hier einfach die Bedeutung umdeklariert: var3
soll den Wert annehmen, der sich aus der Subtraktion von var1
und var2
ergibt; damit haben wir eine Anweisungsfolge und keine Zustandsbeschreibung mehr. Wer jetzt der Meinung ist, dass das doch etwas Haarspalterei und am Ende das Gleiche wäre, dem sei dieses Beispiel ans Herz gelegt. Die folgenden beiden Zeilen sind so direkt hintereinander geschrieben in der Mathematik unsinnig:
x = 4
x = x - 1
Die Variable x kann in der Mathematik nicht gleichzeitig den Werten 4 und 3 entsprechen. In der Informatik sieht das allerdings anders aus, da wir es hier mit zwei voneinander getrennten Anweisungen zu tun hätten; zudem ist eine Variable in der Informatik etwas anderes als eine Variable in der Mathematik, da sie bei ersterem eine Stelle im Speicher, bei letzterem aber ein bestimmtes Konzept (etwa einen Wert) symbolisiert. Der folgende Code in der Informatik führt also dazu, dass die Variable x zuerst den Wert 4 und dann den Wert 3 annimmt; man spricht auch von einer Zuweisung. Ich verwende hier übrigens anstatt des in der Informatik oft üblichen Gleichheitszeichens einen Pfeil, um den Unterschied deutlicher zu machen; in gängigen Programmiersprachen wird der Pfeil (leider) durch das Gleichheitszeichen dargestellt (aber das nur am Rande):
(2) x ← x – 1;
Wer sich jetzt fragt, warum ich diesen Unterschied zwischen Mathematik und Informatik so explizit erwähne: eben dieser Unterschied sorgt dafür, dass Mathematiker ohne Informatik-Ausbildung häufig Probleme haben, die Ideen der Programmierung zu verstehen; ebenso ergeht es Programmieranfängern, denen der Unterschied nicht explizit erläutert wird, da sie ihre im Mathematikunterricht erlernten Denkprinzipien auf ein dafür nicht geeignetes Gebiet (eben die Informatik) anwenden wollen.
Kommentare (46)