Dies ist eine ältere Version dieses Textes.

Die neuste Version ist auf http://www.eggdrop.ch/texts/c/index.htm verfügbar!

 

Einführung in C

Version 0.1

Inhalt

 

1 Einleitung
1.1 Was ist C?
1.2 Was kann man mit C alles schreiben?
1.3 Und was ist mit C++?
1.4 Was brauche ich zum Programmieren?
1.5 Anmerkungen
2 Hallo, Welt!
2.1 Code
2.2 Funktionen
2.3 Anweisungen
2.4 Struktur eines C-Programms
2.5 Steuerzeichen
2.6 Kommentare
3 Variablen
3.1 Was sind Variablen?
3.2 Ein Variablentyp: int
3.3 Formatierte Ausgabe mit printf
3.4 Rechnen mit Operatoren

 

1 Einleitung

1.1 Was ist C?
C ist eine Programmiersprache, die Anfang der 70er Jahre von Dennis Ritchie in den Bell Labs entwickelt wurde, um das Betriebssystem UNIX unabhänging von der Hardware zu schreiben. C ist sehr mächtig, flexibel und portabel, läuft also auf fast jeder Architektur. C ist heute eine der am meisten verbreiteten Programmiersprachen. Damit C-Programme überall ohne grosse Modifikationen laufen, wurde der sogenannte ANSI-C-Standard eingeführt. ANSI-C-Programme lassen sich auf jedem ANSI-C-Compiler unverändert kompilieren.

1.2 Was kann man mit C alles schreiben?
In C ist alles möglich: Grafische Oberflächen (GUI's), Berechnungsprogramme, Datenbanken, 2D und 3D Spiele, Betriebsysteme, Simulationen, Internetanwendungen und viel mehr! Dem Programmierer sind in C keine Grenzen gesetzt.

1.3 Und was ist mit C++?
C++ ist nichts anderes als ein erweitertes C. Alles was in C erlaubt ist geht auch mit C++. C++ enthält Zusätzliches für die objektorientierte Programmierung und ist somit etwas komplizierter als C. Wer C kann, kann ohne weiteres C++ lernen.

1.4 Was brauche ich zum Programmieren?
Zuerst braucht man einen Editor, wo man den C-Code eingeben kann. Theoretisch ist jeder Editor möglich, empfehlenswert ist aber einer, der den C-Code farbig hervorhebt. Ich persönlich benutze den Unix-Editor vim, der mit dem Befehl :syntax on den C-Code hervorhebt und auch automatisch einrückt. Wenn man einen Editor hat, benötigt man einen C-Compiler, um aus dem C-Code eine ausführbare Datei zu erstellen. C-Compiler gibt es auch genug. Ich verwende unter Linux den Compiler gcc, der meistens schon standardmässig dabei ist. Für Windows gibt es z.B. den freien Compiler lcc und mehr (in einer Suchmaschine z.B. windows c compiler eingeben). Alternativ zu einem Editor und einem Compiler kann man auch eine komplette Entwicklungsumgebung verwenden. Die bekanntesten für Windows sind Visual C++ und Borland C++ Builder. Diese unterstützen sowohl C, als auch C++. Wie man den Editor bedient und die Dateien kompiliert, erfährst du in den dazugehörigen Handbüchern usw. Für gcc-Fans sag ich doch noch schnell den Aufruf, um eine Datei zu kompilieren: gcc -o datei datei.c und Ausführen mit ./datei.

1.5 Anmerkungen
Begriffe, die du dir merken solltest, werden Kursiv gekennzeichnet.

 

2 Hallo, Welt!

2.1 Code
Wir fangen gleich mit einem einfachen Programm an. Das Programm soll uns die Zeichenfolge "Hallo Welt" auf den Bildschirm ausgeben. Hier schon mal der Quellcode:

#include <stdio.h>

int main(int argc, char *argv[])
{
	printf("Hallo, Welt!\n");
	return 0;
}

Tippe den Quellcode in deinen Editor bzw. deine Entwicklungsumgebung ein und speichere ihn z.b. unter hello.c. C-Dateien haben grundsätzlich die Dateiendung .c. Kompilier das Programm und führe es aus (unter Windows in einer DOS-Box). Wenn sich das Programm nicht kompilieren lässt, dann überprüf noch einmal den Quellcode auf Schreibfehler: z.B. vergessene Abstände oder Semikola (;) usw. Beachte auch, dass C Gross- und Kleinschreibung unterscheidet. Ich werde das Programm nun in den nächsten Abschnitten beschreiben. Anmerkung: Die nächsten zwei Abschnitte sind die schwierigsten und die wichtigsten in diesem Kapitel. Also nicht sofort aufgeben, lieber mehrere male lesen!

2.2 Funktionen
Wir fangen mit der Zeile int main(int argc, char *argv[]) an. Diese Zeile deklariert eine Funktion. Die Befehle der Funktion werden in den geschweiften Klammern { und } - man nennt das Block oder Anweisungsblock - geschrieben. Jede Funktion hat einen Rückgabewert, der mit return zurückgegeben wird. Eine Funktion sieht so aus:

Typ Name(Argumente)
{
	Befehle;
	return Wert;
}

Typ: Das ist der Typ des Rückgabewerts. main gibt immer den Typ int zurück. int-Werte sind ganze Zahlen. Auf diese Datentypen werde ich später noch zurückkommen.

Name: Wir sehen hier, dass der Name unserer Funktion main ist. Diese Funktion wird beim Aufrufen des Programms immer zuerst aufgerufen. Man kann beliebig viele andere Funktionen mit (fast) beliebigen Namen machen. Diese Funktionen kann man dann aus der Funktion main oder aus anderen Funktionen aufrufen.

Argumente: Jede Funktion kann Argumente haben. Die Argumente werden durch Kommas voneinander getrennt. Die Funktion main hat die Argumente int argc und char *argv[]. Eigene Funktionen können eigene Argumente haben. Auf die Argumente von Funktionen wird aber erst später eingegangen.

Befehle: Hier kommt der eigentliche Code der Funktion hin.

Wert: Das ist jetzt eben Rückgabewert. In der Funktion main verwendet man immer den Rückgabewert 0 (Null), wenn das Programm korrekt beendet wurde. Bei einem Fehler verwendet man meistens 1.

2.3 Anweisungen
Im Anweisungsblock der Funktion main befinden sich folgende Anweisungen:

	printf("Hallo, Welt!\n");
	return 0;

Hier möchte ich festhalten, dass jede Anweisung mit einem Semikolon (;) endet. Ausnahme bilden die Anweisungen, denen ein Adressblock folgt. Doch zu denen später mehr. Das vergessene Semikolon ist einer der häufigsten Fehler von C-Programmierern. Die Anweisung return kennen wir ja bereits schon. Sie gibt den Rückgabewert der Funktion zurück. Ausserdem sollte man wissen, dass sie eventuelle Anweisungen danach nicht mehr ausführen wird. Im folgenden Beispiel würde der Text "Hallo Welt" nicht ausgegeben werden:

#include <stdio.h>

int main(int argc, char *argv[])
{
	return 0;
	printf("Hallo, Welt!\n");
}

Nun zur Anweisung printf. Sie ähnelt ein bisschem einem Funktionskopf, da hinter dem Namen runde Klammern sind - genau wie bei einer Funktion auch. Sie hat aber ein Semikolon am Schluss und befindet sich innerhalb einer Funktion (es gibt keine verschachtelten Funktionen innerhalb von Funktionen). Es ist ein Funktionsaufruf. Diese Anweisung ruft die Funktion printf auf mit dem Argument "Hallo, Welt!\n" auf. Nun, wo befindet sich diese Funktion? Wir haben im Code keine Funktion mit dem Namen printf. Lösung: Sie befindet sich in der Datei stdio.h. Diese Datei wird mit dem Compiler mitgeliefert. Und die erste Zeile (#include <stdio.h>) bewirkt, dass diese Datei mit eingebunden wird. Diese Zeile nennt man Präprozessordirektive. Man erkennt eine Präprozessordirektive daran, dass sie mit einem # beginnt. Vor dem Kompilieren werden diese Befehle durch den Präprozessor abgearbeitet und dann zum eigentlichen C-Compiler geschickt. Die Anweisung #include wird durch den Inhalt der angegebenen Datei ersetzt. Wird der Dateiname bei #include in spitzen Klammern (< und >) angegeben, dann wird im sogenannten Include-Verzeichnis vom Compiler diese Datei gesucht (das ist bei stdio.h der Fall). Wird der Name aber in Anführungszeichen angegeben (z.B. #include "test.h"), dann wird zuerst im Verzeichnis, wo sich das Programm befindet, gesucht und erst dann, wenn nichts gefunden wurde, im Include-Verzeichnis. So kann man eigene Dateien (sogenannte Header-Dateien) einbinden. Zu beachten ist, dass Header-Dateien gewöhnlich die Endung .h haben.

Der letzte Abschnitt zusammengefasst: Die Funktion printf wird mit dem Argument "Hallo Welt\n" aufgerufen. Ich denke ich muss gar nicht erklären, dass diese Funktion Text auf den Bildschirm schreibt. Der Text (eine Zeichenfolge oder String) wird in C immer in Anführungszeichen angegeben. Was ich vielleicht noch erklären muss, ist das \n am Schluss der Zeichenfolge. Das ist ein sogenanntes Steuerzeichen. Steuerzeichen beginnen immer mit einem Backslash (\). Das Steuerzeichen \n macht eine neue Zeile. Beispielsweise erzeugt printf("Dieser Text\nerstreckt\nsich\n\n über mehrere Zeilen\n"); folgende Ausgabe:

Dieser Text
erstreckt
sich

 über mehrere Zeilen

Man könnte das obere Programm auch auf mehrere printf-Anweisungen verteilen:

printf("Dieser Text\n");
printf("erstreckt\n");
printf("sich\n\n");
printf(" über mehrere Zeilen\n");

2.4 Struktur eines C-Programms
In der Programmiersprache C hat man eine grosse Freiheit in der Struktur des Programms. Das heisst, man könnte das obige Programm auch so schreiben:

#include <stdio.h>
int main(int argc,char *argv[]){printf("Hallo, Welt!\n");return 0;}

oder auch mit Leerzeichen und Tabulatoren so "aufpeppen":

			#include         <stdio.h>
	int
main(


int argc
,
char *argv[   ]
) { printf  ("Hallo, Welt!\n"
)
;		return 0;}

Bei diesen zwei Beispielen leidet jedoch stark die Übersichtlichkeit. Also schreibe den Code am besten immer so, wie er hier geschrieben wird. Folgende Regeln muss man noch beachten:

2.5 Steuerzeichen
Hier werde ich auf die Steuerzeichen noch genauer eingehen. Wir kennen ja schon das Steuerzeichen \n, welches eine neue Zeile erzeugt.
 
Zuerst eine Tabelle der wichtigsten Steuerzeichen:

Steuerzeichen Beschreibung
\a Gibt ein akustisches Signal aus
\b Setzt den Cursor um eine Position nach links
\f Erzeugt einen Seitenvorschub beim Drucken
\n Setzt den Cursor an den Anfang der nächsten Zeile
\r Setzt den Cursor an den Anfang der aktuellen Zeile
\t Setzt den Cursor zur nächsten horizontalen Tabulatorposition. Meistens wird alle 8 Zeichen ein Tabulator gesetzt.
\v Setzt den Cursor zur nächsten vertikalen Tabulatorposition.
\" Gibt das Anführungszeichen (") aus.
\nnn Gibt ein Zeichen mit dem Oktalwert (Basis 8) nnn aus.
\xnn Gibt ein Zeichen mit dem Hexadezimalwert (Basis 16) nn aus. Folgende Ziffern werden dazu verwendet:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A (10), B (11), C (12), D (13), E (14), F (15)

Hier einige Beispiele zu den Steuerzeichen:

Gibt den Text "Ungütige Eingabe" aus und piepst:

printf("Ungültige Eingabe!\n\a");

Gibt eine Tabelle aus (am besten selber mal kompilieren):

printf("\tA\tB\tC\tD\tE\n");
printf("1\tA1\tB1\tC1\tD1\tE1\n");
printf("2\tA2\tB2\tC2\tD2\tE2\n");
printf("3\tA3\tB3\tC3\tD3\tE3\n");

Hier die Tabelle, die ausgegeben wird:

        A       B       C       D       E
1       A1      B1      C1      D1      E1
2       A2      B2      C2      D2      E2
3       A3      B3      C3      D3      E3

2.6 Kommentare
Kommentare werden vom Compiler ignoriert und dienen also nur den Programmierern, um den Code einfacher zu lesen und verstehen. Kommentare sind immer sinnvoll, vor allem bei grösseren Projekten, wenn mehrere Leute zusammenarbeiten. Durch Kommentare können auch Anfänger komplexe Programme besser verstehen. In C gibt es zwei Typen von Kommentaren:

Der C-Style Kommentar beginnt mit einem /* und endet mit einem */. Er kann sich über mehrere Zeilen erstrecken. Wenn man einmal mehrere Zeilen schnell rausnehmen will, eignet sich dieser Kommentar am besten, weil man am Anfang der ersten Zeile ein /* setzen kann und am Ende der letzten Zeile ein */. Ich bevorzuge diesen Kommentar. Achtung: Dieser Kommentartyp darf nicht verschachtelt werden. Die Zeile /* Kommentar /* FALSCH! */ */ gäbe einen Fehler

Der C++-Style Kommentar heisst C++, weil er ursprünglich nur in C++ erlaubt war. Er ist aber seit dem ANSI C99-Standard (seit 1999) auch in C erlaubt. Ältere Compiler können unter Umständen Fehlermeldungen ausgeben. Der Kommentar beginnt mit // und endet am Ende der Zeile.

Ein Kommentar ist nicht in einem String gütig.

Hier ein Beispiel mit beiden Kommentar-Typen:

/* bindet die Header-Datei stdio.h für printf ein */
#include <stdio.h>

int main(int argc, char *argv[]) // Hauptfunktion
{
	// gibt eine Zeile aus
	printf("Das ist ein Text. /* Das ist auch ein Text. */ // Das auch\n");
	// Kommentar
	// über
	// mehrere
	// Zeilen
	/* Kommentar
	   über
	   mehrere
	   Zeilen */
} /* ende des Programms */

 

3 Variablen

3.1 Was sind Variablen?
Variablen sind in C veränderbare Speicherstellen. Man kann also den Wert einer Variable verändern (man nennt das Zuweisung) und den dann später verarbeiten und/\oder wieder verändern. Eine Variable besteht aus dem Namen und dem Inhalt. In C gibt es verschiedene Typen von Variablen (sogenannte Datentypen): z.B. für Ganzzahlen, Zeichen usw. Das erstellen einer Variable nennen wir Deklaration. Wir deklarieren eine Variable, indem wir den Datentyp der Variable und den Namen der Variable mit einem Abstand getrennt angeben und die Anweisung mit einem Semikolon abschliessen:

typ name;

Der Name muss mit einem Gross- oder Kleinbuchstaben oder mit einem Unterstrich (_) beginnen und kann danach auch Zahlen beinhalten. Ich erwähne hier nochmal, dass C zwischen Gross- und Kleinschreibung unterscheidet. Also sind die Variablen name, Name und NAME alles unterschiedliche Variablen. Bei Variablen werden nur die ersten 32 Zeichen zur Unterscheidung benötigt. Das heisst, dass man Variablennamen, die länger als 32 Zeichen sind, vermeiden sollte, da sie zu Verwechslungen führen können. Ausserdem gibt es in C eine Liste sogenannter Schlüsselwörter. Diese Wörter dürfen nicht von Variablen benutzt werden.

Hier die Liste der 32 C-Schlüsselwörter:

auto      break     case      char      const     continue  default   do
double    else      enum      extern    float     for       goto      if
int       long      register  return    short     signed    sizeof    static
struct    switch    typedef   union     unsigned  void      volatile  while

Im ANSI C99-Standard wurden noch folgende zusätzliche Schlüsselwörter definiert:

inline    restrict  _Bool     _Complex  _Imaginary

Dazu gibt es noch C++ Schlüsselwörter, die den Compiler auch stören können, da die meisten Compiler sowohl C, als auch C++ beherrschen. Wenn also ein unerklärlicher Fehler bei einer Deklaration auftretet, könnte es sich um ein Schlüsselwort handeln. Ausserdem stellen einige Editoren die Schlüsselwörter mit einer anderen Farbe dar, so dass man diese schnell erkennen kann.

Gütige Variablennamen wären z.B.:

das_ist_EinTest
ABC123
_for_

Ungütige Variablennamen wären z.B.:

while (Schlüsselwort)
123zahl (Variable darf nicht mit einer Zahl anfangen)
sonder-zeichen (Bindestrich ist nicht erlaubt)

Genug der Theorie: Im nächsten Abschintt lernen wir den ersten Variablentyp kennen.

3.2 Ein Variablentyp: int
Der Datentyp int kann ganze Zahlen (also ohne Nachkommastellen) speichern. Sein Bereich geht auf 16Bit-Maschinen von -32768 bis +32767 und auf 32Bit-Maschinen von -2147483648 bis +2147483647. Wir verwenden höchstwahrscheinlich eine 32Bit-Maschine (Windows 95 bis XP sind 32Bit-Betriebssysteme). Wenn wir den Bereich überschreiten, zählt C wieder von vorne. Also +2147483648 wäre in C -2147483648. Um eine int-Variable zu deklarieren, geben wir folgendes ein:

int name;

Wenn wir diese Variable in unserem Beispielprogramm nach der printf-Anweisung versuchen zu deklarieren, bekommen wir eine Fehlermeldung (ausser es handelt sich um einen C++-Compiler).

Hier wäre das fehlerhafte Programm:

#include <stdio.h>

int main(int argc, char *argv[])
{
	printf("Hallo, Welt!\n");
	int name;
	return 0;
}

Das liegt daran, dass in C eine Variable nur am Anfang eines Anweisungsblockes deklariert werden darf. Das heisst, dass am Anfang des Blockes die Deklarationen kommen und erst dann die Anweisungen. Hier ein Beispiel-Block zur Veranschaulichung:

{
	Deklarationen
	Befehle
}

Korrekt müsste unser Programm also folgendermassen sein:

#include <stdio.h>

int main(int argc, char *argv[])
{
	/* Deklarationen */
	int name;

	/* Befehle */
	printf("Hallo, Welt!\n");
	return 0;
}

Wir können auch mehrere Variablen deklarieren:

	/* Deklarationen */
	int eins;
	int zwei;
	int drei;

Oder durch Kommas (,) getrennt in einer Anweisung:

	/* Deklarationen */
	int eins, zwei, drei;

Jetzt wollen wir den Variablen einen Wert zuweisen. Das geschieht mit dem Zuweisungsoperator "=". Die Zuweisungen gehören nicht mehr in den Abschnitt Deklarationen. Hier ein Beisipel, wie man den Variablen einen Wert zuweisen könnte:

#include <stdio.h>

int main(int argc, char *argv[])
{
	/* Deklarationen */
	int eins, zwei, drei;

	/* Befehle */
	eins = 1;
	zwei = 2;
	drei = 3;
	
	printf("Hallo, Welt!\n");
	return 0;
}

Übrigens nennt man das erste Zuweisen eines Werts einer Variable Initialisierung. Denn eine Variable hat nach der Deklarataion einen zufälligen, unvorhersehbaren Wert (nämlich den, der vorher an dieser Speicherstelle war). Nachdem wir die Variable initialisiert haben, hat die Variable einen vorhersehbaren Wert. Meistens initialisiert man Variablen mit 0 (Null).

Wir können Variablen auch während der Deklaration sofort initialisieren:

#include <stdio.h>

int main(int argc, char *argv[])
{
	/* Deklarationen */
	int eins = 1, zwei = 2, drei = 3;

	/* Befehle */
	printf("Hallo, Welt!\n");
	return 0;
}

Da C viel Freiheit bietet, wäre auch das möglich:

#include <stdio.h>

int main(int argc, char *argv[])
{
	/* Deklarationen */
	int eins = 1, zwei;
	int drei = 3;

	/* Befehle */
	zwei = 2;
	printf("Hallo, Welt!\n");
	return 0;
}

Den Abstand zwischen dem Gleichheitszeichen und dem Wert kann man weglassen. Genauso ist es mit dem Abstand nach dem Komma.

3.3 Formatierte Ausgabe mit printf

Nun beschäftigen wir uns genauer mit der Ausgabeanweisung printf. Bis jetzt haben wir nur einen gegebenen Text (String) ausgegeben. Nun wollen wir aber auch Variablen ausgeben können. Dazu verwenden wir auch die Anweisung printf. printf hat eine veränderbare Anzahl Argumente (siehe Kapitel 2.2). Das erste Argument bestimmt den Formatstring. Der Formatstring unterscheidet sich dadurch von einem normalen String, dass er Formatelemente enthät. Formatzeichen erkennt man am Prozentzeichen (%). Der Datentyp int hat das Formatzeichen %d. Wollen wir uns nun die drei Zahlen ausgeben lassen, müssten wir also folgendes in der printf-Anweisung angeben:

printf("eins: %d zwei: %d drei: %d\n");

Ersetzen wir also die "Hallo Welt"-Anweisung durch unsere "neue" Anweisung. Kompilieren wir jetzt das Programm und führen es aus. Eventuell gibt es Compilerwarnungen oder gar einen Fehler. Bei mir kam die folgende Ausgabe:

eins: -1073743176 zwei: 1074056984 drei: 1075023432

Das ist nicht so ganz das, was wir wollten, oder? Wir haben ja gar nicht angegeben, welche Variable er ausgeben soll. Wir haben nur das Formatelement %d als "Platzhalter" genommen. Die Lösung: Wir müssen die Variablen, die ausgegeben werden sollen als zusätzliche Argumente angeben. Und zwar in der Reihenfolge, in der die Formatelemente sind. Wir wir vielleicht noch wissen, werden die Argumente durch Kommas getrennt. Daraus ergibt sich die folgende Anweisung:

printf("eins: %d zwei: %d drei: %d\n", eins, zwei, drei);

Und siehe da, die Ausgabe stimmt:

eins: 1 zwei: 2 drei: 3

Hier zur Veranschaulichung folgende Abbildung. Die Formatelemente (%d) werden durch den Inhalt der Variablen ersetzt:

                                  ,-----------------.
                                 |                  |
                         ,-------+------------.     |
                        |        |            |     |
                ,-------+--------+------.     |     |
               |        |        |      |     |     |
              \|/      \|/      \|/     |     |     | 
printf("eins: %d zwei: %d drei: %d\n", eins, zwei, drei);

                          |
                          |
                          |
                         \|/

               eins: 1 zwei: 2 drei: 3                         


Zurück zur Hauptseite Letzte Änderung: 14.08.03
Copyright (C) 2003 by Thomas "tom" S. <tom at eggdrop.ch>

Dieser Text gehört zu www.eggdrop.ch und ist urheberrechtlich geschützt. Das Weitergeben und Kopieren dieses Textes ist erwünscht unter folgenden Bedingungen: 1. Der Text muss so sein wie er ist und darf in keiner Weise verändert oder in die eigene Homepage integriert werden. 2. Es muss ein deutlicher Hinweis auf die Herkunft (www.eggdrop.ch) vorhanden sein. 3. Der Text sollte wenigstens alle 3 Monate auf Updates überprüft werden (siehe die Versionsnummer ganz am Anfang des Textes!)