Inhaltsverzeichnis

  • Vorwort
    23
  • Vorwort des Gutachters
    25
  • 1
    Einstieg in C
    27
    • 1.1
      Übersicht zu C
      27
    • 1.2
      Der ANSI-C-Standard
      28
      • 1.2.1
        Welcher C-Standard wird in diesem Buch verwendet?
        30
      • 1.2.2
        Der Vorteil des ANSI-C-Standards
        31
    • 1.3
      Der POSIX-Standard
      31
    • 1.4
      Vor- und Nachteile der Programmiersprache C
      32
    • 1.5
      C in diesem Buch
      33
    • 1.6
      Was benötige ich für C?
      33
      • 1.6.1
        Texteditor
        33
      • 1.6.2
        Compiler
        34
      • 1.6.3
        All-in-one – die Entwicklungsumgebung
        34
    • 1.7
      Welcher Compiler und welches Betriebssystem?
      35
  • 2
    Das erste Programm
    37
    • 2.1
      Der beste Lernerfolg
      37
    • 2.2
      »Hallo Welt« in C
      37
    • 2.3
      Analyse des Programms
      39
  • 3
    Grundlagen
    43
    • 3.1
      Zeichensätze
      43
      • 3.1.1
        Basic-Zeichensatz
        43
      • 3.1.2
        Ausführungszeichensatz (Steuerzeichen)
        44
      • 3.1.3
        Trigraph-Zeichen
        46
    • 3.2
      Symbole von C
      48
      • 3.2.1
        Bezeichner
        48
      • 3.2.2
        Schlüsselwörter
        48
      • 3.2.3
        Literale
        48
      • 3.2.4
        Einfache Begrenzer
        50
      • 3.2.5
        Kommentare
        51
  • 4
    Formatierte Ein-/Ausgabe mit »scanf()« und »printf()«
    55
    • 4.1
      Formatierte Eingabe mit »scanf()«
      55
      • 4.1.1
        Der Adressoperator »&«
        57
      • 4.1.2
        Probleme und deren Behandlung mit »scanf()«
        58
      • 4.1.3
        Überprüfen auf das richtige Format
        61
      • 4.1.4
        Zusammenfassung zu »scanf()«
        63
    • 4.2
      Formatierte Ausgabe mit »printf()«
      63
  • 5
    Basisdatentypen
    67
    • 5.1
      Deklaration und Definition
      67
    • 5.2
      Der Datentyp »int« (Integer)
      69
    • 5.3
      Variablen verwenden
      70
    • 5.4
      Der Datentyp »long«
      73
    • 5.5
      Der Datentyp »long long«
      74
    • 5.6
      Der Datentyp »short«
      74
    • 5.7
      Ganzzahlige Typen mit vorgegebener Breite – <stdint.h>
      75
      • 5.7.1
        <inttypes.h> (C99)
        77
    • 5.8
      Die Gleitpunkttypen »float« und »double«
      78
      • 5.8.1
        Gleitpunkttypen im Detail
        80
      • 5.8.2
        »float« im Detail
        80
      • 5.8.3
        »double« im Detail
        81
      • 5.8.4
        long double
        81
      • 5.8.5
        Einiges zu n-stelliger Genauigkeit
        82
    • 5.9
      Numerische Gleitpunktprobleme
      83
    • 5.10
      Komplexe Gleitpunkttypen – <complex.h>
      86
    • 5.11
      Der Datentyp »char«
      87
    • 5.12
      Nationale contra internationale Zeichensätze
      92
    • 5.13
      Der Breitzeichen-Typ »wchar_t«
      94
    • 5.14
      Multibyte-Zeichen
      95
    • 5.15
      Boolescher Wert – <stdbool.h>
      96
    • 5.16
      Vorzeichenlos und vorzeichenbehaftet
      97
    • 5.17
      Limits für Ganzzahl- und Gleitpunktdatentypen
      99
    • 5.18
      Der Typ »void«
      102
    • 5.19
      Konstanten
      103
      • 5.19.1
        Ganzzahlkonstanten
        103
      • 5.19.2
        Gleitpunktkonstanten
        103
      • 5.19.3
        Zeichenkonstanten
        104
      • 5.19.4
        Stringliterale (Stringkonstante)
        104
    • 5.20
      Umwandlungsvorgaben für formatierte Ein-/Ausgabe
      104
  • 6
    Operatoren
    113
    • 6.1
      Exkurs zu Operatoren
      113
    • 6.2
      Arithmetische Operatoren
      114
      • 6.2.1
        Dividieren von Ganzzahlen
        115
    • 6.3
      Erweiterte Darstellung arithmetischer Operatoren
      117
    • 6.4
      Inkrement- und Dekrement-Operatoren
      118
    • 6.5
      Bit-Operatoren
      119
      • 6.5.1
        Bitweises UND
        120
      • 6.5.2
        Bitweises ODER
        122
      • 6.5.3
        Bitweises XOR
        122
      • 6.5.4
        Bitweises Komplement
        123
      • 6.5.5
        Linksverschiebung
        124
      • 6.5.6
        Rechtsverschiebung
        125
      • 6.5.7
        Rezept für Fortgeschrittene
        125
    • 6.6
      Makros für logische Operatoren und Bit-Operatoren – <iso646.h>
      126
    • 6.7
      Der »sizeof«-Operator
      127
      • 6.7.1
        C versus C++
        129
  • 7
    Typumwandlung
    131
    • 7.1
      Implizite Datentypumwandlung
      131
      • 7.1.1
        Implizites »char« nach »int«
        131
      • 7.1.2
        Implizites »float« nach »double«
        132
      • 7.1.3
        Implizite Umwandlung in einen komplexen Gleitpunkttyp
        132
      • 7.1.4
        Übliche arithmetische Datentypumwandlung
        132
    • 7.2
      Explizite Datentypumwandlung mit dem »cast«-Operator
      135
  • 8
    Kontrollstrukturen
    137
    • 8.1
      Verzweigungen mit der »if«-Bedingung
      137
      • 8.1.1
        Anweisungsblock
        138
    • 8.2
      Die Verzweigung mit »else if«
      141
    • 8.3
      Die Verzweigung mit »else«
      143
    • 8.4
      Der !-Operator (logischer Operator)
      147
    • 8.5
      Logisches UND (&&) – logisches ODER (||)
      149
    • 8.6
      Der Bedingungsoperator »?:«
      151
    • 8.7
      Fallunterscheidung: die »switch«-Verzweigung
      153
      • 8.7.1
        default
        156
    • 8.8
      Die »while«-Schleife
      157
      • 8.8.1
        Endlosschleife (»while«)
        159
      • 8.8.2
        Fehlervermeidung bei »while«-Schleifen
        160
    • 8.9
      Die »do while«-Schleife
      161
    • 8.10
      Die »for«-Schleife
      165
      • 8.10.1
        Einsatzmöglichkeiten der »for«-Schleife
        168
    • 8.11
      Kontrollierte Sprünge
      172
      • 8.11.1
        continue
        172
      • 8.11.2
        break
        173
    • 8.12
      Direkte Sprünge mit »goto«
      174
    • 8.13
      Notationsstil
      175
      • 8.13.1
        K&R-Stil
        175
      • 8.13.2
        Whitesmith-Stil
        175
      • 8.13.3
        Allman-Stil
        175
      • 8.13.4
        GNU EMACS-Stil
        176
      • 8.13.5
        Der Stil des Autors ;) (K&R-like)
        176
  • 9
    Funktionen
    177
    • 9.1
      Was sind Funktionen?
      177
    • 9.2
      Wozu dienen Funktionen?
      177
    • 9.3
      Definition von Funktionen
      177
    • 9.4
      Funktionsaufruf
      178
    • 9.5
      Funktionsdeklaration
      180
    • 9.6
      Lokale Variablen
      181
    • 9.7
      Globale Variablen
      184
    • 9.8
      Statische Variablen
      185
    • 9.9
      Schlüsselwörter für Variablen – Speicherklassen
      186
      • 9.9.1
        auto
        187
      • 9.9.2
        extern
        187
      • 9.9.3
        register
        187
      • 9.9.4
        static
        187
    • 9.10
      Typ-Qualifizierer
      188
      • 9.10.1
        volatile
        188
      • 9.10.2
        const
        188
    • 9.11
      Geltungsbereich von Variablen
      188
    • 9.12
      Speicherklassen-Spezifizierer für Funktionen
      190
      • 9.12.1
        extern
        190
      • 9.12.2
        static
        190
      • 9.12.3
        volatile
        190
    • 9.13
      Datenaustausch zwischen Funktionen
      191
    • 9.14
      Wertübergabe an Funktionen (call-by-value)
      192
    • 9.15
      Der Rückgabewert von Funktionen
      195
    • 9.16
      Die Hauptfunktion »main()«
      197
    • 9.17
      Rückgabewert beim Beenden eines Programms
      199
      • 9.17.1
        Programmende auswerten
        200
    • 9.18
      Funktionen der Laufzeitbibliothek
      202
    • 9.19
      Getrenntes Kompilieren von Quelldateien
      203
    • 9.20
      Rekursive Funktionen (Rekursion)
      206
      • 9.20.1
        Exkurs: Stack
        206
      • 9.20.2
        Rekursionen und der Stack
        206
      • 9.20.3
        Fakultät
        211
      • 9.20.4
        Fibonacci-Zahlen
        212
      • 9.20.5
        Größter gemeinsamer Teiler (GGT)
        213
    • 9.21
      »inline«-Funktionen
      217
  • 10
    Präprozessor-Direktiven
    221
    • 10.1
      Einkopieren von Dateien mittels »#include«
      222
    • 10.2
      Makros und Konstanten – »#define«
      224
      • 10.2.1
        Symbolische Konstanten mit »#define«
        225
      • 10.2.2
        Makros mit »#define«
        229
    • 10.3
      Bedingte Kompilierung
      233
    • 10.4
      Vordefinierte Präprozessor-Direktiven (ANSI C)
      238
    • 10.5
      Ersetzung eines Makroparameters durch einen String
      240
    • 10.6
      »#undef« – Makronamen wieder aufheben
      241
    • 10.7
      Ausgeben von Fehlermeldungen – »#error«
      242
    • 10.8
      »#pragma«
      243
  • 11
    Arrays
    245
    • 11.1
      Arrays deklarieren
      245
    • 11.2
      Initialisierung und Zugriff auf Arrays
      246
      • 11.2.1
        Gültigkeitsbereich von Arrays
        251
    • 11.3
      Arrays vergleichen
      253
    • 11.4
      Anzahl der Elemente eines Arrays ermitteln
      255
    • 11.5
      Übergabe von Arrays an Funktionen
      256
    • 11.6
      Arrays aus Funktionen zurückgeben
      258
    • 11.7
      Programmbeispiel zu den Arrays
      259
    • 11.8
      Einlesen von Array-Werten
      263
    • 11.9
      Mehrdimensionale Arrays
      263
      • 11.9.1
        Mehrdimensionale Arrays initialisieren
        264
      • 11.9.2
        Übergabe von zwei- bzw. mehrdimensionalen Arrays an Funktionen
        276
    • 11.10
      Arrays in Tabellenkalkulation einlesen (*.CSV-Dateien)
      278
    • 11.11
      Strings/Zeichenketten (»char«-Array)
      280
      • 11.11.1
        Vom String zur Binärzahl
        283
    • 11.12
      Einlesen von Strings
      286
    • 11.13
      Die Standard-Bibliothek <string.h>
      288
      • 11.13.1
        »strcat()« – Strings aneinanderhängen
        288
      • 11.13.2
        »strchr()« – ein Zeichen im String suchen
        289
      • 11.13.3
        »strcmp()« – Strings vergleichen
        290
      • 11.13.4
        »strcpy()« – einen String kopieren
        291
      • 11.13.5
        »strcspn()« – einen Teilstring ermitteln
        292
      • 11.13.6
        »strlen()« – Länge eines Strings ermitteln
        292
      • 11.13.7
        »strncat()« – String mit n Zeichen aneinanderhängen
        293
      • 11.13.8
        »strncmp()« – n Zeichen von zwei Strings miteinander vergleichen
        294
      • 11.13.9
        »strncpy()« – String mit n Zeichen kopieren
        294
      • 11.13.10
        »strpbrk()« – nach dem Auftreten bestimmter Zeichen suchen
        295
      • 11.13.11
        »strrchr()« – das letzte Auftreten eines bestimmten Zeichens im String suchen
        296
      • 11.13.12
        »strspn()« – das erste Auftreten eines Zeichens, das nicht vorkommt
        296
      • 11.13.13
        »strstr()« – einen String nach dem Auftreten eines Teilstrings durchsuchen
        297
      • 11.13.14
        »strtok()« – einen String anhand bestimmter Zeichen zerlegen
        297
  • 12
    Zeiger (Pointer)
    299
    • 12.1
      Zeiger deklarieren
      300
    • 12.2
      Zeiger initialisieren
      301
      • 12.2.1
        Speichergröße von Zeigern
        312
    • 12.3
      Zeigerarithmetik
      313
    • 12.4
      Zeiger, die auf andere Zeiger verweisen
      314
      • 12.4.1
        Subtraktion zweier Zeiger
        315
    • 12.5
      Typensicherung bei der Dereferenzierung
      316
    • 12.6
      Zeiger als Funktionsparameter (call-by-reference)
      317
      • 12.6.1
        Zeiger als Rückgabewert
        320
    • 12.7
      Array und Zeiger
      323
    • 12.8
      Zeiger auf Strings
      330
      • 12.8.1
        Zeiger auf konstante Objekte (Read-only-Zeiger)
        330
    • 12.9
      Zeiger auf Zeiger und Stringtabellen
      331
      • 12.9.1
        Stringtabellen
        333
    • 12.10
      Zeiger auf Funktionen
      340
    • 12.11
      void-Zeiger
      346
    • 12.12
      Äquivalenz zwischen Zeigern und Arrays
      349
    • 12.13
      Der »restrict«-Zeiger
      351
  • 13
    Kommandozeilenargumente
    355
    • 13.1
      Argumente an die Hauptfunktion übergeben
      355
    • 13.2
      Optionen (Schalter) aus der Kommandozeile auswerten
      361
  • 14
    Dynamische Speicherverwaltung
    365
    • 14.1
      Das Speicherkonzept
      366
    • 14.2
      Speicherallokation mit »malloc()«
      367
    • 14.3
      Das NULL-Mysterium
      370
      • 14.3.1
        NULL für Fortgeschrittene
        370
      • 14.3.2
        Was jetzt - NULL, 0 oder &#092;0 ... ?
        372
      • 14.3.3
        Zusammengefasst
        373
    • 14.4
      Speicherreservierung und ihre Probleme
      373
    • 14.5
      »free()« – Speicher wieder freigeben
      374
    • 14.6
      Die Freispeicherverwaltung
      377
      • 14.6.1
        Prozessinterne Freispeicherverwaltung
        379
    • 14.7
      Dynamische Arrays
      381
    • 14.8
      Speicher dynamisch reservieren mit »realloc()« und »calloc()«
      385
    • 14.9
      Speicher vom Stack anfordern mit »alloca()« (nicht ANSI C)
      389
    • 14.10
      »free()« – Speicher wieder freigeben
      389
    • 14.11
      Zweidimensionale dynamische Arrays
      390
    • 14.12
      Wenn die Speicherallokation fehlschlägt
      393
      • 14.12.1
        Speicheranforderung reduzieren
        394
      • 14.12.2
        Speicheranforderungen aufteilen
        395
      • 14.12.3
        Einen Puffer konstanter Größe verwenden
        396
      • 14.12.4
        Zwischenspeichern auf Festplatte vor der Allokation
        397
      • 14.12.5
        Nur so viel Speicher anfordern wie nötig
        397
  • 15
    Strukturen
    399
    • 15.1
      Struktur deklarieren
      399
    • 15.2
      Initialisierung und Zugriff auf Strukturen
      401
    • 15.3
      Strukturen als Wertübergabe an eine Funktion
      408
    • 15.4
      Strukturen als Rückgabewert einer Funktion
      410
    • 15.5
      Strukturen vergleichen
      412
    • 15.6
      Arrays von Strukturen
      413
    • 15.7
      Strukturen in Strukturen (Nested Structures)
      420
    • 15.8
      Kurze Zusammenfassung zu den Strukturen
      430
    • 15.9
      Unions
      431
    • 15.10
      Der Aufzählungstyp »enum«
      436
    • 15.11
      Typendefinition mit »typedef«
      439
    • 15.12
      Attribute von Strukturen verändern (nicht ANSI C)
      443
    • 15.13
      Bitfelder
      446
    • 15.14
      Das »offsetof«-Makro
      453
  • 16
    Ein-/Ausgabe-Funktionen
    455
    • 16.1
      Was ist eine Datei?
      455
    • 16.2
      Formatierte und unformatierte Ein-/Ausgabe
      455
    • 16.3
      Standard-Streams
      456
    • 16.4
      Höhere Ein-/Ausgabe-Funktionen
      456
    • 16.5
      Datei (Stream) öffnen – »fopen«
      457
      • 16.5.1
        Modus für »fopen()«
        460
      • 16.5.2
        Maximale Anzahl geöffneter Dateien – »FOPEN_MAX«
        463
    • 16.6
      Zeichenweise lesen und schreiben – »getchar()« und »putchar()«
      464
      • 16.6.1
        Ein etwas portableres »getch()«
        466
    • 16.7
      Zeichenweise lesen und schreiben – »putc()«/»fputc()« und »getc()«/»fgetc()«
      468
    • 16.8
      Datei (Stream) schließen – »fclose()«
      474
    • 16.9
      Formatiertes Einlesen/Ausgeben von Streams mit »fprintf()« und »fscanf()«
      477
    • 16.10
      Standard-Streams in C
      482
      • 16.10.1
        Standard-Streams umleiten
        482
    • 16.11
      Fehlerbehandlung von Streams – »feof()«, »ferror()« und »clearerr()«
      485
    • 16.12
      Gelesenes Zeichen in die Eingabe zurückschieben – »ungetc()«
      487
    • 16.13
      (Tastatur-)Puffer leeren – »fflush()«
      489
    • 16.14
      Stream positionieren – »fseek()«, »rewind()« und »ftell()«
      490
    • 16.15
      Stream positionieren – »fsetpos()«, »fgetpos()«
      494
    • 16.16
      Zeilenweise Ein-/Ausgabe von Streams
      496
      • 16.16.1
        Zeilenweise lesen mit »gets()«/»fgets()«
        496
      • 16.16.2
        Zeilenweise schreiben mit »puts()«/»fputs()«
        499
      • 16.16.3
        Zeilenweise vom Stream einlesen mit »getline()« (nicht ANSI C)
        500
      • 16.16.4
        Rezepte für zeilenweises Einlesen und Ausgeben
        502
    • 16.17
      Blockweise lesen und schreiben – »fread()« und »fwrite()«
      509
      • 16.17.1
        Blockweise lesen – »fread()«
        510
      • 16.17.2
        Blockweise schreiben – »fwrite()«
        512
      • 16.17.3
        Big Endian und Little Endian
        517
    • 16.18
      Datei (Stream) erneut öffnen – »freopen()«
      519
    • 16.19
      Datei löschen oder umbenennen – »remove()« und »rename()«
      521
      • 16.19.1
        remove()
        521
      • 16.19.2
        rename()
        522
    • 16.20
      Pufferung einstellen – »setbuf()« und »setvbuf()«
      523
      • 16.20.1
        Die Funktion »setbuf()«
        524
      • 16.20.2
        Die Funktion »setvbuf()«
        528
    • 16.21
      Temporäre Dateien erzeugen – »tmpfile()« und »tmpnam()«
      530
      • 16.21.1
        »mkstemp()« – sichere Alternative für Linux/UNIX (nicht ANSI C)
        534
    • 16.22
      Fehlerbehandlung
      535
      • 16.22.1
        Fehlerausgabe mit »perror()«
        536
      • 16.22.2
        Fehlerausgabe mit »strerror()«
        537
    • 16.23
      Formatiert in einen String schreiben und formatiert aus einem String lesen – »sscanf()« und »sprintf()«
      539
    • 16.24
      Byte- und wide-orientierter Stream
      542
    • 16.25
      Ein fortgeschrittenes Thema
      544
    • 16.26
      Low-Level-Datei-I/O-Funktionen (nicht ANSI C)
      552
      • 16.26.1
        Datei öffnen – »open()«
        553
      • 16.26.2
        Datei schließen – »close()«
        559
      • 16.26.3
        Datei erzeugen – »creat()«
        560
      • 16.26.4
        Schreiben und Lesen – »write()« und »read()«
        561
      • 16.26.5
        File-Deskriptor positionieren – »lseek()«
        571
      • 16.26.6
        File-Deskriptor von einem Stream – »fileno()«
        572
      • 16.26.7
        Stream von File-Deskriptor – »fdopen()«
        574
  • 17
    Attribute von Dateien und das Arbeiten mit Verzeichnissen (nicht ANSI C)
    577
    • 17.1
      Attribute einer Datei ermitteln – »stat()«
      577
      • 17.1.1
        »stat()« – »st_mode«
        578
      • 17.1.2
        »stat()« – »st_size«
        583
      • 17.1.3
        »stat()« – »st_atime«, »st_mtime« und »st_ctime«
        585
      • 17.1.4
        »stat()« – »st_gid« und »st_uid«
        589
      • 17.1.5
        »stat()« – »st_nlink«, »st_ino«
        590
      • 17.1.6
        »stat()« – »st_dev«, »st_rdev«
        590
    • 17.2
      Prüfen des Zugriffsrechts – »access()«
      593
    • 17.3
      Verzeichnisfunktionen
      595
      • 17.3.1
        Verzeichnis erstellen, löschen und wechseln – »mkdir()«, »rmdir« und »chdir«
        596
      • 17.3.2
        In das Arbeitsverzeichnis wechseln – »getcwd()«
        601
      • 17.3.3
        Verzeichnisse öffnen, lesen und schließen – »opendir()«, »readdir()« und »closedir()«
        603
  • 18
    Arbeiten mit variabel langen Argumentlisten – <stdarg.h>
    609
    • 18.1
      Makros in <stdarg.h> – »va_list«, »va_arg«, »va_start« und »va_end«
      609
    • 18.2
      Die Argumentliste am Anfang oder Ende kennzeichnen
      610
    • 18.3
      »vprintf()«, »vsprintf()«, »vfsprintf()« und »vsnsprintf()«
      615
    • 18.4
      Variadic Makros – __VA_ARGS__
      619
  • 19
    Zeitroutinen
    623
    • 19.1
      Die Headerdatei <time.h>
      623
      • 19.1.1
        Konstanten in der Headerdatei <time.h>
        624
      • 19.1.2
        Datums- und Zeitfunktionen in <time.h>
        624
    • 19.2
      Laufzeitmessung (Profiling)
      634
  • 20
    Weitere Headerdateien und ihre Funktionen (ANSI C)
    637
    • 20.1
      <assert.h> – Testmöglichkeiten und Fehlersuche
      637
    • 20.2
      <ctype.h> – Zeichenklassifizierung und Umwandlung
      639
    • 20.3
      Mathematische Funktionen – <math.h>, <tgmath.h> und <complex.h>
      643
      • 20.3.1
        Funktionen für reelle und komplexe Gleitpunkttypen
        644
      • 20.3.2
        Funktionen nur für reelle Gleitpunkttypen
        646
      • 20.3.3
        Funktionen nur für komplexe Gleitpunkttypen
        647
      • 20.3.4
        Typengenerische Makros – <tgmath.h>
        649
      • 20.3.5
        Gleitpunktwerte klassifizieren
        650
      • 20.3.6
        Makro zum Vergleichen von reellen Zahlen
        651
      • 20.3.7
        Zugriff auf die Gleitpunkt-Umgebung – <fenv.h>
        652
    • 20.4
      <stdlib.h>
      655
      • 20.4.1
        Programmbeendigung – »exit()«, »_exit()«, »atexit()« und »abort()«
        655
      • 20.4.2
        Strings in numerische Werte konvertieren
        658
      • 20.4.3
        Bessere Alternative – Strings in numerische Werte konvertieren
        661
      • 20.4.4
        Zufallszahlen
        666
      • 20.4.5
        Absolutwerte, der Quotient und der Rest von Divisionen
        667
      • 20.4.6
        Suchen und Sortieren – »qsort()« und »bsearch()«
        669
      • 20.4.7
        system()
        671
    • 20.5
      <locale.h> – länderspezifische Eigenheiten
      673
    • 20.6
      Nicht-lokale Sprünge – <setjmp.h>
      676
    • 20.7
      <signal.h>
      680
    • 20.8
      <string.h> – die »mem…«-Funktionen zur Speichermanipulation
      685
      • 20.8.1
        »memchr()« – Suche nach einzelnen Zeichen
        686
      • 20.8.2
        »memcmp()« – bestimmte Anzahl von Bytes vergleichen
        686
      • 20.8.3
        »memcpy()« – bestimmte Anzahl von Bytes kopieren
        687
      • 20.8.4
        »memmove()« – bestimmte Anzahl von Bytes kopieren
        687
      • 20.8.5
        »memset()« – Speicherbereich mit bestimmten Zeichen auffüllen
        688
  • 21
    Dynamische Datenstrukturen
    691
    • 21.1
      Lineare Listen (einfach verkettete Listen)
      691
      • 21.1.1
        Erstes Element der Liste löschen
        698
      • 21.1.2
        Ein beliebiges Element in der Liste löschen
        700
      • 21.1.3
        Elemente der Liste ausgeben
        702
      • 21.1.4
        Eine vollständige Liste auf einmal löschen
        708
      • 21.1.5
        Element in die Liste einfügen
        710
    • 21.2
      Doppelt verkettete Listen
      717
    • 21.3
      Stacks nach dem LIFO-(Last-in-First-out-)Prinzip
      734
    • 21.4
      Queues nach dem FIFO-Prinzip
      754
    • 21.5
      Dynamisches Array mit flexiblen Elementen
      762
  • 22
    Algorithmen
    765
    • 22.1
      Was sind Algorithmen?
      765
    • 22.2
      Wie setze ich Algorithmen ein?
      766
    • 22.3
      Sortieralgorithmen
      766
      • 22.3.1
        »Selection Sort« – sortieren durch Auswählen
        767
      • 22.3.2
        Insertion Sort
        769
      • 22.3.3
        Bubble Sort
        771
      • 22.3.4
        Shellsort
        772
      • 22.3.5
        Quicksort
        776
      • 22.3.6
        qsort()
        782
      • 22.3.7
        Zusammenfassung der Sortieralgorithmen
        784
    • 22.4
      Suchalgorithmen – Grundlage zur Suche
      791
      • 22.4.1
        Lineare Suche
        792
      • 22.4.2
        Binäre Suche
        794
      • 22.4.3
        Binäre (Such-)Bäume
        796
      • 22.4.4
        Elemente im binären Baum einordnen
        799
      • 22.4.5
        Binäre Bäume traversieren
        804
      • 22.4.6
        Löschen eines Elements im binären Baum
        805
      • 22.4.7
        Ein binärer Suchbaum in der Praxis
        808
      • 22.4.8
        Binäre Suchbäume mit Eltern-Zeiger und Threads
        817
      • 22.4.9
        Ausgeglichene Binärbäume
        818
      • 22.4.10
        Algorithmen für ausgeglichene Bäume – eine Übersicht
        818
    • 22.5
      Hashing (Zerhacken)
      819
      • 22.5.1
        Wann wird Hashing verwendet?
        820
      • 22.5.2
        Was ist für das Hashing erforderlich?
        820
      • 22.5.3
        Hash-Funktion
        824
      • 22.5.4
        Hashing mit direkter Adressierung
        829
      • 22.5.5
        Vergleich von Hashing mit binären Bäumen
        829
    • 22.6
      String-Matching
      830
      • 22.6.1
        Brute-Force-Algorithmus
        831
      • 22.6.2
        Der Algorithmus von Knuth/Morris/Pratt (KMP)
        833
      • 22.6.3
        Weitere String-Matching-Algorithmen
        840
    • 22.7
      Pattern Matching (reguläre Ausdrücke)
      841
    • 22.8
      Backtracking
      847
      • 22.8.1
        Der Weg durch den Irrgarten
        847
      • 22.8.2
        Das 8-Dame-Problem
        860
  • 23
    CGI mit C
    869
    • 23.1
      Was ist CGI?
      869
    • 23.2
      Vorteile von CGIs in C
      869
    • 23.3
      Andere Techniken der Webprogrammierung
      870
    • 23.4
      Das dreistufige Webanwendungsdesign
      871
      • 23.4.1
        Darstellungsschicht
        871
      • 23.4.2
        Verarbeitungsschicht
        872
      • 23.4.3
        Speicherschicht
        872
    • 23.5
      Clientseitige Programmierung
      873
      • 23.5.1
        JavaScript
        873
      • 23.5.2
        Java-Applets
        873
    • 23.6
      Serverseitige Programmierung
      873
    • 23.7
      Der Webserver
      874
      • 23.7.1
        Das Client/Server-Modell des Internets
        874
      • 23.7.2
        Serverimplementierung
        875
      • 23.7.3
        Hosting-Services
        876
      • 23.7.4
        Schlüsselfertige Lösung
        876
      • 23.7.5
        Weitere Möglichkeiten
        877
      • 23.7.6
        Apache
        877
    • 23.8
      Das HTTP-Protokoll
      888
      • 23.8.1
        Web-Protokolle
        888
      • 23.8.2
        Wozu dienen Protokolle?
        888
      • 23.8.3
        Was ist ein Protokoll?
        889
      • 23.8.4
        Normen für die Netzwerktechnik
        889
      • 23.8.5
        Das OSI-Schichtenmodell
        889
      • 23.8.6
        Die Elemente einer URL
        890
      • 23.8.7
        Client-Anfrage – HTTP-Request (Browser-Request)
        892
      • 23.8.8
        Serverantwort (Server-Response)
        895
      • 23.8.9
        Zusammenfassung
        898
    • 23.9
      Das Common Gateway Interface (CGI)
      898
      • 23.9.1
        Filehandles
        898
      • 23.9.2
        CGI-Umgebungsvariablen
        899
      • 23.9.3
        CGI-Ausgabe
        904
    • 23.10
      HTML-Formulare
      907
      • 23.10.1
        Die Tags und ihre Bedeutung
        907
    • 23.11
      CGI-Eingabe
      913
      • 23.11.1
        Die Anfrage des Clients an den Server
        913
      • 23.11.2
        Eingabe parsen
        917
    • 23.12
      Ein Gästebuch
      922
      • 23.12.1
        Das HTML-Formular (»guestbook.html«)
        922
      • 23.12.2
        Das CGI-Programm (»auswert.cgi«)
        924
      • 23.12.3
        Das HTML-Gästebuch (»gaeste.html«)
        932
    • 23.13
      Ausblick
      933
  • 24
    MySQL und C
    935
    • 24.1
      Aufbau eines Datenbanksystems
      935
      • 24.1.1
        Warum wurde ein Datenbanksystem (DBS) entwickelt?
        935
      • 24.1.2
        Das Datenbank-Management-System (DBMS)
        936
      • 24.1.3
        Relationale Datenbank
        939
      • 24.1.4
        Eigene Clients mit C für SQL mithilfe der ODBC-API entwickeln
        939
    • 24.2
      MySQL installieren
      940
      • 24.2.1
        Linux
        940
      • 24.2.2
        Den Client »mysql« starten
        941
    • 24.3
      Crashkurs (My)SQL
      943
      • 24.3.1
        Was ist SQL?
        944
      • 24.3.2
        Die Datentypen von (My)SQL
        944
      • 24.3.3
        Eine Datenbank erzeugen
        946
      • 24.3.4
        Eine Datenbank löschen
        947
      • 24.3.5
        Datenbank wechseln
        948
      • 24.3.6
        Eine Tabelle erstellen
        948
      • 24.3.7
        Die Tabelle anzeigen
        949
      • 24.3.8
        Tabellendefinition überprüfen
        949
      • 24.3.9
        Tabelle löschen
        950
      • 24.3.10
        Struktur einer Tabelle ändern
        950
      • 24.3.11
        Datensätze eingeben
        951
      • 24.3.12
        Datensätze auswählen
        951
      • 24.3.13
        Ein fortgeschrittenes Szenario
        952
      • 24.3.14
        Datensatz löschen
        954
      • 24.3.15
        Datensatz ändern
        954
      • 24.3.16
        Zugriffsrechte in MySQL
        954
      • 24.3.17
        Übersicht über einige SQL-Kommandos
        955
    • 24.4
      Die MySQL-C-API
      957
      • 24.4.1
        Grundlagen zur Programmierung eines MySQL-Clients
        957
      • 24.4.2
        Client-Programm mit dem gcc unter Linux und dem Cygwingcc-Compiler unter Windows
        958
      • 24.4.3
        MySQL Client-Programme mit dem VC++ Compiler und dem Borland Freeware Compiler
        959
      • 24.4.4
        Troubleshooting
        961
      • 24.4.5
        Das erste Client-Programm – Verbindung mit dem MySQL-Server herstellen
        961
      • 24.4.6
        MySQL-Kommandozeilen-Optionen
        966
      • 24.4.7
        Anfrage an den Server
        969
    • 24.5
      MySQL und C mit CGI
      987
      • 24.5.1
        HTML-Eingabeformular
        987
      • 24.5.2
        Die CGI-Anwendung »add_db.cgi«
        988
      • 24.5.3
        Die CGI-Anwendung »search_db.cgi«
        996
    • 24.6
      Funktionsübersicht
      1004
    • 24.7
      Datentypenübersicht der C-API
      1007
  • 25
    Netzwerkprogrammierung und Cross-Plattform-Entwicklung
    1009
    • 25.1
      Begriffe zur Netzwerktechnik
      1010
      • 25.1.1
        IP-Nummern
        1010
      • 25.1.2
        Portnummer
        1011
      • 25.1.3
        Host- und Domainname
        1012
      • 25.1.4
        Nameserver
        1013
      • 25.1.5
        Das IP-Protokoll
        1013
      • 25.1.6
        TCP und UDP
        1014
      • 25.1.7
        Was sind Sockets?
        1014
    • 25.2
      Headerdateien zur Socketprogrammierung
      1015
      • 25.2.1
        Linux/UNIX
        1015
      • 25.2.2
        Windows
        1016
    • 25.3
      Client/Server-Prinzip
      1018
      • 25.3.1
        Loopback-Interface
        1019
    • 25.4
      Erstellen einer Client-Anwendung
      1019
      • 25.4.1
        »socket()« – Erzeugen eines Kommunikationsendpunktes
        1020
      • 25.4.2
        »connect()« – ein Client stellt eine Verbindung zum Server her
        1022
      • 25.4.3
        Senden und Empfangen von Daten
        1027
      • 25.4.4
        »close()« und »closesocket()«
        1029
    • 25.5
      Erstellen einer Server-Anwendung
      1030
      • 25.5.1
        »bind()« – Festlegen einer Adresse aus dem Namensraum
        1030
      • 25.5.2
        »listen()« – Warteschlange für eingehende Verbindungen einrichten
        1032
      • 25.5.3
        »accept()« und die Serverhauptschleife
        1033
    • 25.6
      (Cross-Plattform-)TCP-Echo-Server
      1036
      • 25.6.1
        Der Client
        1036
      • 25.6.2
        Der Server
        1039
    • 25.7
      Cross-Plattform-Development
      1043
      • 25.7.1
        Abstraction Layer
        1043
      • 25.7.2
        Headerdatei für Linux/UNIX
        1043
      • 25.7.3
        Linux/UNIX-Quellcodedatei
        1044
      • 25.7.4
        Headerdatei für MS-Windows
        1048
      • 25.7.5
        Windows-Quellcodedatei
        1048
      • 25.7.6
        All together – die »main«-Funktionen
        1052
      • 25.7.7
        Ein UDP-Beispiel
        1056
      • 25.7.8
        Mehrere Clients gleichzeitig behandeln
        1058
    • 25.8
      Weitere Anmerkungen zur Netzwerkprogrammierung
      1066
      • 25.8.1
        Das Datenformat
        1066
      • 25.8.2
        Der Puffer
        1067
      • 25.8.3
        Portabilität
        1068
      • 25.8.4
        Von IPv4 nach IPv6
        1068
      • 25.8.5
        RFC-Dokumente (Request for Comments)
        1070
      • 25.8.6
        Sicherheit
        1070
  • 26
    Paralleles Rechnen
    1071
    • 26.1
      Parallelität
      1071
      • 26.1.1
        Single-Prozessorsysteme
        1072
      • 26.1.2
        Hyperthreading
        1072
    • 26.2
      Programmiertechniken der Parallelisierung
      1073
      • 26.2.1
        Automatische Parallelisierung
        1073
      • 26.2.2
        Halbautomatische Parallelisierung
        1074
      • 26.2.3
        Echte Parallelisierung
        1074
    • 26.3
      Vom Prozess zum Thread
      1075
    • 26.4
      Mit den POSIX-Threads programmieren
      1078
      • 26.4.1
        Ein serielles Beispiel
        1078
      • 26.4.2
        Das Grundgerüst für ein Programm mit mehreren Threads
        1080
      • 26.4.3
        Zusammenfassung
        1086
  • 27
    Sicheres Programmieren
    1087
    • 27.1
      Buffer-Overflow (Speicherüberlauf)
      1088
      • 27.1.1
        Speicherverwaltung von Programmen
        1090
      • 27.1.2
        Der Stack-Frame
        1091
      • 27.1.3
        Rücksprungadresse manipulieren
        1092
      • 27.1.4
        Gegenmaßnahmen zum Buffer-Overflow während der Programmerstellung
        1098
      • 27.1.5
        Gegenmaßnahmen zum Buffer-Overflow, wenn das Programm fertig ist
        1101
      • 27.1.6
        Programme und Tools zum Buffer-Overflow
        1104
      • 27.1.7
        Ausblick
        1105
    • 27.2
      Memory Leaks (Speicherlecks)
      1105
      • 27.2.1
        Bibliotheken und Tools zu Memory Leaks
        1109
    • 27.3
      Tipps zu Sicherheitsproblemen
      1110
  • 28
    Wie geht’s jetzt weiter?
    1113
    • 28.1
      GUI-Programmierung – grafische Oberflächen
      1114
      • 28.1.1
        Low-Level-Grafikprogrammierung
        1114
      • 28.1.2
        High-Level-Grafikprogrammierung
        1115
      • 28.1.3
        Multimedia-Grafikprogrammierung
        1116
  • Anhang
    1117
    • A
      Operatoren
      1119
      • A.1
        Rangfolge der Operatoren
        1119
      • A.2
        ASCII-Code-Tabelle
        1121
      • A.3
        Reservierte Schlüsselwörter in C
        1122
      • A.4
        Standard-Headerdateien der ANSI-C-Bibliothek
        1122
      • A.5
        Weiterführende Links
        1122
    • B
      Die C-Standard-Bibliothek
      1123
      • B.1
        <assert.h>
        1123
      • B.2
        <complex.h> (C99)
        1123
      • B.3
        <ctype.h>
        1127
      • B.4
        <errno.h>
        1128
      • B.5
        <fenv.h> (C99)
        1129
      • B.6
        <float.h>
        1131
      • B.7
        <inttypes.h> (C99)
        1133
      • B.8
        <iso646.h> (NA1)
        1135
      • B.9
        <limits.h>
        1135
      • B.10
        <locale.h>
        1136
      • B.11
        <math.h>
        1139
      • B.12
        <setjmp.h>
        1145
      • B.13
        <signal.h>
        1146
      • B.14
        <stdarg.h>
        1147
      • B.15
        <stdbool.h> (C99)
        1148
      • B.16
        <stddef.h>
        1148
      • B.17
        <stdint.h> (C99)
        1149
      • B.18
        <stdio.h>
        1150
      • B.19
        <stdlib.h>
        1156
      • B.20
        <string.h>
        1160
      • B.21
        <tgmath.h> (C99)
        1162
      • B.22
        <time.h>
        1163
      • B.23
        <wchar.h> (NA1)
        1165
      • B.24
        <wctype.h> (NA1)
        1172
  • Index
    1175