Die Sprachen C und C++

C und C++ sind Programmiersprachen, also Sprachen, mit denen Computerprogramme geschrieben werden. Im folgenden wird versucht, C und C++ in einen allgemeinen Kontext einzuordnen. Diese Seite soll ein Verständnis für grundlegende Motivationen der Sprachen aufbauen, indem kurz umrissen aufgezeigt wird, wie sich C und C++ entwickelt haben.

Ein kurzer historischer Rückblick

Es ist noch nicht lange her, seit die ersten elektronischen Schaltungen erfunden wurden: Eine Methode, mit der elektrischer Strom kontrolliert auf verschiedene Leitungen verteilt werden kann. Das Zusammenfügen mehrerer Schaltungen und Leitungen führte zu den ersten elektronischen Geräten: Einfache Steuerelemente wie beispielsweise automatische Türöffner, Zeitschaltuhren oder die Blinklichter eines Autos. Diese Steuerelemente wandeln stets irgendwelche Eingangssignale wie beispielsweise einen Tastendruck durch eine mehr oder weniger komplizierte Verknüpfung verschiedener Schaltungen in Ausgangssignale um. Erfüllt eine Zusammenstellung von Schaltungen einen bestimmten Zweck, so wird sie als sogenannt integrierte Schaltung in einen Chip gepackt, welcher als Ganzes die gewünschte Funktion ausführt.

Elektronische Bauteile wie Chips werden aufgrund ihrer physikalischen Greifbarkeit Hardware genannt. Mit der Zeit wurden die Ansprüche an Hardware immer höher und die Verknüpfungen in den Chips wurden immer komplizierter. Um beliebig komplexe Funktionen ausführen zu können, wurde schliesslich der programmierbare Chip erfunden, ein Chip, der nicht nur eine bestimmte Funktion ausführen kann, sondern ein ganzes Set von grundlegenden Befehlen, darunter beispielsweise auch Addieren und Subtrahieren. Zusammen mit einem elektronischen Modul, welches Informationen zwischenspeichern kann (und auch heute noch als der Speicher bekannt ist), können beliebig komplexe Funktionsabläufe mittels eines einzigen Chips erledigt werden. Dies nennt man noch heute die CPU, Central Processing Unit, oder schlicht: Den Prozessor.

Assembler

Damit ein Prozessor weiss, was für eine Funktion er ausführen soll, braucht er Instruktionen, einen Code, welcher genau vorgibt, wann welche Eingangssignale mit welcher Methode verknüpft werden sollen. Die Zusammenstellung eines Codes wird Software genannt und hat die Aufgabe, die Hardware zu steuern, zu kontrollieren. Eine Abfolge von Instruktionen für einen Prozessor nennt man ein Maschinen-Programm, welches in der einzigen für den Prozessor verständlichen Sprache verfasst ist: Der Maschinen-Sprache. Jeder Prozessortyp hat eine eigene Maschinensprache, die nur er versteht. Sie ist für einen Menschen grundsätzlich unverständlich, da sie nur aus binären Werten besteht, welche bestenfalls als Zahlen interpretiert werden können.

Zu alten Zeiten mussten Programmierer somit einem Prozessor Zahlenwerte übermitteln, um eine bestimmte Funktionalität zu erreichen. Da dies für einen Menschen schwierig zu handhaben ist, wurde der sogenannte Assembler erfunden, ein Programm, welches halbwegs menschliche Wörter in die gewünschten Zahlenwerte umwandelt. Die Sprache, die durch diese Wörter entsteht, wird genauso wie das Umwandlungsprogramm selbst auch Assembler genannt. Folgendes ist ein Beispiel eines Assembler-Programmes:

pushl %ebp movl %esp, %ebp subl $24, %esp movl $1, -20(%ebp) movl $1, -16(%ebp) movl -16(%ebp), %eax addl -20(%ebp), %eax movl %eax, -12(%ebp) movl $0, %eax leave ret

Da jeder Prozessortyp seine eigene Maschinensprache hat, hat auch jeder Prozessortyp seinen eigene Assemblersprache. Die Entwicklung von Prozessoren hält bis heute an, und die Organisation der Daten wurde immer wieder verändert. Dies würde bedeuten, dass ein Programmierer einen Code für jeden Prozessortyp neu schreiben müsste. Um dies zu verhindern, wurden neue Programmiersprachen entwickelt, welche sich nie verändern, im Hintergrund jedoch anhand eines Compilers und/oder Interpreters den Code in jeden gewünschten Assembler umkonvertieren. Da solche Sprachen über allen Assemblern stehen, werden sie als Hochsprachen bezeichnet. Ein Beispiel für eine Hochsprache ist C.

C

Die Sprache C wird als Befehls-Sprache bezeichnet, das bedeutet, dem Computer werden genauso wie beim Assembler mehr oder weniger direkt Befehle erteilt in einer ganz genau definierten Reihenfolge. Einen Befehl nennt man in C Anweisung, seltener auch Instruktion. Solche Anweisungen werden normalerweise in eine Textdatei geschrieben, was man umgangssprachlich als Code bezeichnet. Anhand eines Compilers wird dieser Code zuerst in Assembler übersetzt und dann in Maschinensprache, dies bedeutet, dass schlussendlich ein direkt auf dem Prozessor lauffähiges Programm generiert wird.

Mehrere aufeinanderfolgende Anweisungen werden als sequentielle Abarbeitung des Codes bezeichnet, bei sehr vielen aufeinanderfolgenden Anweisungen spricht man auch von Spaghetti-Code. Diese Teile des Codes sind diejenigen, an welchen der Prozessor schlussendlich Daten verarbeitet, rechnet, produktiv ist. An gewissen Stellen jedoch wird dem Prozessor mitgeteilt, dass er an eine andere Stelle im Code springen soll, beispielsweise, da er je nach Eingabewert etwas anderes ausführen soll. Eine solche Änderung des Befehlsflusses wird allgemein als Kontrollstruktur bezeichnet.

C erlaubt es dem Programmierer, ein Programm in einer übersichtlichen Form zu definieren. Beispielsweise können alle verfügbaren Daten mit einem Namen versehen werden, was man als Variable bezeichnet. Der Umgang mit Werten wird erleichtert, indem mathematische Operationen mittels Symbolen wie +, -, * und / geschrieben werden können. Kontrollstrukturen können in verständlicher und gar visuell unterstützender Form dargestellt werden. In C sind sämtliche Daten mit einem Typ versehen, was eine flexible und doch sichere Datenmanipulation ermöglicht. Für den geordneten Ablauf des Programmes können Teile des Codes in Funktionen verpackt werden, welche an anderer Stelle beliebig aufgerufen werden können. Dasselbe Programm wie im obigen Assembler-Beispiel sieht in C folgendermassen aus:

int main(){ int a = 1; int b = 1; int c = a + b; return 0; }

Mit der Sprache C wurde ein Hilfsmittel geschaffen, um Datenmanipulationen schnell und geordnet durchführen zu können. Die Sprache ist durch die Nähe zu Assembler nicht immer ganz einfach, für den eingefleischten Programmierer jedoch sehr praktisch. Viele Dinge, die man als Programmierer häufig machen muss, sind mit C vereinfacht worden. Viele bekannte kommerzielle Softwarepakete sowie die gängigen Computersysteme sind in ihrer Basis mit C programmiert worden. Die Sprache C kann auch heute noch mit anderen Sprachen konkurrenzieren, insbesondere durch die Erweiterung mit C++ auf objektorientierte Programmierung.

C++

C++ ist auf C aufgebaut, beinhaltet somit den kompletten Funktionsumfang von C, bietet jedoch neue Möglichkeiten in der Datenorganisation. Die Grundüberlegung, dass in C sämtliche Werte einem Typ zugeordnet sind, wurde in C++ dahingehend erweitert, dass jeder Typ eine Klasse repräsentiert. In einer Klasse wird ein zusammengehöriges Set von Daten deklariert und Programmcode so damit verknüpft, dass die Klasse eine Dateneinheit beschreibt mit programmierten Eigenschaften, den sogenannten Methoden. Die Deklaration einer Variablen mit einer Klasse erstellt eine Instanz, oder einfacher: ein Objekt. Um das obige Beispiel in C++ weiterzuführen wurde eine Klasse für eine Nummer definiert:

class Number{ int n; public: Number(int n){this->n = n;} Number operator +(Number o){return Number(n + o.n);} }; int main(){ Number a = 1; Number b = 1; Number c = a + b; return 0; }

Die Methoden einer Klasse definieren, welche Funktionen mit den gespeicherten Daten ausgeführt werden können, aus denen die Objekte bestehen. Dies bedeutet, dass man ausserhalb einer Klasse weder den genauen Aufbau der Daten kennen, noch dieselben zu kontrollieren braucht, es genügt, die passenden Funktionen der Objekte aufzurufen. Alleine durch die Deklaration des Typs sind somit automatisch alle benötigten und passenden Funktionen verfügbar. Die objektorientierte Programmierung in C++ erlaubt es zudem, Klassen ineinander zu verschachteln und Methoden über Klassen hinweg zu vererben. Zusammen mit dem Laufzeitsystem von C++ führt dies zu Polymorphismus, was jedoch an anderer Stelle erklärt wird.

Die Einkapselung von Code und Daten in Klassen strukturiert die Arbeit an der Software. Diese Modularisierung erlaubt es, in einem Programm gesamte Bereiche je nach Bedarf einzubinden. In C++ wird dies durch sogenannte Namespaces (Namensräume) erreicht: Methoden sind unsichtbar, solange man nicht explizit den Namensraum anspricht, in dem sie deklariert wurden.

Um die Arbeit mit Objekten weiter zu vereinfachen, können in C++ nebst Methoden auch benutzerdefinierte Operatoren programmiert werden. Dies wird als Operatorenüberladung bezeichnet und erlaubt es, für beliebig komplexe Typen beispielsweise eine Addition zu definieren. Um die Programmierarbeit zusätzlich zu erleichtern, wurden in C++ Templates (Vorlagen) eingeführt: Eine Erweiterung der Sprache, die es erlaubt, Code unabhängig vom benötigten Typ zu schreiben.

Mehr über C und C++

Hier auf dieser Seite hört die Geschichte von C und C++ auf. Als Rahmen sei hier festgehalten, dass die Sprache C aus der Sprache B entstand, welche erstmals etwa 1969 auftrat. C wurde 1972 von Dennis Ritchie, C++ wurde 1983 von Bjarne Stroustrup entwickelt. 1986 wurde mit Objective-C eine Erweiterung geschaffen und 1999 kam erstmals die Sprache D ins Spiel, genaue Informationen findet man anderswo.