Das Programm 'Hello proggen.org'

  • Der Aufbau einer Quellcodedatei
  • Datentypen und Funktionen
  • Die Funktion main

Der Quelltext

Hier nochmal das Programm, das wir in der vorherigen Lektion kompiliert und ausgeführt haben:

#include <stdio.h>
 
int main( void )
{
  printf( "Hello proggen.org\n" );
 
  return 0; 
}

Der Aufbau einer Quellcodedatei

Eine Quellcodedatei wird in der Regel so aufgebaut, dass am Kopf des Quelltextes sogenannte Headerfiles (Kopfdateien) mit dem Befehl #include eingebunden werden. Das ist ein Präprozessor-Befehl, welcher ausgeführt wird, bevor der Compiler den eigentlichen Quelltext übersetzt. Im Prinzip wird hier der Inhalt der Datei stdio.h an diese Stelle einkopiert und der Text zusammen mit dem Quelltext vom Compiler gelesen:

#include <stdio.h>

Die spitzen Klammern sagen dem Compiler, dass er die Datei stdio.h ausschließlich in den ihm bekannten Pfaden suchen soll, nicht aber im aktuellen Verzeichnis. Möchte man eine eigene Headerdatei inkludieren, so verwendet man doppelte Anführungszeichen. Dadurch wird zuerst im aktuellen Verzeichnis gesucht, dann erst in den dem Compiler bekannten Inkludeverzeichnissen.

#include "stdio.h"

Da wir hier aber definitiv keine eigene Datei einbinden wollen, nutzen wir besser die spitzen Klammern.

In der Datei stdio.h befinden sich Deklarationen, die zusätzliche Funktionen beschreiben, die der C-Compiler von sich aus gar nicht kennt. stdio ist die Kurzschreibweise für „Standard Input/Output“, also Standard-Funktionen für die Standard-Ein- und -Ausgabe. Das Programm soll einen Text ausgeben und daher benötigen wir die Deklaration für die Funktion printf(). Diese kennt der Compiler von sich aus aber nicht und die Deklaration erklärt dem Compiler, dass die Funktion printf() tatsächlich existiert. Die Programmiersprache C ist äußerst klein gehalten, selbst Funktionen zur Ausgabe sind im Sprachkern nicht enthalten und müssen dem Compiler erst erklärt werden. Dafür bindet man die stdio ein, die grundlegende Funktionen zur Ein- und Ausgabe enthält.

Anschließend folgen die einzelnen Funktionen, die in diesem Quelltext dem Compiler erklärt werden.

Datentypen und Funktionen

Für einen Computer existieren nur Daten. Daten können Zahlen oder Texte sein - wobei Texte im Prinzip auch nur Zahlen sind, die als Buchstaben interpretiert werden. Zusätzlich gibt es noch ausführbaren Code - was letztendlich auch wieder Zahlen sind, die als ausführbarer Code interpretiert werden.

Hier lernen wir C, das uns hilft, Daten unterschiedlicher Bedeutung zu unterscheiden. Wir beschreiben vom Computer ausführbaren Code, der Daten verarbeitet. Wenn wir ausführbaren Code schreiben, dann treffen wir Entscheidungen, fordern den Computer auf Dinge wiederholt durchzuführen oder wir fassen derartige Entscheidungen, Wiederholungen und Aufforderungen zusammen und geben dem Kind einen Namen: Damit haben wir eine Funktion.

In unserem Quelltext gibt es eine Funktion, die main heißt. Die Deklaration der Funktion lautet:

int main( void )

Eine Deklaration sieht in C immer so aus, dass der Datentyp angegeben wird, der beschreibt, wie die zurückgegebenen Zahlen zu verstehen sind (hier int, also eine ganze Zahl). Dem folgt ein Identifier, also der Name. Folgt dem Identifier anschließend eine runde, öffnende Klammer, so wird hier eine Funktion deklariert. Zwischen öffnender und schließender runder Klammer befinden sich die Deklarationen für Übergabeparameter. Hier wird nichts übergeben - dafür schreibt man void (Englisch für „leer“) oder lässt die Klammern einfach leer.

Einer Funktions-Deklaration folgt entweder ein Semikolon:

int main( void );

oder, wenn die Funktion gleich definiert wird eine öffnende, geschweifte Klammer:

int main( void )
{
  // das Programm
}

Zwischen den Klammern werden die Anweisungen für diese Funktion geschrieben. Der Unterschied zwischen Deklaration und Definition ist, dass bei einer Deklaration (Semikolon am Ende) nur behauptet wird, dass es die Funktion gibt. Bei einer Definition (gefolgt von dem Paar geschweifter Klammern) wird die Funktion deklariert und gleichzeitig beschrieben, was sie tun soll.

Was sie tun soll steht also zwischen den geschweiften Klammern. Bei unserem Programm ist das

  printf( "Hello proggen.org\n" );
 
  return 0; 

Der erste Befehl ist der Aufruf einer anderen Funktion, nämlich printf(), die in dem Standard-Eingabe-Ausgabe-Header dem Compiler erklärt wird. printf() erhält einen kurzen Text - nämlich den, den es auf den Bildschirm drucken soll - also hat printf() offenbar eine Funktions-Deklaration, die statt void etwas anderes in den runden Klammern der Deklaration stehen hat. Was genau und wie man damit umgeht, erfahren wir bald.
Der Text lautet „Hello proggen.org\n“.
Mit dem Backslash ('\') erklärt man dem Compiler, dass nun ein besonderes Zeichen kommt und das nachfolgende Zeichen beschreibt welches. Es werden also zwei Buchstaben benötigt, um ein Zeichen zu beschreiben. Den Backslash nennt man daher auch „Escape-Zeichen“, also ein Zeichen, was aus dem normalen Text ausschert und eine sogenannte „Escape-Sequenz“ einleitet. In diesem Fall handelt es sich immer nur um ein Zeichen. Das hier verwendete 'n' steht für Newline. Nachdem also „Hello proggen.org“ ausgegeben wurde, wird an den Anfang der nächsten Zeile gewechselt.

Anschließend wird mit dem letzten Befehl return der Wert 0 zurückgegeben. Wir erinnern uns, dass in der Deklaration der Funktion gesagt wird, dass die Funktion einen Wert vom Datentyp int, also eine ganze Zahl, zurückgibt und diese Funktion gibt eine 0 zurück. Damit endet der Anweisungsblock und das Programm kehrt zu der Funktion zurück, die die Funktion main gerufen hat - also dem Betriebsystem, das das Programm gestartet hat.
Anweisungen, die hinter return stehen werden nicht mehr ausgeführt, da return die Ausführung der Funktion an dieser Stelle unterbricht, um zur rufenden Funktionen zurück zu kehren.

Die Funktion main

Die Funktion main() ist etwas besonderes, denn sie markiert in einem C-Programm den Startpunkt, ganz egal, ob es ein kleines Programm wie unser bisheriges Beispielprogramm ist, oder ein Programm von der Größe einer Textverarbeitung, eines Ego-Shooters oder einer Bildverarbeitung. Alle Programme starten mit ihrer eigenen Implementation der Funktion main(). Beim Start des Programms wird das Programm geladen und das Betriebssystem ruft die Funktion main() auf, genauso wie unsere main-Funktion die printf()-Funktion aufruft.

main gibt grundsätzlich einen Integer-Wert zurück, um dem Betriebssystem den Hinweis zu geben, ob das Programm erfolgreich abgelaufen oder etwas schief gegangen ist. Gibt man als Programmierer den Wert 0 zurück, teilt man dem Betriebssystem mit, dass das Programm erfolgreich abgelaufen ist.

Ziel dieser Lektion

Du solltest nun in der Lage sein, das Hello proggen.org-Programm zu verstehen. Weiterhin kannst Du die Ausgabe ändern, das Programm erneut kompilieren und auszuführen. Versuche mehrere printf()-Aufrufe innerhalb des Anweisungsblocks und platziere sie vor der return-Anweisung und ruhig auch mal dahinter.

In der nächsten Lektion beschäftigen wir uns mit Ausdrücken.