2.1. Notwendige Arbeitsschritte

Die Erstellung eines C-Programms besteht aus mehreren Arbeitsschritten, wobei jeder einzelne seine eigenen Werkzeuge erfordert.

Zum Schreiben des Programms benötigt der Programmierer einen Editor. Dafür reicht zwar prinzipiell auch ein Textverarbeitungsprogramm, wobei allerdings unbedingt darauf geachtet werden muß, daß die C-Dateien als reiner ASCII-Text ohne Formatierungszeichen abgespeichert werden. Spezielle Programmier-Editoren haben jedoch den Vorteil, daß sie die jeweiligen Sprachen unterstützen und damit dem Programmierer die Arbeit erleichtern. Merkmale eines guten Programmier-Editors sind u.a. automatische Quellcode-Formatierung, unbegrenzte Undo-Funktion, mit der alle Änderungen schrittweise rückgängig gemacht werden können und ein Brace-Checker, der die Übereinstimmung von öffnenden und schließenden Klammern überprüft. Darüber hinaus darf man erwarten, daß der Compiler innerhalb des Editors gestartet werden kann.

Kommerzielle C-Implementierungen werden mittlerweile mit vollständigen Entwicklungsumgebungen ausgeliefert. Integriert sind dabei Editoren, die den genannten Ansprüchen genügen und die weitgehend auf die individuellen Bedürfnisse des Programmierers angepaßt werden können. Dies gilt besonders für den PC-Bereich, wo die etablierten Anbieter um den größtmöglichen Funktionumfang ihrer Produkte wetteifern. Unter UNIX erfreuen sich die dort stets vorhandenen Editoren vi und emacs immer noch großer Beliebtheit.

Per Konvention erhalten C-Quellcode-Dateien die Erweiterung .c; es empfiehlt sich, diese Konvention einzuhalten, da einige Compiler Dateien nur dann als C-Dateien akzeptieren, wenn ihr Name das .c-Suffix aufweist.

Ist das Programmieren beendet, so liegt eine Textdatei (oder auch mehrere Dateien) vor, deren Inhalt in der Programmsprache C formuliert wurde. Diese Datei heißt Quelldatei, enthält den C-Quellcode und besteht nur aus lesbaren Zeichen. Es ist nun die Aufgabe des Compilers, die in C vorliegenden Anweisungen in maschinenspezifischen Binärcode zu übersetzen. Bevor der Übersetzungsprozeß beginnt, ruft der Compiler den Preprozessor auf, der bestimmte, im Quellcode enthaltene Anweisungen ausführt. Die einzelnen Preprozessor-Anweisungen werden im Kapitel 12 besprochen.

Die vom Compiler erstellten Objektdateien sind maschinenabhängig, d.h., sie sind auf eine bestimmte Hardwareplattform zugeschnitten und nicht auf anderen Rechnertypen verwendbar. Im Gegensatz dazu kann der Quellcode virtuell auf alle möglichen Computer übertragen und dort wieder in ein maschinenspezifisches Format übersetzt werden. Die Objektdateien erhalten unter DOS üblicherweise die Endung .OBJ, unter UNIX die Endung .o.

Der Compiler überprüft beim Übersetzen den Quellcode auf syntaktische Korrektheit und gibt mehr oder weniger aufschlußreiche Meldungen aus, falls das Programm Fehler enthält. Gute Programmier-Editoren heben die fehlerhaften Stellen hervor und erlauben das Springen von Fehler zu Fehler über eine Tastenkombination. Sind alle beanstandeten Programmteile korrigiert, steht der endgültigen Übersetzung nichts mehr im Wege.

Da C u.a. keine Befehle für Ein- bzw. Ausgabe oder die explizite Verwaltung des Speichers enthält, müssen dafür Funktionen herangezogen werden, die mit dem C-Compiler ausgeliefert werden und in Bibliotheken abgelegt sind. Tatsächlich nehmen alle ernsthaften C-Programme Bibliotheksfunktionen in Anspruch. Nach getaner Übersetzung muß das C-Programm also irgendwie mit den Bibliotheksfunktionen, die es benutzen will, in Verbindung gebracht werden: Dies ist die Aufgabe des Linkers. Der Linker erstellt aus Objektdateien durch Einbindung von Bibliotheksroutinen ausführbare Programmdateien. Diese haben bei PC-Betriebssystemen wie DOS und Windows die Endung .EXE. Die integrierten Entwicklungsumgebungen moderner Compiler ermöglichen es, den Linker nach erfolgreicher Übersetzung automatisch zu starten. Bei Kommandozeilen-Versionen von C-Compilern besteht die Möglichkeit, den Prozeß von Compilieren und Linken durch das make-Utility zu automatisieren.

Wenn Übersetzungs- und Linkprozeß ohne Fehler verlaufen sind und eine ausführbare Datei vorliegt, heißt dies meistens aber noch nicht, daß die Erstellung eines Programms erfolgreich beendet wurde. Bei nicht-trivialen Programmen schließt sich an das Programmieren und Compilieren bzw. Linken in der Regel ein mühsamer Prozeß der Fehlersuche an, der oft zeitaufwendiger ist als die Erstellung des Programms selbst. Wie ist das möglich, wenn doch Compiler und Linker nichts Verkehrtes an dem Programm finden konnten? Der Compiler meldet in erster Linie die Fehler, die gegen die Regeln der Sprache C verstoßen. Fehler hingegen, die bei der Ausführung des Programms auftreten, heißen Laufzeitfehler und äußern sich hauptsächlich darin, daß das Programm bei der Ausführung bestimmter Funktionen abbricht oder gar mit einem Absturz endet. Außerdem besteht immer die Möglichkeit, daß dem Programmierer logische Fehler unterlaufen sind: Das Programm ist dann zwar syntaktisch korrekt formuliert, die ausführbare Datei produziert anschließend aber nicht die gewünschten Ergebnisse.

Um Laufzeitfehlern und logischen Ungereimtheiten auf die Schliche zu kommen, verfügen viele C-Entwicklungssysteme über sogenannte Debugger (Bug steht im Computerjargon für Fehler). Gute Debugger sind in der Lage, das Programm nicht nur auf der Ebene der Maschinensprache zu inspizieren, sondern ermöglichen auch Programmablaufverfolgung auf der Ebene des C-Quellcodes. Diesen Prozeß nennt man Source Level Debugging. Zusätzlich erlauben die meisten Debugger, das Programm in Schritten von einzelnen Programmzeilen ablaufen zu lassen, das Setzen von Breakpoints, an denen der Programmablauf gestoppt wird, und die laufende Überwachung von Variablenwerten.