1. Einführung

1.1. Die Geschichte der Sprache

Die Programmiersprache C wurde im wesentlichen Anfang der 70er Jahre von Dennis Ritchie an den Bell Laboratorien entwickelt. Die Entwicklung hing eng mit der Entwicklung von UNIX zusammen. Die Ursprünge von C können zurückverfolgt werden von ALGOL 60 (1960) über Cambridge's CPL (1963) und Martin Richards’s BCPL (1967) bis hin zu Ken Thompson’s B (1970). Die Sprachen BCPL und deren Nachfolger B waren beide noch sehr assemblernah. UNIX wurde 1970 zunächst noch in B entwickelt, aber die Version 6, die als Betriebssystem 1973 in Betrieb genommen wurde, war weitgehend in C geschrieben. 1978 haben Brian W. Kernighan und Dennis Ritchie das Buch „The C Programming Language“ und damit die erste offizielle Beschreibung der Programmiersprache veröffentlicht; daher wurde die Sprache auch häufig K&R C genannt.

Erst 16 Jahre später (1989) wurde vom American National Standards Institute (ANSI) der erste Standard veröffentlicht, der als ANSI-C bzw. auch Standard-C bezeichnet wurde (wird heute auch als C89 bezeichnet). Ein Jahr später übernahm die International Organization For Standardization (ISO) diesen bis dahin rein amerikanischen Standard als internationale Norm und nannte dies C90. Allerdings bezeichnen C89 und C90 den gleichen Standard. 1995 wurden an diesem Standard einige kleine Korrekturen und Erweiterungen vorgenommen; dieser Standard wird "C89 with Amendment 1" (C89 mit Verbesserungen 1) oder kurz C95 genannt. Auch dieser Standard wurde noch einmal gründlich korrigiert und erweitert; dabei entstand 1999 das C99. In diesem Standard sind einige Erweiterungen übernommen worden, die bereits 1993 mit C++ eingeführt wurden. Im weiteren Verlauf der Jahre wurden weitere Korrekturen und Erweiterungen veröffentlicht: Im Dezember 2011 kam C11 mit einer besseren Kompatibilität mit C++ und im Juni 2018 der Standard C18.

Dieses Skript bezieht sich - sofern nicht explizit angegeben - immer auf den C89-Standard.

1.2. Struktur eines C-Programms

Ein Programm besteht aus mehreren Teilen, die in einer oder in verschiedenen Dateien stehen können. Dabei wird im allgemeinen die angegebene Reihenfolge eingehalten.

  • Compiler-Instruktionen, dies sind alle Befehle, die mit einem # beginnen, sie werden auch Präprozessor-Befehle genannt (z.B. #include). Die Präprozessor-Befehle werden in einem späteren Kapitel behandelt.

  • Deklaration von globalen Objekten

  • Funktionsprototypen (Deklaration von Unterprogrammen bzw. von Funktionen)

  • Hauptprogramm int main()

  • Funktionsdefinitionen (Quelltext der Unterprogramme bzw. der Funktionen)


1.3. Das erste einfache Programm

Der erste Schritt in der Programmentwicklung ist immer die Zerlegung des ganzen Problems in kleine Teilprobleme. Diese lassen sich entweder leicht lösen oder in weitere Teilprobleme zerlegen. Jedes Teilproblem wird gelöst und erst einmal in der Umgangssprache formuliert. Als Beispiel nehmen wir mal die Summenberechnung aus zwei Zahlen. Die umgangssprachliche Formulierung lautet dann: Lies die zwei Zahlen a und b von der Tastatur ein. Dann berechne die Summe beider Zahlen. Zum Schluß gebe das Ergebnis auf dem Bildschirm aus. Dieses Umsetzen vom Problem in eine umgangssprachliche Lösung ist der schwierigste Teil beim Programmieren. Das anschließende Übersetzen in die Programmiersprache ist dagegen fast wieder einfach.

Unser erstes Programm beinhaltet nur Kommentare; passieren tut noch nichts.

kap01_01.c

01 int main()
02 {
03    /* Lies die Zahlen a und b ein              */
04    /* Berechne die Summe von a und b           */
05    /* Gebe das Ergebnis auf dem Bildschirm aus */
06    return 0;
07 }

Dabei haben die einzelnen Zeichen/Zeilen folgende Bedeutungen:

int

Rückgabewert des Hauptprogramms ist eine ganze Zahl; im allgemeinen wird damit ein Fehlercode an das Betriebssystem zurückgegeben

main

Schlüsselwort für das Hauptprogramm

()

innerhalb dieser runden Klammern können dem Hauptprogramm Informationen, sogenannte Parameter, mitgegeben werden

{   }

Anweisungsblock, innerhalb dieser geschweiften Klammern stehen die Anweisungen an den Rechner

/* ... */

Kommentarblock, kann auch über mehrere Zeilen gehen

return 0;

Hauptprogramm beenden und Fehlercode 0 (d.h. kein Fehler) zurückgeben

Kommentare werden vom Compiler (das ist ein Programm, das den Programmtext in eine rechnerverständliche Form, d.h. Maschinensprache, übersetzt) vollständig ignoriert. Ein Kommentar, der mit /* ... */ eingeschlossen ist, kann sich auch über mehrere Zeilen erstrecken. Kommentare sind für den Leser und auch für den Autor sehr wichtig. Sie erläutern die Parameter, die Voraussetzungen sowie die Funktionsweise des Programms. Wird in einem Team programmiert, sind auch Änderungsdatum und Name des Autors wichtig.

  • Der Programmtext selber ist eine reine Textdatei, die mit jedem Texteditor bearbeitet werden kann.

  • Es gibt Schlüsselworte (z.B. main), die grundsätzlich klein geschrieben werden (mit einigen Ausnahmen). Generell wird zwischen Groß- und Kleinschreibung unterschieden!

  • Die Zeilenstruktur ist für den Compiler unwichtig. Nur für die Lesbarkeit sollte eine gewisse Struktur eingehalten werden. Auch Leerzeilen sind für die Lesbarkeit sehr wichtig. Mit ihnen lassen sich logische Abschnitte voneinander trennen.

Im nächsten Schritt werden die Anweisungen für das obige Problem eingefügt, für das wir bereits eine umgangssprachliche Lösung entwickelt hatten. Dabei wird jede Anweisung (außer den Präprozessorbefehlen) mit einem Semikolon beendet.

kap01_02.c

01 #include <stdio.h>
02
03 int main()
04 {
05    int a, b, summe;
06
07    /* Lies die Zahlen a und b ein              */
08    printf("Geben Sie bitte zwei ganze Zahlen ein:");
09    scanf("%i %i", &a, &b);
10
11    /* Berechne die Summe von a und b           */
12    summe = a + b;
13
14    /* Gebe das Ergebnis auf dem Bildschirm aus */
15    printf("Summe: %i", summe);
16
17    return 0;
18 }

Folgendes ist jetzt neu hinzugekommen:

#include <stdio.h>

Einbinden der Ein-/Ausgabefunktionen. Diese Zeile muss in jedem Programm stehen, das Eingaben von der Tastatur erwartet (Funktion scanf) oder Ausgaben auf den Bildschirm bringt (Funktion printf). Die Datei stdio.h wird auch Headerdatei genannt.

int a, b, summe;

Deklaration und Definition von Variablen vom Typ "int" ("integer", ganze Zahlen). Der Compiler stellt daraufhin für die Variablen entsprechenden Speicherplatz zur Verfügung. Ab hier kennt der Compiler die drei Variablen. Mit Hilfe der Variablennamen kann auf die Werte der Variablen zugegriffen werden.

printf

printf ist die Standardausgabe auf dem Bildschirm. In Klammern wird der Text in Anführungsstrichen angegeben, der auf dem Bildschirm ausgegeben werden soll.

scanf

scanf ist die Standardeingabe von der Tastatur. In Klammern wird zuerst das Eingabeformat in Anführungsstrichen angegeben ("%i %i", d.h. es sollen zwei ganze Zahlen eingelesen werden), dahinter ein Verweis auf die Variable, die den eingegebenen Wert aufnehmen soll (&a). Für diese Verweis wird vor dem Variablennamen ein kaufmännisches Und (&) gesetzt. Sollen mit einem scanf-Befehl Werte für mehrere Variablen eingelesen werden, so müssen die Verweise auf die Variablen mit Kommata getrennt werden.

=

Zuweisung: Der Variablen auf der linken Seite (l-value bzw. L-Wert) des Gleichheitszeichens wird das Ergebnis des Ausdrucks auf der rechten Seite zugewiesen.

"Text"

beliebige Zeichenkette (im englischen: string), die die Anführungszeichen selbst nicht enthalten darf. Wenn die Zeichenkette die Anführungszeichen enthalten soll, sind sie als \" zu schreiben.

;

beendet jede Deklaration und jede Anweisung

Damit haben wir bereits das erste Programm geschrieben.



Inhaltsverzeichnis