peace software
  Berndt Wischnewski  Richard-Wagner-Str. 49  10585 Berlin 
  Tel.: 030 - 3429075  FAX : 030 34704037  email: webmaster@peacesoftware.de  Ust-ID: DE135577379 

<= Previous

 

C Kurs - hello.c revisited

1. Header Files

Sie erinnern sich an Ihr erstes C Programm

#include <stdio.h>
int main(void)
{
   printf("hello world");
  return 0;
}

In der ersten Zeile steht:

#include <stdio.h>

#include bedeutet, hier wird etwas eingefügt und zwar der Inhalt der Header Datei stdio.h . Header Dateien erkennt man an der Endung ".h". Stellen Sie sich einfach vor, hier würde mit Copy & Paste der Inhalt der Datei stdio.h eingefügt werden. Muß #include am Anfang des Programmes stehen? Im Prinzip nicht, es könnte überall stehen, aber vor der ersten Benutzung einer Funktion oder Variablen aus einem Header File müssen deren Definitionen "included" sein. Deshalb stehen die #include Anweisungen meist doch am Anfang eines Programmes oder Programmteiles.

Was sind Header Files im allgemeinen und stdio.h im speziellen?
Header Files dürfen alles enthalten (außer Syntaxfehlern), sollten es aber nicht. Der Sinn von Header Files ist es, globale Definitionen oder Deklarationen für andere Programmteile zur Verfügung zu stellen. Niemand hindert Sie jedoch daran, selbst geschriebene Funktionen in ein Header File zu stecken, wenn Sie sich selbst und andere verwirren wollen bitte gerne. Das Header File stdio.h , die Abkürzung von Standard-In-Out, enthält die Deklarationen und Definitionen für

  • das Anlegen, Öffnen, Schreiben, Lesen, Überschreiben, Anfügen und Löschen von Files
  • die Standard Eingabe über die Tastatur
  • die Standard Ausgabe von Text auf dem Bildschirm.
In unserem Miniprogramm wird printf - die formatierte print-Anweisung für das Ausgeben von "hello world" auf dem Bildschirm, benutzt. Durch das Einfügen von stdio.h in unser File, "kennt" der Compiler anschließend die Funktion printf und wenn die richtige Library gelinkt wird, kann er sie auch ausführen. C ist de fakto standardisiert, jeder Hersteller eines C Compilers liefert einen Satz Standardheader Files und die dazugehörigen Libraries. Außer stdio.h gibt es noch etwa 30 andere, einige werden wir uns später näher ansehen.

Die spitzen Klammern < .. > bedeuten, es handelt sich um eine Standard Header Datei, die der Compiler kennt und von der er weiß wo sie liegt.Wenn Sie selber eigene Header Dateien kreieren, würden die ersten Zeilen vielleicht so lauten:

#include <stdio.h>
#include "meinHeader.h"

usw...

der Compiler wird dann in dem Pfad, wo sich Ihr Programmquelltext, hello.c befindet, nach meinHeader.h suchen.

Warum und wann soll ich eigene Header Files anlegen?
Niemand zwingt Sie, eigen Header Files zu schreiben, ab einer bestimmten Programmgröße wird es jedoch übersichtlicher zusammengehörige Teile eines Programmes in separaten C Files abzulegen. Wann das sinnvoll wird, ist Geschmackssache. Ich finde, für mich ganz individuell, wenn das Programm so 1000 bis 2000 Zeilen lang ist und noch kein Ende in Sicht, fange ich an es zu modularisieren. Ich kenne jedoch Programmierer die ihre Programme von Anfang an und in jedem Fall modular aufbauen. Ich kenne auch einen Deppen, der sich strikt weigerte seine Programme in Teile zu zerlegen, ich sage aber hier seinen Namen nicht. Diese Module, mehrere *.C Files, importieren gemeinsame globale Variablen und Funktions-Deklarationen über Header Files und geben ihre Funktionen anderen C Files über eigene Header Files weiter. Wie solch ein Verwaltung aufgebaut ist sehen wir später. Im Prinzip wird eine Modularisierung dann sinnvoll, wenn die Suche nach zusammenhängenden Teilen in einem großen File lästiger wird, als sich um den Overhead einer Zerlegung in mehrere C Files zu kümmern.

Programmiert man an größeren Softwareprojekten zusammen mit mehreren anderen Programmierern, wird in lustigen meetings die Struktur der Header Files festgelegt. Hier kann man prima seinem Ego freien Lauf lassen und die von einem selber bevorzugten Namenskonventionen mit Vehemenz gegen die abstrusen Vorschläge der anderen Gruppenmitglieder verteidigen. Natürlich gibt es dann auch immer einige, die beim meeting gerade nicht konnten und dann trotzdem die alten Namensregeln weiter pflegen, woraufhin dann neue meetings angesetzt werden...

 

2. Die Funktion main

Die zweite Zeile unseres Programmes lautet:

int main(void)

Die Funktion main ist der Anfangspunkt unseres Programmes. Ab hier geht es los. jedes ausführbare C Programm hat eine main Funktion. Gibt es auch nicht-ausführbare C Programme? Ja klar, z. B. Libraries, Hardware Treiber usw.. Diese werden von anderen Programmen aufgerufen und ausgeführt und enthalten keine main Funktion. Dies bedeutet auch das main ein reserviertes Key-Wort ist, es ist strikt verboten eine eigene Funktion oder Variable main zu nennen.

Was ist eigentlich eine Funktion?
Eine Funktion ist ein zusammengehörender eigenständiger Teil eines Programmes. Funktionen können von anderen Orten des Programms aufgerufen werden. Sie können sich übrigens auch selber aufrufen, das nennt man dann "Rekursion". Wann ist es sinnvoll Funktionen zu programmieren? Am einleuchtensten ist es, bei sich im Programm wiederholenden Teilen. Ein typisches Beispiel sind die in der MathLibrary gesammelten Funktionen wie z. B. y =  sin(x) etc.. Aber auch zum modularisieren des Programmes ist es sinnvoll Funktionen einzuführen. Eine alte Faustregel sagt, wenn der Code länger als eine DIN A4 Seite wird, sollte man ihn in wegen der Übersichtlichkeit in zwei Funktionen aufteilen, man muss sich aber nicht daran halten.

Funktionen haben einen Namen, einen Rückgabewert (immer, anders als in Pascal wo procedure eine Funktion ohne Rückgabewert bedeutet) und eine Liste von Eingabe Variablen. Wenn eine Funktion "nichts" ausgeben wird, dann gibt sie "void" zurück, dies muss aber deklariert werden. Void bedeutet "nichts". In unserem Falle der main-Funktion.

int main(void)
{
..
}

wird von der Funktion ein int - ein Integer Wert, eine ganze Zahl - ausgegeben int main(void),

und nichts geht in die Funktion hinein int main(void) .

Nach dem Funktionskopf (function head), int main(void) kommt der in geschweiften Klammern {..} der Funktionsrumpf(body of function), in dem die eigentliche Arbeit passiert. Funktionen in die nichts hineingeht und aus denen nichts herauskommt, z.B. void myFunction(void), können also trotzdem etwas ausführen, nämlich das, was in ihrem Funktionsrumpf steht.

 

Namensregeln für Funktionen und Variable:

  • eine C Funktion oder Variable beginnt mit einem Buchstaben oder "_" dem Underscore-Zeichen
  • Namen von C Funktionen oder Variablen dürfen dann weiterhin Buchstaben, Zahlen und den "_" Underscore enthalten. Alles andere Sonderzeichen, Umlaute etc ist verboten.
  • Der Name der Variablen darf sich nicht mit einem C Schlüsselwort decken, z.B. main ist als Variablenname verboten
  • Namen sind "case-sensitiv" also Groß- und Kleinschreibung beachten.
  • Die maximale Länge des Namens ist abhängig vom Compiler, meistens jedoch 256 Zeichen.
  • Alles andere ist Ihre Sache, Sie können Ihre Variable natürlich 'dies_ist_meine_Sonntags_Nachmittags_lieblings_Variable' nennen, zu sinnvollen, freiwilligen Regel für die Namensgebung von Funktionen und Variable kommen wir später.

 

3. printf("hello world");

Innerhalb des Rumpfes der main Funktion stehen zwei Anweisungen: 1.

   printf("hello world");

Hier erfolgt ein Aufruf der printf Funktion, einer C Standardfunktion zur formatierten Ausgabe.Der Rückgabewert wird nicht ausgewertet. Welcher Rückgabewert? Nun man könnte auch X = printf("hello world"); schreiben, aber haben wir nicht gemacht. Warum? Nun der Rückgabewert interessiert uns einfach nicht. Als Eingabevariable für die printf Funktion wird der String, was das ist kriegen wir später, ""hello world" eingefügt.Am Ende steht ein Semikolon ";". damit ist Funktionsaufruf von printf abgeschlossen.

und 2.

   return 0;

Hier wird die main Funktion angewiesen, etwas zurückzugeben, nämlich Null. Zurückgegeben an wen? Na an den, der die Funktion aufruft. Wer ruft unser main denn auf? das Betriebssystem Ihres Computers ruft main auf, indem Sie hello.exe starten. Warum muss main denn einen Wert an das Betriebssystem zurückgeben? Unter den meisten Betriebssystemen kann man so etwas wie Shell Skripte oder Batch Dateien schreiben, in denen natürlich auch selbst geschriebene C Programme aufgerufen werden können. Hier kann man an die Rückgabewerte der aufgerufenen Programme dann auswerten.

   return 0;

bedeutet immer "alles OK, Programm fehlerfrei beendet".

<= Previous











Einige gute C Lernbücher von Erlenkötter und Wolf: