Ein zentrales Thema bei der Verarbeitung von Computerprogrammen ist die Ein- und Ausgabe von Daten. Wir legen ein neues Projektverzeichnis mit dem Namen einaus an, in dem wir folgenden Quellcode als einaus.c speichern:
Code: Alles auswählen
#include <stdio.h>
#define PI 3.141592654
int main(void) {
float radius, flaeche;
printf("Kreisflaeche berechnen\n\nRadius: ");
scanf("%f", &radius);
flaeche = PI * radius * radius;
printf("\nDie Flaeche betraegt: %f\n", flaeche);
return 0;
}
Wir erzeugen das ausführbare Programm mit
Es ist an der Zeit ein paar Worte über das Kompilieren und Binden zu verlieren.
zcc ist nicht der Compiler, sondern das Compiler Frontend, das seinerseits einen C-Compiler aufruft. Das z88dk hat gleich zwei zur Auswahl: den klassischen Compiler
sccz80 und den moderneren Compiler
zsdcc. Über die zcc-Option -compiler=sdcc können wir zsdcc auswählen; mit -compiler=sccz80 wird der klassische Compiler verwendet, der auch der Standard ist, wenn wir die Option -compiler weglassen.
Die Option +cpm wählt die Plattform aus, für die der Code erzeugt werden soll (CP/M). Dazu geben wir den Untertyp pcw80 über die Option -subtype an. pcw40 wäre genausogut möglich; der Unterschied ist nur das Diskettenformat der bei Verwendung der zusätzlichen Option -create-app erzeugten Image-Datei, die automatisch die Endung .dsk bekommt. Beide pcw-Optionen erzeugen Code für die Amstrad PCW-Rechner.
zcc kompiliert nicht nur, sondern kann auch gleich den Linker aufrufen um eine ausführbare COM-Datei zu erstellen, was wir ja bereits fleißig nutzen. Mit -l kann man zusätzliche Bibliotheken (libraries) angeben, die zum Programm dazugebunden werden. Hier wird mit -lm die Standard-Mathematik-Library dazugebunden, die wir für die float-Verarbeitung brauchen.
Dann folgt die zu kompilierende C-Datei, hier einaus.c. An dieser Stelle kann auch eine Liste von mehreren C-Dateien stehen, von denen aber nur eine eine main-Funktion enthalten darf. Über die Option -o können wir schließlich den Namen der Ausgabedatei angeben, hier einaus.com.
Nun zum Programm einaus:
Der
#include-Befehl ist eine sog. Präprozessor-Direktive, wie alle Befehle, die am Zeilenanfang ein Hash-Symbol (#) haben. Wichtig: das # muss ganz am Anfang der Zeile stehen! Der Präprozessor verarbeitet alle Quellcode-Dateien, bevor der Compiler zum Zuge kommt. Er liest nur die Zeilen, die mit # führt dann bestimmte Textersetzungsoperationen durch. Bei #include fügt er genau an dieser Stelle den Inhalt der Datei an, die hinter der #include-Direktive aufgeführt ist. Steht der Dateiname in spitzen Klammern wie hier, dann wird die Datei im include-Verzeichnis des Compilers gesucht. Steht er in Gänsefüßchen, dann wird sie im selben Verzeichnis gesucht, in dem sich auch die Datei befindet, die die #include-Direktive enthält.
Die
#define-Direktive wird oft für die Definition von
Konstanten verwendet, hier für die Kreiszahl Pi. Der Präprozessor sucht in der Folge alle Textstellen, in denen "PI" vorkommt und ersetzt sie durch "3.141592654". Das funktioniert wie beim Suchen / Ersetzen im Editor.
Es folgt die Funktion
main, also der Einsprungpunkt in das Programm. In unserem Beispiel werden keine Parameter von der Kommandozeile gebraucht, also steht zwischen den Klammern das Schlüsselwort
void, was so viel wie "nichts" bedeutet.
Dann folgt einen geöffnete geschweifte Klammer. Alle Anweisungen bis zur zugehörigen schließenden geschweiften Klammer bilden den Funktionsblock. Jede Anweisung wird in C mit einem Semikolon beendet. Das ist anders als in Pascal, wo das Semikolon zwischen Anweisungen steht.
Zu Beginn des Funktionsblocks werden zwei Variablen vom Typ float deklariert: radius und flaeche. Dann geben wir Text über die Funktion
printf aus. printf ist eine Abkürzung für "print formatted", weil sie die Ausgabe von formatiertem Text unterstützt. Der Text besteht aus der Überschrift "Kreisflaeche berechnen", dann folgen zwei Zeilenumbrüche (\n) und die Eingabeaufforderung "Radius: ". Die Ausgabe erscheint auf dem Bildschirm.
Wir wollen eine Gleitkommazahl eingeben; dazu dient die Funktion
scanf ("scan formatted"). scanf kann mehrere Parameter haben. Der erste ist immer der sog. Format-String: "%f" steht hier für "float" - wir wollen also einen Gleitkomma-Wert von der Tastatur "scannen". Die folgenden Parameter geben für jede mit dem Prozentzeichen eingeleitete Formatangabe jeweils eine Variable an, in die die eingegebenen Daten gespeichert werden sollen. Anders als bei printf werden die Daten aber nicht aus einer Variablen gelesen, sondern sie sollen in eine Variable geschrieben werden. Dazu muß scanf die Adresse der Variablen kennen. Als zweiten Parameter haben wir daher nicht radius, sondern &radius. Der
&-Operator ermittelt die Adresse der Variablen im Speicher des Rechners.
Die flaeche wird mit der bekannten Kreisformel berechnet. Ich möchte noch darauf hinweisen dass der Präprozessor aus dem "flaeche = PI * radius * radius;" bereits ein "flaeche = 3.141592654 * radius * radius;" gemacht hat. Das ist der Code, den der Compiler "sieht".
Die Fläche wird mit printf ausgegeben, wobei auch hier eine Formatangabe "%f" verwendet wird, um eine Gleitkommazahl auszugeben. An Stelle des "%f" wird der Wert der Variablen flaeche eingesetzt, der printf als zweiter Parameter übergeben wurde.
Schließlich geben wir via
return eine 0 an das Betriebssystem CP/M zurück und signalisieren damit, dass kein Fehler aufgetreten ist.
Wenn wir das Programm einaus.com starten, dann erscheint die Aufforderung zur Eingabe des Radius. Geben wir z.B. 12.5 ein, dann erscheint das Ergebnis: "Die Flaeche betraegt: 490.873852".