Zum Hauptinhalt springen

Programmiersprachen

Jede Programmiersprache hat eigene Regeln und Richtlinien, wie ein Programm geschrieben wird. Es wird dabei zwischen der Syntax und der Semantik unterschieden.

Syntax

Wörter und Symbole, die in einer Programmiersprache verwendet werden dürfen

Fehler werden bereits vor dem Programmstart erkannt

Semantik

Inhaltliche Bedeutung des Codes

Die Bedeutung ergibt sich durch die Verwendung der gegebenen Syntax

Fehler werden erst zur Laufzeit erkannt

Mittlerweilen gibt es eine schier unüberschaubar grosse Anzahl an Programmiersprachen (Liste aller Programmiersprachen). Im EF werden wir zu Beginn mit Python 3 programmieren, bevor wir dann auch Einblicke in andere Programmiersprachen und Domänenspezifische Sprachen (SQL) erhalten werden.

Sprachstufen​

Bei der Klassifizierung von Programmiersprachen wird aktuell unter vier Typen von Programmiersprachen unterschieden:

Wobei die Interpretierten Sprachen auch oft Skriptsprachen genannt werden

Maschinensprache​

Zu den Pionierzeiten der Computerentwicklung war die einzige Möglichkeit, ein Programm für einen Computer zu erstellen, dieses in binärem Maschinencode zu schreiben (bzw. auf Lochkarten zu stanzen). Aufgrund ihrere für Menschen extrem schwer verständlichen Form ist die Programmierung in Maschinensprache nicht mehr gebräuchlich.

Die Maschinensprache kann direkt von einer CPU ausgefĂĽhrt werden.

Achtung

Maschinencode läuft nicht einfach auf allen Prozessoren - je nach Aufbau/Architektur des Prozessors müssen andere Befehle verwendet werden.

	0  00101001111101100111101101
1 00101001111110101110000010
2 10001001010101000100000000
3 00101001111101100100100101
4 10001001010101000100000000
5 00100110001110010111001100
6 01010111110110100100010010
7 00100110010001010101110100
8 00011000000100100011110011
9 10000101100000111101000011
10 01110110010000010111100011
11 00100111001000111110110000
12 00101001111101100111101101
13 00101001111111000111000010
14 10001001010101000100000000
15 00101001111101100110001001
16 00100110010000110001111000
17 10001001010101000100000000
18 00101001111101100111101101
19 00101001111111100011001010
20 10001001010101000100000000
21 00101001111101100110001001
22 00100110010011001110001000
23 10001001010101000100000000
info
  • unlesbar, unveränderbar

  • nur Linus Torvalds, Erfinder von Linux, schreibt und ändert Maschinencode

In einigen wenigen Spezialfällen (wenn z.B. der eigentliche Quellcode oder die ursprüngliche Programmierumgebung nicht mehr verfügbar ist) kann es unter Umständen erforderlich sein, direkt den Maschinencode zu bearbeiten.

Assembler Sprache​

In Assembler gibt es als Erleichterung für die Programmierer:in sogenannte mnemonische Kürzel (Mnemonics), die eine Gedächtnisstütze für die entsprechend möglichen CPU-Befehle sein sollen, bspw. addiu für die Addition von positiven ganzen Zahlen (Add Integer Unsigned). Die Assemblersprache ist gerade noch verständlich für einen Menschen und kann leicht von einem Programm, dem sogenannten Compiler in Maschinensprache übersetzt werden, da für jeden Mnemonics ein CPU-Befehl existiert. Dennoch ist Assembler-Sprache bereits auf eine CPU-Architektur zugeschnitten und es muss im Voraus entschieden werden, welches Ziel man sich vornimmt (nicht jede CPU-Familie weist dieselbe Befehlspalette auf).

Ein einfaches Beispiel einer Addition von zwei ganzen Zahlen

sum:
addiu $sp,$sp,-8
sw $fp,4($sp)
move $fp,$sp
sw $4,8($fp)
sw $5,12($fp)
lw $3,8($fp)
lw $2,12($fp)
nop
addiu $2,$3,$2
move $sp,$fp
lw $fp,4($sp)
addiu $sp,$sp,8
jr $31
nop
info

Aufgrund der mühseligen Programmierung und der fehlenden Portabilität von Programmen auf unterschiedliche Systeme ist Assembler nicht für komplexe Projekte zu empfehlen. Für bestimmte zeitkritische Aufgaben (Echtzeit), wo es auf Geschwindigkeit ankommt (bspw. Grafiktreiber) oder nur sehr wenig Platz zur Verfügung steht (embedded systems), wird auch heute noch auf Assembler zurückgegriffen.

Hochsprachen​

In Hochsprachen wird eine Abstraktionsschicht fĂĽr komplexen Funktionen wie

  • Speichermanagment

  • Repetition von immer gleichen Mustern

  • Betriebssystemabhängige Unterschiede

hinzugefĂĽgt. Dadurch mĂĽssen Programmierer:innen Algorithmen nicht fĂĽr jede CPU-Architektur neu schreiben. Zudem ist der Code nochmals bedeutend besser lesbar als in der Assembler Sprache.

Obiges Beispiel in Assemblersprache sieht in Hochsprachen wie folgt aus:

#include <stdio.h>

int sum(int zahl1, int zahl2) {
return zahl1 + zahl2;
}

int main()
{
printf("3 + 4 = %d", sum(3, 4));
return 0;
}
Finding

Was fällt Ihnen bei den verschiedenen Programmiersprachen auf?

In Hochsprachen wird zusätzlich unterschieden zwischen kompilierten und interpretierten Sprachen.

Kompilierte Sprachen​

C C# Java ...

Wie bei der Assemblersprache muss ein geschriebenes Programm durch einen Compiler in Maschinensprache übersetzt werden. Dieser Prozess ist bei Hochsprachen um einiges komplexer als bei Assemblersprache, da keine direkte Übersetzung möglich ist. Da das Programm nach der Kompilierung von einem Prozessor ausgeführt wird, braucht es einen vorgegebenen Einstiegspunkt - eine Funktion namens main.

Zwischenschritt Bytecode

Einige kompilierte Sprachen verwenden zur Erhöhung der Portabilität eine Zwischensprache, sogenannter Bytecode verwendet. Dieser Bytecode ist quasi die Maschinensprache für eine virtuelle Maschine (VM für Virtual Machine). Um den Bytecode auszuführen, muss also lediglich die VM auf einem System installiert werden, und der Bytecode kann ausgeführt werden.

Interpretierte Sprachen​

Python Ruby Java Script ...

Für die Programmierung einer Skriptsprache braucht es keine Installation eines zusätzlichen Compilers. Die Programmiersprache, also bspw. Python, interpretiert den Quellcode direkt. Dazu wird der Code gelesen (Parsen) und gemäss der Syntax-Vorgaben in einen Syntax-Baum (AST, Abstract Syntax Tree) übersetzt.

Python Code
def sum(zahl1, zahl2):
return zahl1 + zahl2
Ăśbersetzer AST
Ăśbersetzer AST

Auf dieser Basis entscheidet der Interpreter fĂĽr jeden Knoten im Baum, welche kompilierte Funktion ausgefĂĽhrt werden soll. Diese kompilierten Funktionen werden oft in C geschrieben und bei der Installation der Programmiersprache in Maschinencode compiliert (bzw. bereits compiliert heruntergeladen).

Da kein eigentlicher Compile-Schritt notwendig ist, muss bei Skriptsprachen auch keine main als Einstiegspunkt vorhanden sein. Zudem ist es im Gegensatz zu kompilierten Sprachen möglich, den Quellcode von laufenden Programmen zu verändern. Deshalb ist es etwa auch möglich, eine interaktive Code-Konsole (REPL ReadEvaluatePrintLoop) für Skriptsprachen auszuführen.

Insgesamt ist das Arbeiten mit Skriptsprachen mit weniger Konfigurationsaufwand, weniger Standardcode (Boilerplate Code) verbunden und daher effizienter. Der Nachteil ist, dass die Programme deutlich langsamer (ca. 10x langsamer) ausgefĂĽhrt werden.

Footnotes​

  1. ↩