zurück zum News-Archiv
> Anfang zurück vorwärts Ende ## ANSI C - Ein Programmierkurs - Teil II ### Compiler Als erste Übung werden wir die Entwicklungsumgebungen in Betrieb nehmen und konfigurieren. Dies unterscheidet sich sehr stark, je nach verwendetem Compiler und verwendeter Shell. Sozobon und GCC ähneln sich etwas, da beide Kommandozeilenprogramme sind, und die unbedingt notwendigen Parameter identisch sind. Die Konfiguration für Turbo-C/Pure-C (TC/PC) bzw. weitere Kommandozeilenparameter für Sozobon und GCC werden im Anhang nochmals detaillierter ausgeführt. Hier werden nur die unbedingt notwendigen Einstellungen besprochen. Als Beispielprogramm ist folgendes Programm einzugeben und unter dem Namen `first.c` zu speichern. Es ist der Klassiker der C-Programmierung; sehr viele C-Kurse bzw. Bücher beginnen mit diesem Programm. Achtung! Nach der letzten Zeile ist noch einmal ein Zeilenumbruch (RETURN-Taste drücken) erforderlich, damit der Sozobon-Compiler das Programm akzeptiert. ### first.c
>     #include <stdio.h>

>     int main(void)
>     {
>        printf("Hallo Welt!");
>        return 0;
>     }
> ### TC/PC Der Inhalt der Disketten ist in ein beliebiges Verzeichnis zu kopieren, z.B. `c:\tc` bzw. `c:\pc`. In diesem Verzeichnis sollten unter anderem die 2 Verzeichnisse `include` und `lib` zu finden sein; außerdem `tc.prg`, `tc.cfg` bzw. `pc.prg`, `pc.cfg` und `default.prj`. Im Verzeichnis `include` befinden sich Dateien mit der Extension `.h`, im Verzeichnis `lib` befinden sich Dateien mit der Extension `.lib` sowie die Datei `tcstart.o` bzw. `pcstart.o`. Die Bedeutung dieser Dateien wird später erklärt. Dies sind auch die Dateien, die für ein Minimalsystem auf Diskette unbedingt erforderlich sind. #### Konfiguration Als nächstes muss das System konfiguriert werden. Die hier abgebildeten Dialoge gehören zu TC. Die entsprechenden Dialoge von PC unterscheiden sich nur minimal, die wesentlichen Einträge sind auch unter PC vorhanden. Unter Options im Menüpunkt Compiler erscheint folgender Dialog: Hier muss das include directory auf den entsprechenden Pfad gesetzt werden. Das wäre im obigen Beispiel: `c:\tc\include` Unter Options im Menüpunkt Linker erscheint ein Dialog für die Linkeroptionen: Hier muss das library directory auf den entsprechenden Pfad gesetzt werden. Das wäre im obigen Beispiel: `c:\tc\lib` Anschließend bitte nicht das Abspeichern vergessen; dazu unter Options den Menüpunkt save TC.CFG aufrufen. Jetzt kann unter File mit dem Menüpunkt Open C mit dem Fileselektor eine neue Datei angelegt und editiert werden. Unter Project mit dem Menüpunkt Run kann diese Datei übersetzt und sofort ausgeführt werden. Jetzt sollte normalerweise der Compiler das Programm übersetzen, der Linker diese Datei mit den dazu benötigten Bibliotheken zusammenbinden und anschließend das Programm ausgeführt werden. TC/PC öffnet ein neues Fenster, in dem jetzt nur eine Meldung des Linkers erscheint. Sollten auch Fehlermeldungen des Compilers erscheinen, ist das Programm fehlerhaft abgetippt worden und sollte auf Tippfehler untersucht werden. Meldungen über doppelt definierte Symbole, die der Linker ausgibt, können hier ignoriert werden. Da sowohl Compiler als auch Linker vor Ausgabe der Meldungen eine Überschrift wie `******* Compiler messages:` ausgeben, können die Meldungen eindeutig zugeordnet werden. Mit der Taste Esc kann der Bildschirm auf die Ausgabe des Programms umgeschaltet werden. Diese Umschaltung funktioniert allerdings nur in den Standardauflösungen und nicht mit Grafikkarten. Auch Shells oder Multitasking-Betriebssysteme mit einem eigenen Konsolenfenster könnten die Ausgabe beeinflussen. Wenn es Probleme gibt, die Ausgabe des Programms zu lesen, kann das Programm wie folgt erweitert werden. Es wartet damit vor der Beendigung darauf, dass der Benutzer die Returntaste drückt. #### Wartendes `first.c`
>     #include <stdio.h>

>     int main(void)
>     {
>        printf("Hallo Welt!");
>        getchar();
>        return 0;
>     }
> ### Sozobon Der Inhalt der Archive ist in ein beliebiges Verzeichnis zu entpacken, z.B. `c:\sozobon`. Die Dateien des Archivs `scbin20.lzh` (`cc.ttp`, ...) gehören in das Unterverzeichnis `bin`. Hier sind die ausführbaren Programme zu finden. Achtung: Wird die Pfadangabe des Archivs übernommen, dann wird ein Verzeichnis `scbin20` angelegt, das die Programme enthält. Dieses Verzeichnis kann in `bin` umbenannt, oder der Inhalt kopiert werden. Das Archiv `sozlib15.zip` enthält die Bibliotheken. Nach dem Auspacken findet man ein Verzeichnis `sozdistr` vor. Dessen Inhalt ist in das gewünschte Verzeichnis, hier `c:\sozobon`, für Sozobon zu kopieren. Das Gleiche ist mit `sozuti09.zip` durchzuführen. Hier sind noch einige Hilfsprogramme enthalten. Das darin befindliche `make.ttp` wird benötigt, wenn das Projekt auf mehrere Dateien aufgeteilt wird. Als nächstes muss das Environment gesetzt werden, damit der Compiler die Includedateien, den Linker, und der Linker die Bibliotheken findet. Folgende Variablen sind zu setzen:
>     LIB

>     INCLUDE

>     PATH

>     TEMP
> Für die Shell Guläm ist unten ein Skript vorgestellt, das dies erledigt. Die dort aufgeführten Pfade müssen noch auf das Verzeichnis von Sozobon auf dem eigenen System angepasst werden. Die Pfade für das Include- und das Libverzeichnis gelten so für den Sozobon-Compiler auf der Seidel SDK-CD bzw. den oben angegebenen Quellen. Sollte sich die verwendete Distribution hier unterscheiden, so sind die Pfade entsprechend anzupassen. Im Includeverzeichnis muss eine größere Zahl von Dateien mit der Extension `.h` zu finden sein, darunter auch `stdio.h`. In dem Libverzeichnis sind unter anderen `crt0.o` und eine Anzahl Dateien mit der Extension `.a` zu finden. Es ist auch möglich, die Verzeichnisnamen aus den Archiven direkt zu benutzen und das Environment entsprechend anzupassen. Das Programm wird mit folgender Kommandozeile übersetzt:
>     cc -o first.tos first.c
> Es sollte keine weitere Meldung auf dem Monitor erscheinen. Anschließend sollte in dem Verzeichnis, in dem `first.c` steht, das übersetzte Programm `first.tos` stehen. Wenn von Guläm die Fehlermeldung kommt, dass der Befehl `cc` nicht gefunden wurde, stimmt entweder der Wert der Environmentvariable PATH nicht oder es wurde versäumt, mit dem Befehl `rehash` Guläm anzuweisen, die Verzeichnisse der `PATH`-Variable nach ausführbaren Programmen zu scannen. Wenn vom Compiler die Fehlermeldung erscheint, dass die Includedatei `stdio.h` nicht gefunden wurde, stimmt der Wert für `INCLUDE` nicht. Genauso ist bei der Fehlermeldung des Linkers, dass er `crt0.o` oder eine Lib nicht gefunden habe, die Variable `LIB` zu prüfen. #### `sozobon.g`
>     setenv LIB c:\sozobon\lib\sozobonx\xdlibs
>     setenv INCLUDE c:\sozobon\include\xdlibs
>     setenv PATH c:\sozobon\bin
>     setenv TEMP c:\temp
>     rehash
> ### GCC Der Inhalt der Archive ist in ein beliebiges Verzeichnis zu entpacken, z.B. `c:\gnu`. Der Inhalt der Archive `gcc258ba.zoo` und `gcc258bb.zoo` wird in das Unterverzeichnis `bin` entpackt. Der Inhalt des Archivs `includ97.zoo` gehört in das Verzeichnis `include`. Die Dateien, die in diesem Archiv im Verzeichnis `sys` sind, gehören natürlich nach `include\sys`. Der Inhalt des Archivs `libolb97.zoo` kommt in das Verzeichnis `lib`. Als nächstes muss das Environment gesetzt werden, damit der Compiler die Includedateien, den Linker, und der Linker die Bibliotheken findet. Folgende Variablen sind zu setzen:
>     GNULIB

>     GNUINC

>     PATH

>     TEMP
> Für den C++-Compiler müssen noch zusätzlich folgende Variablen gesetzt werden:
>     GXXINC und GXXLIB
> Für die Shell Guläm ist unten ein Skript vorgestellt, dass dies erledigt. Die dort aufgeführten Pfade müssen noch auf das Verzeichnis von GCC auf dem eigenen System angepasst werden. In dem Includeverzeichnis muss eine größere Zahl von Dateien mit der Extension `.h` zu finden sein, darunter auch `stdio.h`. In dem Libverzeichnis sind unter anderen `crt0.o` und eine Anzahl Dateien mit der Extension `.olb` zu finden. Das Programm wird mit folgender Kommandozeile übersetzt:
>     gcc -o first.tos first.c
> Es sollte keine weitere Meldung auf dem Monitor erscheinen. Anschließend sollte in dem Verzeichnis, in dem `first.c` steht, das übersetzte Programm `first.tos` stehen. Wenn von Guläm die Fehlermeldung kommt, dass der Befehl `gcc` nicht gefunden wurde, stimmt entweder der Wert der Environmentvariable `PATH` nicht, oder es wurde versäumt, mit dem Befehl `rehash` Guläm anzuweisen, die Verzeichnisse der `PATH`-Variable nach ausführbaren Programmen zu scannen. Wenn vom Compiler die Fehlermeldung erscheint, dass die Includedatei `stdio.h` nicht gefunden wurde, stimmt der Wert für `GNUINC` nicht. Genauso ist bei der Fehlermeldung des Linkers, dass er `crt0.o` oder `gnu.olb` nicht gefunden habe, die Variable `GNULIB` zu prüfen. #### `gnu.g`
>     setenv GNULIB c:\gnu\lib
>     setenv GNUINC c:\gnu\include
>     setenv GCC_EXEC_PREFIX c:\gnu\bin\gcc-
>     setenv UNIXMODE .,/d
>     set path c:\gnu\bin,$path
>     setenv TEMP c:\temp
>     setenv TMPDIR c:\temp
>     rehash
> ### Packer/Entpacker Hier folgt eine Kurzanleitung zum Auspacken der Archive. Sie ersetzt nicht die Anleitung der entsprechenden Programme. Die beiden Programme `lzhshell` und `stzip` sind jeweils GEM-Programme und deshalb selbsterklärend. Die Programme `zoo`, `gzip` und `tar` sollten als Kommandozeilenprogramme von einem Kommandozeileninterpreter (shell) gestartet werden. Es ist aber ausreichend, die Entpacker in das Verzeichnis des Archivs zu kopieren und nach einem Doppelklick die Parameter in den Dialog des Desktops einzugeben. Die `zoo`-Archive werden mit folgender Befehlszeile ausgepackt:
>     zoo -extract <archiv.zoo>
> Die `tgz`-Archive sind `tar`-Archive, die anschließend mit `gzip` gepackt wurden. Sie müssen also zuerst mit `gzip` ausgepackt, und anschließend die Dateien aus dem Archiv herausgeholt werden. Dazu werden zwei Programme gestartet. Zuerst wird das Archiv dekomprimiert:
>     gzip -d <archiv.tgz>
> Anschließend werden die Dateien aus dem Archiv herausgeholt:
>     tar xf <archiv.tar>
> > Anmerkung: bei neueren Versionen von `tar` lassen sich die beiden Schritte Entpacken und Auspacken auch in einem einzigen Schritt erledigen (nämlich dann, wenn `tar` die Option `z` versteht):
> >     tar xzf <archiv.tgz>
> ## Struktur eines C-Programms Schauen wir uns mal das (leicht erweiterte) Beispiel an. Diese Datei besteht aus verschiedenen Bereichen. Bei den Zeilen mit einem # in der ersten Spalte handelt es sich um Anweisungen für den Präprozessor. Darunter befinden sich eine Deklaration einer Variablen und im Anschluss daran eine Funktion. Ein gültiges C-Programm muss mindestens eine Funktion mit dem Namen main enthalten! Die Reihenfolge, in der Funktionen, Deklarationen und Präprozessoranweisungen erscheinen, ist beliebig, wichtig ist nur der Gültigkeitsbereich. Sie können auch mehrfach vorhanden sein oder entfallen, wenn sie nicht benötigt werden. Unser Beispiel `first.c`, das dazu diente, die Compiler in Betrieb zu nehmen, hatte keine Deklarationen. Um sich schneller in fremde Programme einzuarbeiten, wird meist die unten aufgeführte Reihenfolge bevorzugt.
>                                      \
>      #include <stdio.h>              |- Präprozessoranweisungen
>                                      /
>                                      \
>      int i;                          |- Deklarationen von Datentypen
>                                      |  und Variablen
>                                      /
>      int main(void)                  \
>      {                               |
>         int i; /* als Beispiel */    |
>                                      |- Funktionen
>         printf("Hallo Welt!");       |
>         return 0;                    |
>      }                               /
> Der in `/*` und `*/` eingeschlossene Text ist ein Kommentar, der vom Compiler überlesen wird. Kommentare dienen nur dazu, einem Programmierer Hinweise o.ä. zu geben. Sie können damit zum Verständnis von Programmen beitragen oder aber Teile des Codes von der Übersetzung ausnehmen. Einrückungen o.ä. sind nicht relevant und dienen nur dazu, dass der Programmierer optisch die Struktur des Programms leichter erfasst. Das obige Programm ließe sich deshalb z.B. auch wie folgt schreiben:
>     #include <stdio.h>
>     int i;
>     int main(void) {int i;printf(Hallo Welt!);return 0;}
> Durch Einfügen von Whitespaces, also Leerzeichen, Tabulatoren und Zeilenvorschübe, wird ein Programm lesbarer formatiert. Dazu wird jeder Block innerhalb geschweifter Klammern eingerückt. Eine gute Größe sind drei Leerzeichen, da hierbei noch nicht zu viel Platz einer Zeile verloren geht. Wenn auch die Monitore immer größer werden, so beschränkt man sich doch häufig auf maximal 80 Zeichen pro Zeile, damit auch bei einem Ausdruck die Zeile komplett auf das Papier passt und nicht vom Drucker umbrochen werden muss. Die Funktion kann man auch weiter aufschlüsseln. Sie besteht aus einem Funktionskopf und einem Block in geschweiften Klammern. Dieser Block kann am Blockanfang Deklarationen und anschließend Anweisungen (bzw. Statements auf Neudeutsch) enthalten.
>     int main(void)                  |- Funktionskopf
>     {                               \
>        int i;                       |- Deklarationen
>                                     /
>        printf(Hallo Welt!);       \
>        return 0;                    |- Anweisungen / Statements
>     }                               /
> In den folgenden Kapiteln werden wir uns die einzelnen Teile genauer anschauen. Zuerst kommt etwas Theorie über Variablen und Datentypen. Anschließend können mit Anweisungen erste Übungen mit Programmen durchgeführt werden. Nicht jedes der Beispiele wird ein komplettes Programm sein. Solche Beispiele werden dadurch gekennzeichnet, dass in ihnen 3 Punkte (...) als Hinweis auf fehlende Teile auftauchen. Solche Beispiele müssen Sie dann selbst in die Funktion `main` einbauen. Die benutzten Variablen sind auch zu deklarieren und auf sinnvolle Werte zu setzen, wenn noch keine Deklarationen vorhanden sind. Die letzte Zeile `return 0;` der Funktion `main` aus dem oben aufgeführten Beispiel ist immer mit zu übernehmen, wenn ein unvollständiges Beispiel in ein Programm übernommen wird. Andernfalls erhält man eine entsprechende Meldung des Compilers. Ist in dem Beispiel eine Ausgabe (`printf`) enthalten, muss die Zeile `include <stdio.h>` auch mit übernommen werden. Ansonsten kann sie wegfallen. Wenn die Beispiele übersetzt werden, können noch Warnungen des Compilers auftreten, weil z.B. Variablen nicht weiter benutzt werden. Sie können hier ignoriert werden, da eine Abhilfe das Programm nur unnötig vergrößern würde und das Wesentliche des Beispiels verschleiert. Bei der Entwicklung eigener Programme sollte man allerdings auch auf Warnungen ein Augenmerk richten, da es sich um versteckte Fehler handeln kann. ## Variablen und Standarddatentypen In C muss jede Variable durch die Angabe ihres Datentyps und Namens deklariert werden. Der Compiler kennt keine impliziten Variablen. Dies mag einem Basic-Programmierer vielleicht etwas umständlich erscheinen. Der Vorteil ist aber, dass gerade bei Verwendung von aussagekräftigen Namen ein Tippfehler zu einem ungültigen Namen führt und damit schon vom Compiler erkannt wird. Variablen können außerhalb von Funktionen an jeder Beliebigen Stelle und am Anfang eines jeden Blocks (geschweifte Klammern) deklariert werden. ### Gültige Namen Ein in C gültiger Name besteht nur aus Buchstaben, Ziffern und dem Unterstrich '_', wobei zwischen Groß- und Kleinschreibung unterschieden wird. Das erste Zeichen muss ein Buchstabe sein. Die deutschen Umlaute werden nicht zu den Buchstaben gezählt, hier sind nur 'a' - 'z' und 'A' - 'Z' erlaubt! Es werden mindestens die ersten 31 Zeichen für eine Unterscheidung der Namen herangezogen. Bei Namen, die aus anderen Bibliotheken stammen, können es aber weniger Zeichen sein; dann sind mindestens 6 Zeichen signifikant. Es muss hier auch nicht zwingend zwischen Groß- und Kleinschreibung unterschieden werden. Einige Namen sind von der Sprache C schon reserviert und dürfen nicht für eigenen Namen benutzt werden. Diese reservierten Wörter sind im Kapitel reservierte Bezeichner aufgeführt. Einige Beispiele für gültige Namen:
>     Name1 Test DiesIstEinSprechenderName dies_auch _Nur_intern Zeile_3
>     Dies_ist_ein_sehr_langer_Namen_mit_vielen_Buchstaben
>     Dies_ist_ein_sehr_langer_Namen_auch_mit_vielen_Buchstaben
> Die beiden letzten Namen unterscheiden sich in den ersten 31 Zeichen nicht. Ein Compiler, der sich nur an das Minimum von mindestens 31 signifikanten Zeichen hält, kann diese beide Namen also nicht unterscheiden. Einige Beispiele für unzulässige Namen:
>     3_Zeichen Häuser while
> Es hat sich als Konvention eingebürgert, für Variablenbezeichner Kleinschreibung zu benutzen. Wenn ein Name aus mehreren Worten zusammengesetzt ist, werden die einzelnen Bestandteile durch einen Unterstrich voneinander abgetrennt:
>     dies_ist_ein_zusammengesetzter_name
Man sollte außerdem einen Namen wählen, der für die Verwendung der Variable aussagekräftig ist, also einen sprechenden Namen. Dies erleichtert es, die Verwendung der Variablen zu erkennen und damit ein Programm zu verstehen! Im nächsten Abschnitt werden wir uns mit Datenstrukturen beschäftigen. Michael Bernstein

Anfang zurück vorwärts Ende Seitenanfang

Copyright und alle Rechte beim ATOS-Magazin. Nachdruck und Veröffentlichung von Inhalten nur mit schriftlicher Zustimmung der Redaktion.
Impressum - Rückmeldung via Mail oder Formular - Nachricht an webmaster