74
Dr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux / UNIX / Windows Beispiele, Anwendungen, Programmiertechniken

C-Programmierung unter Linux/UNIX/Windows - · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Embed Size (px)

Citation preview

Page 1: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Dr. Helmut HeroldDr. Jörg Arndt

C-Programmierung unterLinux / UNIX / Windows

Beispiele, Anwendungen,Programmiertechniken

Page 2: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Alle in diesem Buch enthaltenen Programme, Darstellungen und Informationen wurden nach bestem Wis-sen erstellt und mit Sorgfalt getestet. Dennoch sind Fehler nicht ganz auszuschließen. Aus diesem Grundist das in dem vorliegenden Buch enthaltene Programm-Material mit keiner Verpflichtung oder Garan-tie irgendeiner Art verbunden. Autoren und Verlag übernehmen infolgedessen keine Verantwortung undwerden keine daraus folgende Haftung übernehmen, die auf irgendeine Art aus der Benutzung diesesProgramm-Materials, oder Teilen davon, oder durch Rechtsverletzungen Dritter entsteht.

Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. in diesem Buch be-rechtigt auch ohne besondere Kennzeichnung nicht zu der Annahme, dass solche Namen im Sinne derWarenzeichen- und Markenschutz-Gesetzgebung als frei zu betrachten wären und daher von jedermannverwendet werden dürften.

Alle Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt und sind möglicher-weise eingetragene Warenzeichen. Der Verlag richtet sich im Wesentlichen nach den Schreibweisen derHersteller. Andere hier genannte Produkte können Warenzeichen des jeweiligen Herstellers sein.

Dieses Werk ist urheberrechtlich geschützt.Alle Rechte, auch die der Übersetzung, des Nachdruckes und der Vervielfältigung des Buches, oder Teilendaraus, vorbehalten. Kein Teil des Werkes darf ohne schriftliche Genehmigung des Verlages in irgendei-ner Form (Druck, Fotokopie, Microfilm oder einem anderen Verfahren), auch nicht für Zwecke der Unter-richtsgestaltung, reproduziert oder unter Verwendung elektronischer Systeme verarbeitet, vervielfältigtoder verbreitet werden.

Bibliografische Information Der Deutschen Bibliothek

Die Deutsche Bibliothek verzeichnet diese Publikation in der DeutschenNationalbibliografie; detaillierte bibliografische Daten sind im Internet überhttp://dnb.ddb.de abrufbar.ISBN 3-938626-17-7

© 2010 Nicolaus Millin Verlag GmbH, Lohmar (http://www.millin.de)Umschlaggestaltung: millin Verlag, http://www.millin.de

Gesamtlektorat: Nicolaus MillinFachlektorat: Dieter Bloms, Jörg Dippel, Klaas Freitag, Bruno Gerz, Bernhard Hoelcker, Björn Jacke, An-dreas Jaeger, Dirk Pankonin, Wolfgang Rosenauer, Christian Steinrücken, Peter VarkolySatz: LATEXDruck: druckhaus köthen GmbH, Köthen (http://www.koethen.de

Printed in Germany on acid free paper.

Page 3: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

1 Einführendes Beispiel 3

1.1 Erste wesentliche C-Regeln . . . . . . . . . . 3

1.2 Zeilen-Kommentare mit // (neu in C99) . . . . . . . 5

1.3 Gute Lesbarkeit von Programmen . . . . . . . . . 5

1.4 Vermeiden von geschachtelten Kommentaren . . . . . . 6

2 Elementare Datentypen 7

2.1 Die Grunddatentypen in C . . . . . . . . . . 7

2.2 Wertebereiche für die einzelnen Datentypen . . . . . . . 9

2.3 Fallgrube: Verlust von Bits bei zu großen Zahlen . . . . . . 10

3 Konstanten 11

3.1 char-Konstanten . . . . . . . . . . . . 11

3.2 Ganzzahlige Konstanten . . . . . . . . . . . 11

3.3 Gleitpunktkonstanten . . . . . . . . . . . 12

4 Variablen 13

4.1 Variablen und die C-Regeln für Variablennamen . . . . . . 13

4.2 Tipps zur Wahl der Variablennamen . . . . . . . . 14

4.3 Deklaration von Variablen . . . . . . . . . . 14

4.4 Tipp: Variablen bereits bei Deklaration dokumentieren . . . . 16

5 Ausdrücke und Operatoren 17

5.1 Der einfache Zuweisungsoperator . . . . . . . . . 17

5.1.1 Allgemeines zum einfachen Zuweisungsoperator . . . . 17

5.1.2 Initialisierung von Variablen . . . . . . . . 19

5.2 Arithmetische Operatoren . . . . . . . . . . 19

5.2.1 Die arithmetischen Operatoren . . . . . . . . 19

V

Page 4: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

5.2.2 Die C-Begriffe Ausdruck und Anweisung . . . . . . 20

5.2.3 Ausgabe von int-Variablen und -Ausdrücken . . . . . 21

5.2.4 Ausgabe von Gleitpunkt-Variablen und -Ausdrücken . . . 21

5.2.5 Fallgrube: Ganzzahl- statt Gleitpunktdivision . . . . . 22

5.3 Vergleichsoperatoren . . . . . . . . . . . 23

5.3.1 Die unterschiedlichen Vergleichsoperatoren . . . . . 23

5.3.2 Die zwei Wahrheitswerte von Vergleichen . . . . . . 23

5.3.3 Prioritäten der Vergleichsoperatoren . . . . . . . 23

5.4 Logische Operatoren . . . . . . . . . . . 24

5.4.1 TRUE und FALSE in C . . . . . . . . . . 24

5.4.2 Der Datentyp _Bool (neu in C99) . . . . . . . 24

5.4.3 Die C-Operatoren für NOT, AND und OR im Überblick . . . 25

5.4.4 Der Negations-Operator ! . . . . . . . . . 25

5.4.5 Der AND-Operator && . . . . . . . . . 26

5.4.6 Der OR-Operator || . . . . . . . . . . 26

5.4.7 Die Priorität der logischen Operatoren . . . . . . 26

5.4.8 Keine unnötige Auswertung rechts von &&und || . . . . 27

5.4.9 Übung: Überprüfungen mit logischen Operatoren . . . . 28

5.5 Bit-Operatoren . . . . . . . . . . . . . 28

5.5.1 Bitweise Invertierung mit ~ . . . . . . . . . 28

5.5.2 Bitweise AND-Verknüpfung mit & . . . . . . . 30

5.5.3 Bitweise OR-Verknüpfung mit | . . . . . . . . 31

5.5.4 Bitweise XOR-Verknüpfung mit ^ . . . . . . . 33

5.5.5 Bit-Operatoren nur für ganzzahlige Datentypen erlaubt . . . 34

5.5.6 Fallgruben . . . . . . . . . . . . 34

5.5.7 Übung: Überprüfungen mit Bit-Operatoren . . . . . 36

5.6 Shift-Operatoren . . . . . . . . . . . . 37

5.6.1 Die beiden Shift-Operatoren <<und >> . . . . . . 37

5.6.2 Shift-Operatoren nur für ganzzahlige Datentypen erlaubt . . 38

5.6.3 Priorität der Shift-Operatoren . . . . . . . . 38

5.7 Zusammengesetzte Zuweisungsoperatoren . . . . . . . 39

5.7.1 Die zusammengesetzten Zuweisungsoperatoren . . . . 39

5.8 Inkrement- und Dekrement-Operatoren . . . . . . . . 40

5.8.1 Inkrementieren und Dekrementieren mit ++ und -- . . . . 40

5.8.2 Präfix- und Postfix-Schreibweise für ++ und -- . . . . . 40

5.8.3 ++ und -- ist nur für Variablen erlaubt . . . . . . 42

5.8.4 ++ und -- ist nicht auf linken Seite einer Zuweisung erlaubt . . 42

VI

Page 5: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

5.9 Prioritätstabelle für Operatoren . . . . . . . . . 42

5.10 Assoziativität der Operatoren . . . . . . . . . . 43

5.11 Erlaubte und unerlaubte Operationen für C-Datentypen . . . . 43

5.12 Priorität und Auswertungszeitpunkt bei ++ und -- . . . . . 43

5.13 Fallgrube: Zugriff auf nicht vorbesetzte Variablen . . . . . . 45

5.14 Übungen . . . . . . . . . . . . . . 46

6 Symbolische Konstanten 47

6.1 Konstanten-Definition mit #define . . . . . . . . . 47

6.1.1 Die Direktive #define . . . . . . . . . . 47

6.1.2 Regeln für Konstanten-Namen bei #define . . . . . . 49

6.1.3 Konstanten machen Programm leicht änderbar . . . . . 49

6.2 Konstanten-Definition mit const . . . . . . . . . 49

7 Ein- und Ausgabe 51

7.1 Headerdateien und #include . . . . . . . . . . 51

7.1.1 Bibliotheken und Headerdateien . . . . . . . 51

7.1.2 Eigene Headerdateien . . . . . . . . . . 52

7.2 Ein- und Ausgabe eines Zeichens . . . . . . . . . 53

7.2.1 getchar() und putchar() . . . . . . . . . 53

7.2.2 Gepufferte Eingabe bei getchar() . . . . . . . . 53

7.2.3 Puffer-Bereinigung mit Dummy getchar() . . . . . . 57

7.2.4 Puffer-Bereinigung ist nicht immer notwendig . . . . . 58

7.2.5 Fallgrube: Zahlen nicht mit getchar() einlesen . . . . . 60

7.2.6 Die Headerdatei <ctype.h> . . . . . . . . 60

7.2.7 Einfache Makros . . . . . . . . . . . 62

7.3 Die Ausgabe mit printf() . . . . . . . . . . . 67

7.3.1 Die Funktion printf() . . . . . . . . . . 67

7.3.2 Fallgruben . . . . . . . . . . . . 74

7.3.3 Tipps . . . . . . . . . . . . . 75

7.4 Die Eingabe mit scanf() . . . . . . . . . . . 77

7.4.1 Die Funktion scanf() . . . . . . . . . . 77

7.4.2 Fallgruben . . . . . . . . . . . . 83

7.4.3 Die Headerdatei <math.h> . . . . . . . . . 86

7.4.4 Fallgrube: Vergessen von #include <math.h> . . . . . 88

8 Datentypumwandlungen 91

8.1 Implizite Datentypumwandlungen . . . . . . . . 91

VII

Page 6: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

8.1.1 Der sizeof-Operator . . . . . . . . . . 91

8.1.2 Implizite Datentypumwandlungen . . . . . . . 93

8.1.3 Fallgrube: Zuweisen von Ganzzahlausdrücken an Gleitpunktvariablen 97

8.2 Explizite Datentypumwandlungen . . . . . . . . . 98

8.2.1 Explizite Datentypumwandlungen mit cast-Operator . . . 98

8.2.2 Fallgruben . . . . . . . . . . . . 98

9 Die Headerdateien <limits.h und <float.h> 101

9.1 <limits.h> - Grenzwerte von Ganzzahltypen . . . . . . 101

9.2 <float.h> – Grenzwerte von Gleitpunkt-Datentypen . . . . . 102

10 Anweisungen und Blöcke 103

11 Die if-Anweisung 105

11.1 Die zweiseitige if-Anweisung . . . . . . . . . . 105

11.2 Die einseitige if-Anweisung . . . . . . . . . . 110

11.3 Verschachtelte if-Anweisungen . . . . . . . . . 112

11.4 Tipp: Einrücken untergeordneter Programmteile . . . . . . 113

11.5 Fallgruben . . . . . . . . . . . . . 114

11.5.1 Falsche Gleichheitsüberprüfung . . . . . . . . 114

11.5.2 Keine unnötige Auswertung rechts von && und || . . . . 115

11.5.3 Vergleiche von negativen Zahlen mit unsigned-Variablen . . 116

11.5.4 Hohe Priorität des Negations-Operators ! . . . . . . 116

11.6 Programmiertechniken . . . . . . . . . . . 117

11.6.1 if-Kaskaden . . . . . . . . . . . . 117

12 Die bedingte Bewertung ?: 119

13 Die switch-Anweisung 121

13.1 Die switch-Anweisung . . . . . . . . . . . 121

13.2 Fallgrube: case-Marken müssen ganzzahlige Konstanten sein . . . 125

13.3 Tipps . . . . . . . . . . . . . . . 126

13.3.1 Alle case-Marken (auch letzte) mit break abschließen . . . 126

13.3.2 default immer angeben . . . . . . . . . 126

14 Der Komma-Operator 127

14.1 Der Komma-Operator . . . . . . . . . . . 127

14.2 Komma-Operator hat die niedrigste Priorität . . . . . . 128

VIII

Page 7: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

15 Die for-Anweisung 129

15.1 Die for-Anweisung . . . . . . . . . . . . 129

15.2 Die for-Schleife und der Komma-Operator . . . . . . . 133

15.3 Fallgrube: Semikolon am Ende des for-Schleifenkopfs . . . . . 136

15.4 Geschachtelte Schleifen . . . . . . . . . . . 137

15.5 Eine endlose for-Schleife . . . . . . . . . . . 143

15.6 for bei Durchläufen mit festen Schrittweiten . . . . . . . 143

15.7 Variablendeklaration im for-Schleifenkopf (neu in C99) . . . . 146

15.8 Programmiertechniken . . . . . . . . . . . 146

15.8.1 Anhalten einer Bildschirmausgabe . . . . . . . 146

15.8.2 Zeilenvorschübe bei geschachtelten Schleifen . . . . . 149

15.8.3 Kombinieren mit for-Schleifen . . . . . . . . 150

15.8.4 Zwischeninformationen bei rechenintensiven Programmen . . 152

15.8.5 Merker in for-Schleifen bei Eintreten von Ereignissen . . . 153

15.9 Fallgruben . . . . . . . . . . . . . 154

15.9.1 Niemals die Laufvariable im Schleifenkörper ändern . . . 154

15.9.2 Gleitpunktzahlen niemals auf Gleichheit prüfen . . . . 157

15.9.3 Laufvariable einer for-Schleife läuft über Endwert hinaus . . 159

16 Die while-Anweisung 161

16.1 Die while-Anweisung . . . . . . . . . . . 161

16.2 Programmiertechniken . . . . . . . . . . . 163

16.2.1 while bei unbekannter Zahl von Schleifendurchläufen . . . 163

16.2.2 Konsistenzprüfungen bei Eingaben . . . . . . . 165

16.2.3 Die Konstante EOF . . . . . . . . . . 166

16.2.4 Minimum und Maximum in einer Zahlenfolge . . . . . 167

16.3 Zufallszahlen in C . . . . . . . . . . . . 168

17 Die do. . . while-Anweisung 175

17.1 Die do. . . while-Anweisung . . . . . . . . . . 175

17.2 Programmiertechniken . . . . . . . . . . . 177

17.2.1 do. . . while-Schleifen nicht so oft wie while-Schleifen . . . 177

17.2.2 Abschließendes } while immer in einer Zeile . . . . 178

18 Die break-Anweisung 179

18.1 Die break-Anweisung . . . . . . . . . . . 179

18.2 break bewirkt Verlassen einer Schleifenebene . . . . . . 180

18.3 Programmiertechniken . . . . . . . . . . . 180

IX

Page 8: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

18.3.1 Sofortiges Verlassen von Schleifen und switch . . . . . 180

18.3.2 Endlosschleifen und break . . . . . . . . . 182

19 Die continue-Anweisung 183

19.1 Die continue-Anweisung . . . . . . . . . . . 183

19.2 Programmiertechniken . . . . . . . . . . . 184

19.2.1 continue nur im äußersten Notfall . . . . . . . 184

19.2.2 Korrekte Programme müssen auch schnell sein . . . . . 185

19.3 Datums- und Zeitangaben (<time.h>) . . . . . . . . 189

19.3.1 Konstanten und Datenytpen . . . . . . . . 189

19.3.2 Funktionen . . . . . . . . . . . . 189

19.3.3 Beispiele zu Funktionen aus <time.h> . . . . . . 192

20 Marken und die goto-Anweisung 197

20.1 Marken und die goto-Anweisung . . . . . . . . . 197

20.2 Programmiertechniken . . . . . . . . . . . 197

20.2.1 goto nur im äußersten Notfall . . . . . . . . 197

20.2.2 Lesbarere und schnellere Programme mit goto . . . . . 198

21 Grafikprogrammierung unter Linux 199

21.1 Benutzung von LCGI . . . . . . . . . . . 199

21.2 Grafikmodus ein- und ausschalten . . . . . . . . . 200

21.3 Eingaben im Grafikmodus . . . . . . . . . . 200

21.4 Bildschirm-, Farben- und Pixel-Operationen . . . . . . . 204

21.5 Positionieren, Linien zeichnen und Farbe einstellen . . . . . 207

21.6 Figuren zeichnen und ausfüllen . . . . . . . . . 209

21.7 Einstellungen für Textausgaben . . . . . . . . . 215

21.8 Bilder laden, Bildteile speichern und einblenden . . . . . . 217

21.9 Kuchenstücke malen . . . . . . . . . . . 220

21.10Grafikpaket neu bzw. anders einrichten . . . . . . . . 222

21.11Arbeiten mit mehreren Zeichenfenstern . . . . . . . . 223

21.12Programmierung der Maus . . . . . . . . . . 223

21.13Transformation mathematischer Koordinaten . . . . . . 226

22 Funktionen 231

22.1 Allgemeines zu Funktionen . . . . . . . . . . 231

22.1.1 Allgemeines Beispiel zu Funktionen . . . . . . . 231

22.1.2 Die Begriffe Parameter und Argumente . . . . . . 233

X

Page 9: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

22.1.3 Bibliotheken und Headerdateien . . . . . . . 233

22.2 Erstellen eigener Funktionen . . . . . . . . . . 234

22.2.1 Definition von Funktionen in C89/C99 . . . . . . 234

22.2.2 Definition von Funktionen in Alt-C . . . . . . . 237

22.2.3 Die return-Anweisung . . . . . . . . . . 238

22.2.4 Funktionen ohne Rückgabewert . . . . . . . . 238

22.2.5 Forward-Deklarationen . . . . . . . . . 239

22.2.6 Funktions-Prototypen . . . . . . . . . . 242

22.2.7 Implizite Datentypumwandlung beim Funktionsaufruf . . . 246

22.2.8 Typische Anwendungsgebiete von Funktionen . . . . . 248

22.3 Die Parameter von Funktionen . . . . . . . . . 253

22.3.1 Leere Parameterliste durch Angabe von void . . . . . 253

22.3.2 Bei Funktionsaufrufen findet nur Wertübergabe statt . . . 253

22.3.3 Call by reference . . . . . . . . . . . 258

22.3.4 Auswertung der Argumente findet vor Funktionsaufruf statt . . 260

22.3.5 Fallgruben . . . . . . . . . . . . 261

22.4 Ellipsen-Prototypen für Funktionen mit variabler Argumentzahl . . 263

22.4.1 Reihenfolge der Argument-Ablage im Stack . . . . . 263

22.4.2 Ellipsen-Prototypen . . . . . . . . . . 264

22.4.3 Abarbeiten variabel langer Argumentlisten . . . . . 264

22.4.4 Verfahren zum Abarbeiten variabel langer Argumentlisten . . 265

22.4.5 Fallgruben . . . . . . . . . . . . 269

22.5 Neuheiten in C99 . . . . . . . . . . . . 270

22.5.1 Inline-Funktionen . . . . . . . . . . 270

22.5.2 Der vordefinierte Name __func__ . . . . . . . 271

22.5.3 Keine Unterstützung von implizitem int . . . . . . 272

22.5.4 Keine impliziten Funktionsdeklarationen . . . . . . 272

22.5.5 Einschränkungen bei return . . . . . . . . 272

22.6 Rekursive Funktionen . . . . . . . . . . . 273

22.6.1 Allgemeines zu rekursiven Funktionen . . . . . . 273

22.6.2 Einige typische Anwendungen für die Rekursion . . . . 276

22.7 Zeiger auf Funktionen . . . . . . . . . . . 280

22.7.1 Zeiger auf Funktionen . . . . . . . . . . 280

22.7.2 Typische Anwendungen . . . . . . . . . 283

23 Speicherklassen und Modultechnik 287

23.1 Gültigkeitsbereich, Lebensdauer, Speicherort . . . . . . 287

XI

Page 10: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

23.1.1 Gültigkeitsbereich . . . . . . . . . . 287

23.1.2 Lebensdauer . . . . . . . . . . . . 291

23.1.3 Speicherort . . . . . . . . . . . . 292

23.1.4 Gültigkeit, Lebensdauer und Speicherort im Überblick . . . 292

23.1.5 Übung: Ausgabe des Programms block3.c . . . . . 293

23.2 Schlüsselwörter extern, auto, static und register . . . . . . 293

23.2.1 Das Schlüsselwort extern . . . . . . . . . 293

23.2.2 Das Schlüsselwort auto . . . . . . . . . 296

23.2.3 Fallgrube: Niemals Adressen von auto-Variablen zurückgeben . 303

23.2.4 Das Schlüsselwort static . . . . . . . . . 304

23.2.5 Das Schlüsselwort register . . . . . . . . . 310

23.3 Die Schlüsselwörter const und volatile . . . . . . . . 310

23.3.1 Das Schlüsselwort const . . . . . . . . . 310

23.3.2 Das Schlüsselwort volatile . . . . . . . . . 312

23.3.3 Kombination von const und volatile . . . . . . . 313

23.4 Modultechnik und Information Hiding . . . . . . . . 314

23.4.1 Linker und Compiler . . . . . . . . . . 317

23.4.2 Beispiel: Simulation von Turingmaschinen . . . . . 319

24 Präprozessor-Direktiven 331

24.1 Bedingte Kompilierung . . . . . . . . . . . 332

24.1.1 Präprozessor-Direktiven zur bedingten Kompilierung . . . 332

24.1.2 Typische Anwendungen . . . . . . . . . 334

24.1.3 Testen mit Makro assert() aus Headerdatei <assert.h> . . . 339

24.2 Einkopieren von anderen Headerdateien . . . . . . . 340

24.2.1 Die Präprozessor-Direktive #include . . . . . . . 340

24.2.2 Typische Anwendungen . . . . . . . . . 341

24.3 Definition von Makros (#define und #undef) . . . . . . . 342

24.3.1 Definition von Konstanten mit #define . . . . . . 342

24.3.2 Definition von Funktionsmakros mit #define . . . . . 343

24.3.3 Operator #: Ersetzung von Makroparametern durch String . . 345

24.3.4 Operator ##: Zusammensetzen neuer Namen . . . . . 346

24.3.5 Rekursive Makrodefinitionen . . . . . . . . 346

24.3.6 Makros mit variabler Anzahl von Argumenten (neu in C99) . . 348

24.3.7 Makrodefinitionen mit #undef wieder aufheben . . . . 349

24.3.8 Unterschiede zwischen Funktionen und Makros . . . . 349

24.4 Vordefinierte Makronamen . . . . . . . . . . 353

XII

Page 11: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

24.5 Die restlichen Präprozessor-Direktiven . . . . . . . . 354

24.5.1 #line – Festlegen einer neuen Zeilennumerierung . . . . 354

24.5.2 #error – Ausgeben von Fehlermeldungen . . . . . . 355

24.5.3 #pragma – Festlegen von compilerspezifischem Verhalten . . 355

24.5.4 # – Die Null-Direktive . . . . . . . . . . 355

25 Zeiger und Arrays 357

25.1 Eindimensionale Arrays . . . . . . . . . . . 357

25.1.1 Eindimensionale Arrays . . . . . . . . . 357

25.1.2 Nur statische Arrays erlaubt (in C89) . . . . . . . 361

25.1.3 Von Arrays belegter Speicherplatz . . . . . . . 362

25.1.4 Fallgruben . . . . . . . . . . . . 363

25.2 Mehrdimensionale Arrays . . . . . . . . . . 365

25.2.1 Zweidimensionale Arrays . . . . . . . . . 365

25.2.2 Drei-, vier-, fünf- und sonstige mehrdimensionale Arrays . . 373

25.2.3 sizeof liefert die Größe eines Arrays . . . . . . . 373

25.3 Zusammenhänge zwischen Arrays und Zeigern . . . . . . 374

25.3.1 Arrayname ist konstanter Zeiger auf erstes Element . . . . 374

25.3.2 Zugriff auf Arrayelemente ist auch über Zeiger möglich . . . 377

25.3.3 Unterschied zwischen Arraynamen und echtem Zeiger . . . 380

25.3.4 Erlaubte Operationen mit Zeigern . . . . . . . 381

25.3.5 Unerlaubte Operationen mit Zeigern . . . . . . . 381

25.3.6 Übergabe eines Arrays an eine Funktion mittels Adresse . . . 384

25.3.7 call by value für Arrays (Zeiger) . . . . . . . . 388

25.3.8 Nachlese zu Arrays und Zeiger . . . . . . . . 389

25.3.9 Algorithmus: Der Bubble-Sort . . . . . . . . 389

25.3.10 Verwendung der Bibliotheksfunktion qsort() . . . . . 390

25.4 Strings und char-Zeiger . . . . . . . . . . . 392

25.4.1 Besonderheiten von C-Strings . . . . . . . . 392

25.4.2 Das Schlüsselwort restrict für Zeiger (neu in C99) . . . . 394

25.4.3 Eigene Realisierung der Funktion strcpy() mit Arrays . . . 394

25.4.4 Eigene Realisierung der Funktion strcpy() mit Zeigern . . . 395

25.4.5 Die Headerdatei <string.h> . . . . . . . . . 398

25.4.6 Umwandeln von Strings in numerische Werte . . . . . 413

25.4.7 Umwandeln von numerischen Werten in Strings . . . . 419

25.4.8 Besonderheiten beim Einlesen von Strings mit scanf() . . . 421

25.4.9 Ein- und Ausgabe von Strings mit gets() und puts() . . . . 422

XIII

Page 12: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

25.4.10 Unterschied zwischen Zeiger- und Array-Deklaration . . . 423

25.4.11 Direkter Zugriff auf Zeichen in einer String-Konstante . . . 425

25.5 Array-Initialisierungen . . . . . . . . . . . 426

25.5.1 Initialisierung von Arrays . . . . . . . . . 426

25.5.2 Dimensionierungsangaben bei der Initialisierung . . . . 428

25.5.3 Zeiger auf unbenamte Arrays (neu in C99) . . . . . 429

25.5.4 Implizite Initialisierung bei static-Variablen/Arrays . . . . 430

25.5.5 Initialisierung lokaler Variablen auch mit Nicht-Konstanten . . 431

25.5.6 Initialisierung von lokalen Arrays in C89/C99 . . . . . 432

25.5.7 Initialisierung von lokalen Arrays mit variablen Werten (neu in C99) 432

25.5.8 Initialisierung von lokalen Arrays mit 0 oder NULL . . . . 433

25.5.9 Initialisierte Arrays mit const vor Überschreiben schützen . . 434

25.6 Lokale Arrays variabler Länge (neu in C99) . . . . . . . 435

25.7 Zeigerarrays und Zeiger auf Zeiger . . . . . . . . 436

25.7.1 Einfache Zeigerarrays . . . . . . . . . . 436

25.7.2 Zeiger auf Arrays . . . . . . . . . . . 437

25.7.3 Vertauschen von zwei Arrays über Zeiger . . . . . . 438

25.7.4 Übergabe von Arrays an Funktionen . . . . . . . 440

25.7.5 Zeiger-Zeiger . . . . . . . . . . . 441

25.7.6 Unterschiede bei zweidimensionalen Arrays und Zeigerarrays . 442

25.7.7 Zugriff auf beliebige Elemente in einem Zeigerarray . . . 445

25.7.8 Zeigerarrays mit Funktionsadressen . . . . . . . 451

26 Argumente auf der Kommandozeile 453

26.1 Die Parameter argc und argv der Funktion main() . . . . . 453

26.2 Optionen auf der Kommandozeile . . . . . . . . . 456

27 Dynamische Speicher-Reservierung und -Freigabe 463

27.1 Nachteile von statischen Arrays . . . . . . . . . 463

27.1.1 Gefahr der Speicherüberschreibung . . . . . . . 464

27.1.2 Speicherplatzvergeudung . . . . . . . . . 465

27.2 Speicher reservieren mit malloc() . . . . . . . . . 466

27.2.1 Die Funktion malloc() . . . . . . . . . . 466

27.2.2 Dynamische Arrays für beliebige Datentypen . . . . . 470

27.2.3 Konvertierung von void-Zeigern . . . . . . . 473

27.3 Speicher reservieren und initialisieren mit calloc() . . . . . 474

27.4 Größenänderung eines allozierten Speichers mit realloc() . . . . 475

XIV

Page 13: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

27.4.1 Die Funktion realloc() . . . . . . . . . . 475

27.4.2 Besonderheiten der Funktion realloc() . . . . . . 478

27.4.3 Schnellere Programme mit größeren Speicherblöcken . . . 479

27.5 Freigeben von dynamisch reservierten Speicherbereich . . . . 481

27.5.1 Die Funktion free() . . . . . . . . . . 481

27.5.2 Fallgrube: free() setzt übergebenen Zeiger nicht auf NULL . . 481

27.5.3 Tipp: Eigenes Makro zur Freigabe von dynamischen Speicher . . 483

27.6 Fallgruben . . . . . . . . . . . . . 484

27.6.1 free() nur auf von malloc(), calloc() und realloc() gelieferte Zeiger . 484

27.6.2 Allozieren von Speicherplatz in einer Funktion . . . . . 485

27.7 Programmiertechnik: Dynamische Zeiger-Arrays . . . . . . 488

27.8 Fallgrube: free() bei Zeiger-Arrays . . . . . . . . . 489

28 Strukturen 491

28.1 Deklaration und Definition von Strukturen . . . . . . . 491

28.1.1 Deklaration von Strukturen . . . . . . . . . 491

28.1.2 Wichtige Regeln und Hinweise für Strukturdeklarationen . . 492

28.1.3 Definition von Strukturvariablen . . . . . . . 493

28.1.4 Zusammenfassung von Strukturdeklaration und -definition . . 494

28.1.5 Namenlose Strukturen . . . . . . . . . . 495

28.2 Operationen mit Strukturvariablen . . . . . . . . . 496

28.2.1 Zugriff auf Strukturkomponenten mittels Punktoperator . . . 496

28.2.2 Zuweisung zwischen Strukturkomponenten . . . . . 497

28.2.3 Zuweisung ganzer Strukturvariablen . . . . . . . 502

28.2.4 Vergleich von Strukturvariablen ist nicht möglich . . . . 502

28.2.5 Casting für komplette Strukturvariable ist nicht möglich . . . 503

28.2.6 Adreß- und sizeof-Operator für Strukturvariablen erlaubt . . 503

28.3 Initialisierung von Strukturvariablen . . . . . . . . 504

28.3.1 Initialisierung von Strukturvariablen in C89 und C99 . . . 504

28.3.2 Initialisierung von Strukturvariablen (nur in C99) . . . . 505

28.4 Strukturarrays . . . . . . . . . . . . . 507

28.5 Strukturen als Funktionsparameter . . . . . . . . 514

28.6 Zeiger und Strukturen . . . . . . . . . . . 516

28.6.1 Allgemeines zu Zeiger und Strukturen . . . . . . 516

28.6.2 Dynamische Strukturarrays . . . . . . . . 522

28.6.3 Rekursive Strukturen . . . . . . . . . . 529

28.7 Strukturen mit variabel langen Arrays (neu in C99) . . . . . 558

XV

Page 14: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

28.8 Spezielle Strukturen (Unions und Bitfelder) . . . . . . . 559

28.8.1 Unions . . . . . . . . . . . . . 559

28.8.2 Bitfelder . . . . . . . . . . . . 564

29 Eigene Datentypen 569

29.1 Definition eigener Datentypnamen mit typedef . . . . . . 569

29.1.1 Vergabe neuer Namen an existierende Datentypen mit typedef . 569

29.1.2 Höhere Portabilität und bessere Lesbarkeit durch typedef . . 572

29.2 Definition eigener Datentypen mit enum . . . . . . . 573

29.2.1 Definition eigener Datentypen mit enum . . . . . . 573

29.2.2 Regeln für enum . . . . . . . . . . . 575

30 Dateien 577

30.1 Höhere E/A-Funktionen . . . . . . . . . . . 577

30.1.1 Vordefinierte Struktur FILE . . . . . . . . . 578

30.1.2 Öffnen und Schließen von Dateien . . . . . . . 578

30.1.3 Lesen und Schreiben in Dateien . . . . . . . . 580

30.1.4 Unterschied zwischen Text- und Binärmodus . . . . . 596

30.1.5 Positionieren in Dateien . . . . . . . . . 598

30.1.6 Öffnen einer Datei mit existierenden Stream . . . . . 601

30.1.7 Löschen und Umbenennen von Dateien . . . . . . 603

30.1.8 Pufferung . . . . . . . . . . . . 603

30.1.9 Temporäre Dateien . . . . . . . . . . 605

30.1.10 Ausgabe von System-Fehlermeldungen . . . . . . 608

31 Anhang 613

31.1 Prioritätstabelle für die Operatoren . . . . . . . . 613

31.2 C-Schlüsselwörter . . . . . . . . . . . . 613

31.3 Wertebereiche für die einzelnen Datentypen . . . . . . . 614

31.4 Die Funktion printf() . . . . . . . . . . . 615

31.5 Die Funktion scanf() . . . . . . . . . . . 617

31.6 ASCII-Tabelle . . . . . . . . . . . . . 619

XVI

Page 15: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

Vorwort

Ein paar Worte zu C und seiner Geschichte

Zu Beginn wird hier kurz auf die Historie von C und die verschiedenen Standardisierungenvon C eingegangen.

Die Entstehung von C

Die Sprache C wurde im Jahre 1972 von Dennis M.Ritchie in den Bell-Laboratorien bei AT&Tentwickelt und von Brian W. Kernighan in den Jahren 1973/74 weiter verbessert. Vorläufer vonC waren die Sprachen BCPL (Basic Combined Programming Language) und B.C war schon immer sehr eng mit dem Betriebssystem Unix verbunden, da die Sprache C aufdiesem damals noch jungen Betriebssystem entwickelt wurde und Unix wiederum selbst mitallen seinen Dienstprogrammen nahezu vollständig in C geschrieben wurde. In den 80er Jah-ren hat sich aber C als eine universell einsetzbare Sprache entpuppt, was dazu führte, dassC heute auf nahezu jedem beliebigen Betriebssystem (Linux, Unix-Systeme, MS-DOS, Win-dows95/98/NT/. . . , VMS, OS/2, . . . ) angeboten wird.In den 1970er und 1980er Jahren gab es keine Standardbeschreibung zur Sprache C. Statt dessengalt die 1. Ausgabe des Buches „The C Programming Language“ von Kernighan und Ritchie (Pren-tice Hall, 1978) als die Bibel für alle C-Fragen. Diese „Bibel“ ließ jedoch einige Fragen offen. Sowurde bereits in den frühen 80er Jahren die Notwendigkeit für einen wirklichen C-Standarderkannt:

❏ C89 – der erste Standard für CIm Jahre 1983 begann das ANSI-Komitee X3J11 1 mit dem Unterfangen, die Sprache Czu standardisieren. Im selben Jahr noch entschied das Komitee X3J11, dass nur ein C-Standard geschaffen werden soll, welcher von beiden Organisationen ANSI und ISO ver-abschiedet wird. C wurde zum ersten Mal Ende des Jahres 1989 mit der Annahme desANSI-Standards standardisiert. Diese Version von C wird allgemein als C89 bezeichnet.Dieser Standard wurde auch im Jahre 1990 von ISO übernommen. C89 wurde im Jahre1995 leicht verbessert.

❏ C99 – der neue Standard für CIm Jahre 1999 wurde ein neuer Standard für C geschaffen. Diese Version nennt sich ISOC99, oder kurz auch nur C99. C99 enthält eine Reihe von Verbesserungen und einige neueKonstrukte, welche teilweise von C++ übernommen wurden.Alle C-Programme, die die von C99 vorgegebenen Vorschriften einhalten, werden C99kompatibel genannt. Solche Programme haben den Vorteil, dass sie leicht portierbar sind,also ohne größere Änderungen von einem anderen C99-Compiler auf einer anderen Ma-schine in eine ablauffähige Version übersetzt werden können.

C als Vorstufe zu C ++

C++ wurde – beginnend im Jahr 1979 – von Bjarne Stroustrup entwickelt. C++, das eine objektori-entierte Version zu C ist, hat sich inzwischen sehr verbreitet. Da aber C++ nur eine Erweiterungzu C ist, muss auch jeder, der mit C++ programmieren will, die Sprache C richtig beherrschen,bevor er in die höheren Sphären der objektorientierten Programmierung aufsteigen kann.

1ANSI (American National Standard Institute) ist eine amerikanische Organisation, welche Mitglied derInternational Standards Organisation (ISO) ist.

1

Page 16: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Inhaltsverzeichnis

Hinweise zu diesem Buch

Dieses Buch beschreibt die Theorie der Programmiersprache C anhand vieler Beispiele. Da-bei begnügt es sich jedoch nicht allein mit der Vorstellung der einzelnen C-Elemente, sondernvermittelt dem C-Neuling auch Einblicke in wichtige Grundlagen der Informatik. Zudem gibtes auch zu den einzelnen C-Konstruktionen Programmiertechniken aus der C-Praxis, typischeAnwendungsgebiete, Tipps und Fallgruben, die in C leider nicht allzu selten sind. Diese Grund-kenntnisse bilden das Fundament, das für eine erfolgreiche Programmierung in C unverzicht-bar ist.

Nach dem Durcharbeiten dieses Buches verfügt der Leser über ein gesundes und breites C-Fundament, und ist in der Lage, erfolgreich in C zu programmieren. Die Intention dieses Buchesist es nämlich:

❏ den C-Anfänger systematisch vom C-Basiswissen bis hin zu den fortgeschrittenen Tech-niken der Programmierung zu führen.

❏ dem bereits erfahrenen C-Programmierer – aufgrund der Vielzahl von Tipps, fundamen-talen Algorithmen und nützlichen Programmiertechniken – eine Vertiefung bzw. Ergän-zung seines C-Wissens zu ermöglichen.

Layout der Programme in diesem Buch

Es sei vorweg darauf hingewiesen, dass sich die in diesem Buch vorgestellten Programme nichtimmer an die allgemein gültigen Programmier-Richtlinien halten. So befinden sich z. B. manch-mal mehrere Anweisungen in einer Zeile. Dies wurde sowohl aus Platzgründen als auch ausLayout-Gesichtspunkten, die in einem solchen Buch einzuhalten sind, leider notwendig, dennein Programmlisting, bei dem sich eventuell die entscheidenden Anweisungen über zwei Sei-ten verteilen, ist sicherlich aus didaktischen Gründen hinsichtlich Lesbarkeit ungünstiger alsein Programm, das sich vollständig auf einer Seite befindet, ohne dass der Leser ständig vor-und zurückblättern muss.

Downloads zu diesem Buch

Alle Programme in diesem Buch können von folgender Webseite

http://www.millin.de

heruntergeladen werden.

Windows-Kompatibilität

Auch wenn dieses Buch ursprünglich für die C-Programmierung unter Linux konzipiert wur-de, so sind doch nahezu alle in diesem Buch vorgestellten Programme auch unter Windows-Compilern lauffähig. Einschränkungen gibt es lediglich bei einigen Windows-Compilern, dienoch nicht den neuesten C99-Standard implementiert haben, aber das betrifft nur einige weni-ge Programme in diesem Buch.

Auch zu der ursprünglich für Linux eigens im Rahmen dieses Buches entwickelten Graphik-bibliothek LCGI existiert zwischenzeitlich eine Windows-Version, die von der oben erwähntenWebseite heruntergeladen werden kann.

2

Page 17: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 1

Einführendes Beispiel

1.1 Erste wesentliche C-Regeln

Das erste C-Programm erst.c :

/ *************************************************** ************ /

/ * Einfuehrendes Beispiel * /

/ *************************************************** ************ /

#include <stdio.h>

int main(void)

{

printf(" *************************************************** \n");

printf(" * * \n");

printf(" * Das ist mein erstes C-Programm * \n");

printf(" * * \n");

printf(" *************************************************** \n");

return 0; / * auch moeglich: return(0); * /

}

Hier sind bereits einige grundlegende C-Regeln zu erkennen:

1. Vorläufig müssen alle C-Programme die Zeichenfolge int main(void) enthalten, wasden eigentlichen Programmanfang kennzeichnet.

2. Der zu main() gehörige Programmteil ist in geschweiften Klammern einzubetten. Dabeikennzeichnet:

{ den Anfang und} das Ende des entsprechenden Programmteils.

3. Ein Kommentar wird mit / * ..... * / geklammert. Kommentare sind Informationen für denProgrammierer und werden vom C-Übersetzer (auch C-Compiler genannt) nicht beachtet.Um ein Programm möglichst lesbar zu machen, sollte es möglichst gut kommentiert sein.

4. Bildschirmausgaben sind mit printf("Text") möglich. Auszugebender Text muss dabeimit Anführungszeichen geklammert sein.

3

Page 18: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

1 Einführendes Beispiel

5. Um die einzelnen C-Anweisungen voneinander zu trennen, muss immer ein Semikolonals Trennzeichen angegeben werden. Vor und nach einem Semikolon können beliebig vie-le Leerzeichen oder auch Leerzeilen angegeben werden; gilt übrigens auch für andereWörter wie main , printf oder return .

6. #include ‹stdio.h› sollte zunächst immer am Anfang (vor main() ) angegeben wer-den. Ebenso sollte vor der abschließenden geschweiften Klammer immer return 0; oderreturn(0); angegeben werden.

7. Die Angabe von \n im Text bei printf("Text") bewirkt, dass beim Programmablauf andieser Stelle auf den Anfang der nächsten Zeile gesprungen wird. Das Steuerzeichen \n,das immer in Anführungszeichen anzugeben ist, wird also niemals als Text ausgegeben,sondern bewirkt einen Zeilenvorschub.

Wird als letztes Zeichen in einem auszugebenden Text nicht \n angegeben, so wird beim näch-sten printf in der gleichen Zeile (an der alten Bildschirmposition) mit der Ausgabe fortgefah-ren, wie es das C-Programm zweit.c verdeutlicht:

#include <stdio.h>

int main(void)

{

printf(" **** \n * * \n * * \n **** \n\n");

printf("Das ist ein Viereck ");

printf("aus Sternchen, ");

printf("oder nicht ?");

printf("\nE\nN\nD\nE");

printf("N");

printf("D");

printf("E\n");

return 0;

}

Startet man dieses Programm zweit , liefert es die folgende Bildschirmausgabe:

****

* *

* *

****

Das ist ein Viereck aus Sternchen, oder nicht ?

E

N

D

ENDE

Eine Angabe wie:

printf("Guten Ta

g");

ergibt einen Fehler, da ein Zeilenwechsel innerhalb der in “. . . “ eingebetteten Zeichenkette nichterlaubt ist.

4

Page 19: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

1.2 Zeilen-Kommentare mit // (neu in C99)

1.2 Zeilen-Kommentare mit // (neu in C99)

Neben dem schon immer vorhandenen C-Kommentar, der in einem C-Programm mit der Zei-chenfolge / * eingeleitet und mit der Zeichenfolge * / beendet wird, hat C99 zusätzlich nochwie C++ auch die Zeichenfolge // zum Kommentieren eingeführt: Alle Zeichen ab // bis zumZeilenende werden dabei als Kommentar interpretiert:

printf("Frau Holle, "); / * Normaler C-Kommentar, der sich über

mehrere Zeilen erstrecken kann und

auch weiterhin verwendet werden kann.

* /

printf("wie gehts?\n"); // Ab hier bis zum Zeilenende Komme ntar (neu in C99)

// Bei mehrzeiligen Kommentare ist erneut // anzugeben

1.3 Gute Lesbarkeit von Programmen

Einrücken von untergeordneten Programmteilen

Wie einzurücken ist, wurde bereits in den vorherigen Programmbeispielen für die Anweisun-gen innerhalb der geschweiften Klammern von main() gezeigt. Es gibt keine allgemeingültigeRegel, wie viele Leerzeichen einzurücken sind; üblich ist jedoch das Einrücken um drei, vieroder auch acht Leerzeichen.

Sinnvolle Kommentare

Da Kommentare in einem C-Programm der Mensch/Mensch-Kommunikation dienen, sind sieein wichtiges Hilfsmittel, um die Lesbarkeit eines Programms zu erhöhen und somit das Ver-ständnis zu erleichtern.

❏ Kommentare sollten zusätzliche Information enthaltenDie Befehlsbedeutung ist nicht zu kommentieren. Kommentare wiei=i+1; / * i wird um 1 erhoeht * /

sind nicht nur überflüssig, sondern sogar schädlich, da sie den Programmtext unnötigaufblähen, was eher zur Unübersichtlichkeit und damit zu einer schlechteren Lesbarkeitführt.

❏ Nicht zuviel Programmtext auf einmal kommentierenDrei Seiten zusammenhängender Kommentar, um die nächsten drei Seiten Programm-text zu beschreiben, dient nicht der besseren Verständlichkeit eines Programms, sondernlässt sich auch nicht leicht ändern, wenn sich der betreffende Programmteil grundlegendändert.

❏ Ein falscher Kommentar ist schlimmer als gar kein KommentarKommentare müssen bei jeder Änderung des Programms aktualisiert werden.

❏ Einige gute treffende Sätze sind mehr wert als RomaneBei Kommentaren geht es meist darum, den Nagel auf den Kopf zu treffen. Die Profes-sionalität und Güte eines Programmierers lässt sich unter anderem an seinem Stil derKommentierung erkennen.

5

Page 20: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

1 Einführendes Beispiel

1.4 Vermeiden von geschachtelten Kommentaren

Obwohl einige Compiler geschachtelte Kommentare, wie z. B.:

...../*

.....

/*

.....

.....

*/

.....

* /.....

zulassen, ist es nicht empfehlenswert, von solchen Schachtelungen Gebrauch zu machen, dadiese nicht durch die C-Standards „abgesegnet“ sind. Verwendet man trotzdem solche Kom-mentar-Schachtelungen, dann verstößt man gegen die in der SW-Entwicklung wichtige Forde-rung der Portabilität, da ein solches Programm eventuell auf anderen C89- bzw. C99-Compilernnicht mehr ablauffähig ist.

Es gilt nämlich, dass ab dem ersten Vorkommen von /* bis zum ersten Auftreten von */ alles alsKommentar interpretiert wird. Für obige Angabe würde dies bedeuten, dass der fett gedruckteTeil vom Compiler als Kommentar interpretiert wird, so dass er dann mit dem Rest nichts mehranfangen kann.

6

Page 21: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 2

Elementare Datentypen

2.1 Die Grunddatentypen in C

In C existieren die in Abbildung 2.1 gezeigten elementaren Datentypen. Da ein Computer Zei-chen – wie z. B. Buchstaben – ganz anders behandelt werden als Gleitpunktzahlen – wie z. B.die Zahl π=3.1415. . . –, wurde eine Klassifikation dieser unterschiedlichen Daten notwendig.

Abbildung 2.1: Die elementaren C-Datentypen

Ordnet man nun in einem Programm Daten bestimmten Klassen wie Zeichen, ganze Zahl, ein-fach/doppelt genaue Gleitpunktzahl usw. zu, dann teilt man dem Rechner deren Datentyp mit. In Cexistieren die Grunddatentypen: char, int, float und double , wobei es für die Typen int

und double Versionen mit unterschiedlichen Genauigkeiten gibt:

7

Page 22: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

2 Elementare Datentypen

char Daten dieses Typs belegen ein Byte Speicherplatz und repräsentieren „ Zeichen“. In ei-nem Byte (8 Bit) kann genau ein Zeichen des ASCII-Zeichenvorrats gespeichert werden.Vor char darf dabei eines der beiden folgenden Schlüsselwörter angegeben werden:

signed 1. Bit ist Vorzeichenbit.unsigned 1. Bit ist kein Vorzeichenbit.

int Dieser Datentyp repräsentiert „ganze Zahlen“; dafür sind im allgemeinen 4 Bytes vorge-sehen, also viermal soviel Speicherplatz wie für char . Mit diesen 4 Bytes (32 Bit) könnenZahlen im Bereich -2 147 483 648 . . . +2 147 483 647 dargestellt werden.Vor int darf dabei eines der folgenden Schlüsselwörter angegeben werden:

short Durch Voranstellen dieses Schlüsselworts (short int ) werden typischerweise 2Bytes (16 Bits) reserviert, was dem Zahlenbereich -32 768 ...+32 767 entspricht.

long Durch Voranstellen dieses Schlüsselworts (long int ) wird auf 32-Bit Maschinenüblicherweise ein Speicherplatz von 4 Bytes (32 Bit) reserviert. Auf 64-Bit Computernhat long aber normalerweise eine Genauigkeit von 64 Bit, also 8 Byte, was einemWertebereich von etwa ±9.22. . . ·1018 entspricht.

long long (nur in C99) Ein long long int entspricht sowohl auf 32-, als auch auf 64-Bit Architekturen einer 8-Byte Genauigkeit. Dieser Datentyp bietet also für 32-BitComputer die Möglichkeit, mit einem größeren Wertebereich zu arbeiten, als ihn dieProzessorregister bieten.

unsigned Das Voranstellen dieses Schlüsselworts (unsigned int ) bewirkt, dass das er-ste Bit nicht als Vorzeichenbit, sondern als echte Stelle interpretiert wird. Mit un-

signed kann also festgelegt werden, dass in einem Speicherplatz nur ganze positive,also keine negativen Zahlen stehen können.

Die obigen Schlüsselwörter können auch alleine, d. h. ohne int , angegeben werden,was vom C-Compiler genauso wie mit Angabe von int interpretiert wird: short ent-spricht short int, long entspricht long int , long long entspricht long long int

und unsigned entspricht unsigned int .

float Dieser Datentyp ist für Gleitpunktzahlen mit einfacher Genauigkeit vorgesehen; dazuwerden im allgemeinen 4 Bytes (32 Bit) reserviert.

double Daten dieses Typs belegen 8 Byte (64 Bit) Speicherplatz und sind Gleitpunktzahlenmit doppelter Genauigkeit. Wird long double angegeben, so bedeutet dies meist, dassein Speicherplatz von 96 Bits (12 Bytes) reserviert wird.

Wie viele Bytes ein bestimmter Datentyp auf einer gegebenen Architektur tatsächlich belegt,kann mit dem folgenden Programm ermittelt werden (Beispiel für long double ):

#include <stdio.h>

int main(void)

{

printf( "Der Datentyp belegt %d Bytes \n", sizeof(long doub le) );

return 0;

}

8

Page 23: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

2.2 Wertebereiche für die einzelnen Datentypen

2.2 Wertebereiche für die einzelnen Datentypen

Tabelle 2.1 zeigt für die einzelnen Datentypen die auf 32-Bit Maschinen üblicherweise verwen-deten Bitzahlen und die daraus resultierenden Wertebereiche. Tabelle 2.2, welche die äquiva-lente Information für 64-Bit Architekturen enthält, verdeutlicht, dass sich auf 64-Bit Computernlediglich der Wertebereich des Datentyps long ändert.

Tabelle 2.1: Typische Wertebereiche für die einzelnen Datentypen auf 32-Bit-Architekturen

Datentyp-Bezeichnung Bitanzahl Wertebereich

char , signed char 8 -128 .. 127

unsigned char 8 0 .. 255

short , signed short ,short int , signed short int 16 -32 768 .. 32 767

unsigned short , unsigned short int 16 0 .. 65 535

int , signed , signed int 32 -2 147 483 648 .. 2 147 483 647

unsigned , unsigned int 32 0 .. 4 294 967 295

long , signed longlong int , signed long int 32 -2 147 483 648 .. 2 147 483 647

unsigned long , unsigned long int 32 0 .. 4 294 967 295

long long , signed long long (C99) 64 -9 223 372 036 854 775 808 ..long long int , signed long long int (C99) .. 9 223 372 036 854 775 807

unsigned long long (C99)unsigned long long int (C99) 64 0 .. 18 446 744 073 709 551 615

float 32 1.2 ·10−38..3.4·1038

double 64 2.2 ·10−308..1.8·10308

long double 96 3.4 ·10−4932..1.1·104932

Tabelle 2.2: Typische Wertebereiche für die einzelnen Datentypen auf 64-Bit-Architekturen

Datentyp-Bezeichnung Bitanzahl Wertebereich

int , signed , signed int 32 -2 147 483 648 .. 2 147 483 647

long, signed long 64 -9 223 372 036 854 775 808 ..long int, signed long int .. 9 223 372 036 854 775 807

unsigned long, unsigned long int 64 0 .. 18 446 744 073 709 551 615

unsigned long long , (C99)unsigned long long int (C99) 64 0 .. 18 446 744 073 709 551 615

long long , signed long long (C99) 64 -9 223 372 036 854 775 808 ..long long int , signed long long int (C99) .. 9 223 372 036 854 775 807

9

Page 24: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 3

Konstanten

Die Eigenschaft von Konstanten ist, dass sie – im Gegensatz zu Variablen – einen festen Wertbesitzen, der einem der gerade besprochenen Datentypen zugeordnet ist. Jede Konstante hatdabei einen Datentyp, welcher durch ihre Form und Wert bestimmt wird (engl. self-typing).

3.1 char-Konstanten

Der Datentyp char wird meist durch 1 Byte realisiert. char -Konstanten müssen mit einfachemHochkomma (z. B.: ’a’) geklammert werden. Im Byte des char -Datentyps wird dann der zuge-hörige ASCII-Wert gespeichert, der dieses Zeichen repräsentiert, wie z. B.:

char-Konstante Dezimaler ASCII-Wert Dualdarstellung im char-Byte’a’ 97 01100001’W’ 87 01010111’*’ 42 00101010’8’ 56 00111000

Bei char handelt es sich anders als bei float und double um einen Ganzzahltypen. C ist nunbei weitem nicht so typstreng wie z. B. PASCAL. So ist es in C ohne weiteres möglich, imchar- Datentyp auch einen numerischen Wert zu speichern. Es ist dabei lediglich zu beachten,dass bei einem numerischen Wert dann nicht der ASCII-Wert wie bei einer char- Konstante,sondern die Dualdarstellung dieser Zahl abgespeichert wird. Während also z. B. für ’8’ derASCII-Wert 56 , der dieses Zeichen repräsentiert als Dualzahl (00111000 ) abgelegt wird, wirddagegen für die Dezimalzahl 8 die dieser Zahl entsprechende Dualzahl (00001000 ) im char- Da-tentyp abgelegt.

3.2 Ganzzahlige Konstanten

Es gibt drei verschiedene Arten von ganzzahligen Konstanten:

❏ Dezimal-Konstanten, die immer mit einer von 0 verschiedenen Ziffer beginnen❏ Oktal-Konstanten, die immer mit einer 0 beginnen müssen❏ Hexadezimal-Konstanten, die immer mit 0x oder 0X beginnen müssen.

11

Page 25: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 4

Variablen

4.1 Variablen und die C-Regeln für Variablennamen

Die Eigenschaft von Variablen ist, dass sich ihre Werte ständig ändern können. Es handelt sichbei Variablen um eine Art Beschriftung eines Speicherbereichs. Während aber die Beschriftungimmer gleich bleibt, kann sich der Inhalt eines Speicherbereichs ändern.

Die Beschriftung eines Speicherplatzes, d. h. die Vergabe eines Namens an eine Variable, wird vomProgrammierer vorgenommen. Natürlich muss festgelegt werden, um welche Art von Variable(siehe auch Datentypen in Kapitel 2 ab Seite 7) es sich handelt. Diese Festlegung wird ebenfallsvom Programmierer vorgenommen; wie das geschieht, wird im nächsten Kapitel gezeigt. Umnun einen Speicherplatz zu „beschriften“, muss diesem ein Name, der Variablenname, gegebenwerden. Die Vergabe von Variablennamen ist in C an bestimmte Regeln gebunden:

1. Es dürfen nur Buchstaben (keine Umlaute ä, ü, ö, Ä, Ü, Ö oder ß), Ziffern und der Unter-strich (_) verwendet werden.

2. Das erste Zeichen eines Variablennamens muss immer ein Buchstabe oder ein Unterstrichsein.

3. Ein Variablenname darf beliebig lang sein.4. Wie jede höhere Programmiersprache verfügt auch C über einen festen Wortschatz von

Befehlen (siehe unten). Solche Befehle dürfen natürlich nicht als Variablennamen verwen-det werden, weil sonst der C-Compiler nicht entscheiden könnte, ob ein Befehl oder einVariablenname gemeint ist.

5. Obwohl nach der ersten Regel erlaubt, sollten Variablennamen niemals mit einem Unter-strich beginnen, da es eine Reihe intern vordefinierter Namen dieser Form gibt.

Wie oben erwähnt, dürfen C-Schlüsselwörter nicht als Variablennamen verwendet werden. Infolgender Tabelle sind alle C-Schlüsselwörter angegeben, wobei die in C99 neu hinzugekom-menen Schlüsselwörter fett gedruckt sind. Während die Verwendung von Schlüsselwörtern alsalleinstehende Variablennamen verboten ist, dürfen sie jedoch in Variablennamen eingebettetsein; z. B. wäre automobil ein erlaubter Variablenname.

auto break case char const continue default dodouble else enum extern float for goto ifint long register return short signed sizeof staticstruct switch typedef union unsigned void volatile whileinline restrict _Bool _Complex _Imaginary

13

Page 26: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 5

Ausdrücke und Operatoren

5.1 Der einfache Zuweisungsoperator

5.1.1 Allgemeines zum einfachen Zuweisungsoperator

Der Zuweisungsoperator hinterlegt einen Wert in einer Variablen. Durch die Anweisung

zahl_var = 5;

wird z. B. in der Variablen zahl_var der Wert 5 abgelegt. Soll nun der Wert -17 in zahl_var

gespeichert werden, so ist lediglich

zahl_var = -17;

zu schreiben, wodurch der alte Wert von zahl_var überschrieben wird. Der Operator = ist nichtmathematisch als Gleichheitszeichen zu verstehen, sondern mehr im Sinne von „ergibt sichaus“:

zaehler = 19;

Der Wert der Variablen zaehler ergibt sich aus 19 , d. h.: im Speicherplatz mit dem Namenzaehler wird der Wert 19 gespeichert.

Beispiel:

In der Variablen zahl_1 sei der Wert 4 und in der Variablen zahl_2 der Wert -24 gespeichert.Durch die Zuweisung:

zahl_1 = zahl_2; / * Speichere in zahl_1 den Wert von zahl_2) * /

gilt dann Folgendes:

Vor dieser Zuweisung:

zahl_1 4zahl_2 -24

. . .

Nach dieser Zuweisung:

zahl_1 4\ -24zahl_2 -24

. . .

Der ursprüngliche Inhalt von zahl_1 wurde mit dem Inhalt der Variablen zahl_2 überschrie-ben.

17

Page 27: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

5 Ausdrücke und Operatoren

Beispiel:

Das C-Programm tausch.c vertauscht die Werte von zwei int -Variablen:

#include <stdio.h>

int main(void)

{

int variab_1, variab_2, hilf; / * Deklaration von drei ganzzahligen Variablen mit den Namen

’variab_1’, ’variab_2’, ’hilf’ * /

variab_1 = 105; / * _______________

variab_1 I 105 I

I_____________I * /

variab_2 = -14; / * _______________

variab_1 I 105 I

I_____________I

variab_2 I -14 I

I_____________I * /

/ ***************************************** Vertauschen *********************************** /

/ * Zwischenspeichern der Werte von ’variab_1’ in der "Hilfsva riable" ’hilf’ * /

hilf = variab_1; / * _______________

variab_1 I 105 I

I_____________I

variab_2 I -14 I

I_____________I

hilf I 105 I

I_____________I * /

/ * Speichern des Wertes von ’variab_2’ in ’variab_1’, (d. h. de r urspruengliche

Wert von ’variab_1’ wird ueberschrieben).

Der urpruengliche Wert von ’variab_1’ wurde zuvor in ’hilf’ gesichert * /

variab_1 = variab_2; / * _______________

variab_1 I -14 I

I_____________I

variab_2 I -14 I

I_____________I

hilf I 105 I

I_____________I * /

/ * Speichern des in ’hilf’ gespeicherten Wertes in ’variab_2’ . Nach dieser Zuweisung sind

die urspruenglichen Werte von ’variab_1’ und ’variab_2’ ve rtauscht. * /

variab_2 = hilf; / * _______________

variab_1 I -14 I

I_____________I

variab_2 I 105 I

I_____________I

hilf I 105 I

I_____________I * /

return 0;}

18

Page 28: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

5 Ausdrücke und Operatoren

5.5.5 Bit-Operatoren nur für ganzzahlige Datentypen erlau bt

Die Bit-Operatoren ~, &, | und ^ dürfen nicht auf Operanden angewendet werden, die vomDatentyp float oder double sind. Z. B. würde für das folgende C-Programm bitgleit.c einFehler gemeldet:

#include <stdio.h>

int main(void) {

int x;

float zahl = 10 * 23;

x = zahl & 200; / * zahl vom Typ float --> keine Bit-Operatoren dafuer erlaubt * /

printf("%d\n", x);

return 0;

}

5.5.6 Fallgruben

Logische Operatoren und Bit-Operatoren unterscheiden sic h

Das Ergebnis einer logischen Operation ist FALSE (in C: 0) oder TRUE(in C: 1). Bei den Bit-Operatoren dagegen werden die einzelnen Bits verglichen, und das Ergebnis ist dann das Bit-muster, und nicht unbedingt 0 oder 1. Die nachfolgenden Beispiele sollen dies verdeutlichen.Hat z. B. die short -Variable z1 den Wert 2 und die short -Variable z2 den Wert 5, so haben diebeiden Operatoren & und &&unterschiedliche Auswirkungen:

z = z1 & z2;

Vor

zeic

hen

=16

384

214

=81

92

213

=40

96

212

=20

48

211

=10

24

210

=51

2

29

=25

6

28

=12

8

27

=64

26

=32

25

=16

24

=8

23

=4

22

=2

21

=1

20

z1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 = 2

z2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 = 5

z1 & z2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 = 0

z = z1 && z2;

Vor

zeic

hen

=16

384

214

=81

92

213

=40

96

212

=20

48

211

=10

24

210

=51

2

29

=25

6

28

=12

8

27

=64

26

=32

25

=16

24

=8

23

=4

22

=2

21

=1

20

z1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 = 2 (TRUE)

z2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 = 5 (TRUE)

z1 &&z2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 = 1 (TRUE)

TRUE && TRUE = TRUE (in C durch 1 dargestellt)

34

Page 29: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

5.5 Bit-Operatoren

Hat z. B. die short -Variable z1 den Wert 2 und die short -Variable z2 den Wert 5, so haben diebeiden Operatoren | und ‖ unterschiedliche Auswirkungen:

z = z1 | z2; Vor

zeic

hen

=16

384

214

=81

92

213

=40

96

212

=20

48

211

=10

24

210

=51

2

29

=25

6

28

=12

8

27

=64

26

=32

25

=16

24

=8

23

=4

22

=2

21

=1

20

z1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 = 2

z2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 = 5

z1 | z2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 = 7

z = z1 || z2; Vor

zeic

hen

=16

384

214

=81

92

213

=40

96

212

=20

48

211

=10

24

210

=51

2

29=

256

28

=12

827

=64

26

=32

25

=16

24

=8

23

=4

22

=2

21

=1

20

z1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 = 2 (TRUE)

z2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 = 5 (TRUE)

z1 ‖ z2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 = 1 (TRUE)

TRUE ‖ TRUE = TRUE (in C durch 1 dargestellt)

Niedrige Priorität der dyadischen Bit-Operatoren

Die Bitoperatoren lassen sich – wie in Tabelle 5.2 gezeigt - in die Prioritätstabelle der bisherkennengelernten Operatoren einordnen.

In Tabelle 5.2 ist erkennbar, dass die Priorität der Bitoperatoren sehr niedrig ist. Dies führt häu-fig zu äußerst ärgerlichen und schwer auffindbaren Fehlern in der praktischen Programmie-rung.

⇓( ) ⇓! ˜ (Tilde) + (Vorz.) − (Vorz.) ⇓ höhere∗ / % ⇓ Priorität+ − ⇓< <= > >= ⇓== ! = ⇓& ⇓ˆ ⇓| ⇓&& ⇓ niedrigere|| ⇓ Priorität= ⇓

Tabelle 5.2: Priorität der Bit-Operatoren

35

Page 30: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 6

Symbolische Konstanten

Die Programmiersprache C sieht die Möglichkeit vor, an Konstanten Namen zu vergeben. Wiewir im nachfolgenden sehen werden, bringt die Verwendung von Konstanten viele Vorteile mitsich, wie z. B. bessere Lesbarkeit von C-Programmen, Arbeitsersparnis beim Programmierenund leichtere Änderbarkeit von Programmen. In C können auf zwei verschiedene Arten sym-bolische Namen an Konstanten vergeben werden:

❏ Definition mit #define oder❏ Definition unter Verwendung des Schlüsselworts const .

6.1 Konstanten-Definition mit #define

6.1.1 Die Direktive #define

Nehmen wir einmal an, dass Sie ein Programm erstellen sollen, in dem die Zahl π immer mit9 Stellen Genauigkeit nach dem Komma verwendet werden muss. Sie müssten dann bei je-dem Vorkommen von π die Zahlenschlange 3.141592654 eintippen. Mit der Verwendung von#define ist es nun jedoch möglich, am Anfang des Programms einem Zahlenwert einen Namenzuzuordnen, wie z. B.

#define PI 3.141592654

Anstelle des Zahlenwerts 3.141592654 können Sie dann bei den entsprechenden Anweisungenim gesamten Programm den symbolischen Namen (PI) verwenden. Dies kann eine erheblicheArbeitsersparnis für das restliche Programm bedeuten, da nicht ein ständiges Nachschlagenund konzentriertes Abtippen der 10 Ziffern notwendig ist, sondern anstelle dessen nur derName PI anzugeben ist.

Hinweis:

#define-Angaben werden nicht wie die anderen C-Anweisungen mit Semikolon abgeschlos-sen.

47

Page 31: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 7

Ein- und Ausgabe

Bevor wir die beiden Bibliotheks-Funktionen printf() und scanf() in diesem Kapitel aus-führlich behandeln, werden wir uns zunächst mit den sogenannten Headerdateien beschäfti-gen.

7.1 Headerdateien und #include

7.1.1 Bibliotheken und Headerdateien

Zu jedem C-Compiler wird eine Bibliothek mitgeliefert, in der Funktionen hinterlegt sind. Wieder Aufbau einer Funktion ist, können wir an main() sehen:

Funktionskopf, evtl. mit Parametern int main(void){...

Funktionsrumpf ......}

Der Anfang des Funktionsrumpfs wird durch { und das Ende durch } gekennzeichnet.

Nun haben wir aber in den vorherigen Programmen bereits Funktionsaufrufe wie printf()

oder scanf() benutzt, zu denen der Funktionsrumpf fehlte. Diese Funktionen sind in einerBibliothek hinterlegt, in der sich der Linker, nachdem kompiliert wurde, die zum entsprechen-den Funktionsaufruf gehörige Funktion sucht und zu Ihrem Programm dazubindet. Sie kön-nen also z. B. die Funktion printf() benutzen und Bildschirmausgaben veranlassen, obwohlSie den dazugehörigen Programmteil (Funktion) nicht selbst programmiert haben; dies hat derCompiler-Hersteller bereits für Sie getan.

Seit C89 sind die Funktionsnamen und deren Funktionalität, die jedes C-Kompilierungssystemanbieten muss, genau festgelegt. Diese Funktionen sind üblicherweise in einer Standardbiblio-thek hinterlegt. Diese Standardbibliothek ist im Prinzip eine Datei, die den für den Linker bind-baren Objekt-Code dieser Funktionen enthält.

Damit aber auch bereits dem C-Compiler Informationen zu solchen Standardfunktionen be-kannt sind, existieren so genannte Headerdateien, in denen die Funktionsköpfe der entspre-

51

Page 32: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 8

Datentypumwandlungen

8.1 Implizite Datentypumwandlungen

8.1.1 Der sizeof-Operator

Bevor wir uns genauer mit den impliziten Datentypumwandlungen beschäftigen, werden wireinen neuen Operator kennenlernen: den sizeof -Operator. Mit diesem Operator kann die Grö-ße eines Datentyps, einer Variable oder eines Ausdrucks in Bytes ermittelt werden. So sind z. B.die folgenden Angaben möglich:

sizeof(double) liefert Anzahl von Bytes, die vom Datentyp double belegt werden.sizeof(var) liefert Anzahl von Bytes, die von der Variable var belegt werden.sizeof(a+b) liefert Anzahl von Bytes, die zur Berechnung von a+b benötigt werden.

Um festzustellen, wie viele Bytes Ihr Compiler für die Grunddatentypen verwendet, kann z. B.das folgende Programm typgroes.c dienen.

#include <stdio.h>

int main(void) {

printf("%20s: %d Bytes\n", "char", sizeof(char));

printf("%20s: %d Bytes\n", "signed char", sizeof(signed c har));

printf("%20s: %d Bytes\n", "unsigned char", sizeof(unsig ned char));

printf("------------------------------------------\ n");

printf("%20s: %d Bytes\n", "short", sizeof(short));

printf("%20s: %d Bytes\n", "signed short", sizeof(signed short));

printf("%20s: %d Bytes\n", "unsigned short", sizeof(unsi gned short));

printf("------------------------------------------\ n");

printf("%20s: %d Bytes\n", "int", sizeof(int));

printf("%20s: %d Bytes\n", "signed int", sizeof(signed in t));

printf("%20s: %d Bytes\n", "unsigned int", sizeof(unsign ed int));

printf("------------------------------------------\ n");

printf("%20s: %d Bytes\n", "long", sizeof(long));

printf("%20s: %d Bytes\n", "signed long", sizeof(signed l ong));

printf("%20s: %d Bytes\n", "unsigned long", sizeof(unsig ned long));

printf("------------------------------------------\ n");

91

Page 33: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 9

Die Headerdateien <limits.h und <float.h >

9.1 <limits.h > - Grenzwerte von Ganzzahltypen

Diese Headerdatei definiert die Grenzwerte für die verschiedenen Ganzzahltypen. C legt fürjeden dieser Werte nur einen Mindestwert fest, wie dies in Tabelle 9.1 gezeigt ist. Der absoluteBetrag dieses Mindestwerts (mit gleichem Vorzeichen) darf von keinem Compiler unterschrit-ten werden, der sich C89- bzw. C99-Compiler nennt.

Tabelle 9.1: Konstanten mit Mindestwert aus <limits.h >

Konstante Mindestwert Beschreibung

CHAR_BIT 8 maximale Bitanzahl für ein ByteSCHAR_MIN -127 Minimalwert für signed charSCHAR_MAX +127 Maximalwert für signed charUCHAR_MAX 255 Maximalwert für unsigned charCHAR_MIN SCHAR_MINoder 01 Minimalwert für charCHAR_MAX SCHAR_MAXoder

UCHAR_MAX2Maximalwert für char

MB_LEN_MAX 1 maximale Bytes für Vielbyte-Zeichen (länderspezifischeZeichen wie z. B. japanische oder chinesische Zeichen)

SHRT_MIN -32767 Minimalwert für short intSHRT_MAX +32767 Maximalwert für short intUSHRT_MAX 65535 Maximalwert für unsigned shortINT_MIN -32767 Minimalwert für intINT_MAX +32767 Maximalwert für intUINT_MAX 65535 Maximalwert für unsigned intLONG_MIN -2147483647 Minimalwert für long intLONG_MAX +2147483647 Maximalwert für long intULONG_MAX 4294967295 Maximalwert für unsigned longLLONG_MIN -9223372036854775807 (neu in C99) Minimalwert für long long intLLONG_MAX +9223372036854775807 (neu in C99) Maximalwert für long long intULLONG_MAX 18446744073709551615 (neu in C99) Maximalwert für unsigned long long

1Abhängig davon, ob char ein vorzeichenbehafteter oder vorzeichenloser Datentyp ist2Abhängig davon, ob char ein vorzeichenbehafteter oder vorzeichenloser Datentyp ist

101

Page 34: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 10

Anweisungen und Blöcke

Fügt man zu einem Ausdruck wie schieb >>= 4 oder scanf("%d", &zahl) oder zaehl = 7

oder nieder-- ein Semikolon hinzu, so erhält man eine C-Anweisung, wie z. B. folgende An-weisungen:

schieb >>= 4;

scanf("%d", &zahl);

zaehl = 7;

nieder--;

Um mehrere Anweisungen zu einem Block zusammenfassen zu können, müssen die geschweif-ten Klammern { und } verwendet werden. Ein solcher Block wird dann wie eine einzelne An-weisung interpretiert, wie z. B.

{

zahl1 = -7;

zahl2 = 15;

sum = zahl1+zahl2;

printf("%d + %d = %d\n", zahl1, zahl2, sum);

}

Hinweise:

1. In C beendet ein Semikolon eine Anweisung, während z. B. in Pascal ein Semikolon einTrennzeichen zwischen den einzelnen Anweisungen ist.

2. Wie wir später sehen werden, können in einem Block auch Variablen vereinbart werden.

103

Page 35: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 11

Die if-Anweisung

11.1 Die zweiseitige if-Anweisung

Die if -Anweisung wird für Programmverzweigungen benötigt: if (deutsch Wenn) und else

(deutsch Sonst). Die Syntax für die vollständige (zweiseitige) if -Anweisung ist:

if (ausdruck)anweisung1

elseanweisung2

anweisung1 und anweisung2 kann ein mit {} geklammerter Block von Anweisungen sein.

Der nach if in Klammern ( ) angegebene ausdruck ist meist eine Bedingung. Ist die Bedin-gung erfüllt bzw. der Wert dieses Ausdrucks von 0 verschieden, dann wird anweisung1, sonstanweisung2 ausgeführt, denn es gilt ja in C immer:

❏ Der Wert 0 entspricht FALSE(falsch).❏ Ein Wert verschieden von 0 entspricht TRUE(wahr).

Die Funktionsweise der if -Anweisung kann am besten durch einen so genannten Programma-blaufplan veranschaulicht werden, wie er in Abbildung 11.1 gezeigt ist.

ausdruckwahr (verschieden von 0) ?

ja

nein

anweisung anweisung1 2

Abbildung 11.1: Programmablaufplan zur if -Anweisung

105

Page 36: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 12

Die bedingte Bewertung ?:

Wenn wir das Maximum der beiden Variablen zahl1 und zahl2 an die Variable max zuweisenwollen, so würden wir mit unseren bisherigen Kenntnissen folgenden Programmteil erstellen:

if (zahl1 > zahl2)

max=zahl1;

else

max=zahl2;

Ist der Wert von zahl1 größer als der Wert von zahl2 , so wird der Wert von zahl1 der Variablenmax, andernfalls der Wert von zahl2 der Variablen max zugewiesen.

Mit der bedingten Bewertung hätten wir diesen Programmteil auch wie folgt angeben können:

max = (zahl1 > zahl2) ? zahl1 : zahl2;

Zunächst wird hier der Ausdruck (zahl1 > zahl2 ) bewertet. Trifft diese Bedingung zu, dannwird der Variablen max der Wert von zahl1 , andernfalls der Wert von zahl2 zugewiesen.

ausdr1 ? ausdr2 : ausdr3

Zunächst wird dabei der ausdr1 bewertet.Ist sein Wert verschieden von 0, so wird ausdr2 bewertet, andernfalls ausdr3.In jedem Fall wird nur einer der beiden Ausdrücke ausdr2 oder ausdr3 bewertet;dieser Wert ist dann das Ergebnis der gesamten bedingten Bewertung.

Da der Operator ? : eine sehr niedrige Priorität besitzt, sind runde Klammern bei ausdr1,ausdr2 und ausdr3 meist nicht notwendig, erhöhen aber die Lesbarkeit.

Das folgende C-Programm mannweib.c zeigt eine Anwendung des bedingten Operators:

#include <stdio.h>

int main(void) {

char zeichen;

printf("Geben Sie den Buchstaben m oder w ein: ");

printf("----> Sie haben *** %s*** gewaehlt\n",

((zeichen=getchar()) == ’m’) ? ("maennlich") : ("weiblich "));

return 0;

}

119

Page 37: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 13

Die switch-Anweisung

13.1 Die switch-Anweisung

Mit der switch -Anweisung kann unter mehreren Alternativen, nicht nur unter zwei wie beider if -Anweisung, ausgewählt werden. Die Syntax für die switch -Anweisung ist:

switch (ausdruck){

case ausdr1: anweisungen1case ausdr2: anweisungen2

. . .case ausdrN: anweisungenNdefault: anweisungenD

}

Es wird der bei switch angegebene (ausdruck) ausgewertet und das Ergebnis mit den einzelnencase -Ausdrücken, die int- oder char- Werte (Konstanten) liefern müssen, verglichen.

Wird keine Übereinstimmung gefunden, so verzweigt das Programm zur default -Marke, fallsdiese angegeben wurde.

Wird keine Übereinstimmung gefunden und es ist keine default -Marke angegeben, so wirdkeine Anweisung des switch -Blocks ausgeführt. Fehlt also die default -Marke, so wird der ge-samte switch -Block übersprungen, falls keine Übereinstimmung in den case -Marken vorliegt.

Die switch -Anweisung ist mit einem Programm-Schalter zu vergleichen und wird im Strukto-gramm - wie in Abbildung 13.1 gezeigt – dargestellt.

Abbildung 13.1: Struktogramm zur switch -Anweisung

121

Page 38: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 14

Der Komma-Operator

14.1 Der Komma-Operator

Der Komma-Operator fasst mehrere Ausdrücke syntaktisch zu einem einzigen Ausdruck zu-sammen.

Sind mehrere Ausdrücke durch ein Komma (, ) getrennt, so werden sie von links nach rechtsbewertet; Datentyp und Wert des Gesamtausdrucks ist dann gleich dem Datentyp und Ergebnisder letzten Operation.

Beispiel:

zeich = ’J’, zaehl = 9, pi = 3.1415;Alle drei Zuweisungen werden nacheinander berechnet, das Ergebnis des Gesamtaus-druckes ist gleich 3.1415 .

Im Zusammenhang mit Schleifenvariablen, die wir im nächsten Kapitel behandeln werden,wird dieser Komma-Operator häufig verwendet. Der Komma-Operator erlaubt nämlich dieUnterbringung von mehreren Zuweisungen an einer Stelle, wo sonst nur eine erlaubt wäre.

Mann kann den Komma-Operator auch innerhalb einer if -Anweisung verwenden, um sich diegeschweiften Klammern einer Blockanweisung zu sparen, wie z. B.:

if (...)

zaehl++, printf ("\n Zaehler erhoeht\n");

Sonst hätte man schreiben müssen:

if (...) {

zaehl++;

printf ("\n Zaehler erhoeht\n");

}

Aus Gründen der besseren Lesbarkeit ist aber immer die zweite Vorgehensweise vorzuziehen.

127

Page 39: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 15

Die for-Anweisung

15.1 Die for-Anweisung

Syntaktisch sieht die for -Schleife wie folgt aus:

for (ausdruck1; ausdruck2; ausdruck3)anweisung

Die anweisung kann ein Block von Anweisungen sein, der mit {...} zu klammern ist.- ausdruck1 initialisiert die Schleifenvariable(n).- ausdruck2 legt das Abbruchkriterium für die Schleife fest, wenn ausdruck2 nicht erfüllt ist.- ausdruck3 reinitialisiert die Schleifenvariable(n).

Die Komponenten (ausdrücke) können einzeln oder auch insgesamt fehlen, jedoch müssen dieSemikolons in der Klammer an den richtigen Stellen verbleiben.

nächste Anweisung(außerh. der for-Schleife)

ausdruck1

ausdruck2

?

ausdruck3

anweisung

wahr(verschieden von 0)

falsch (gleich 0)

Abbildung 15.1: Programmablaufplan zur for -Schleife

129

Page 40: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

15.2 Die for-Schleife und der Komma-Operator

Jetzt wollen wir nochmals die geometrische Reihe berechnen, wobei wir alle erforderlichenSchleifenanweisungen im for -Schleifenkopf unterbringen, so dass überhaupt keine Schleifenan-weisung mehr übrigbleibt.

#include <stdio.h>

int main(void)

{

int zaehl, n;

double reih_teil, summe;

printf("Geben Sie n ein !\n");

scanf("%d",&n);

for (reih_teil = 1, summe = 1, zaehl = 1;

zaehl <= n;

reih_teil /= 2, summe += reih_teil, ++zaehl)

; / * leere Anweisung * /

printf("\n\n\nDie Summe der "

"geometrischen Reihe bis %d ist:\n", n);

printf("%lf\n", summe);

return 0;

}

zaehl = 1

zaehl <= n?

wahr

falsch

reih_teil = 1

summe = 1

Anfang

Leere Anweisung

( nur ; )

++zaehl

Ausgabe von

summe

Ende

reih_teil /= 2

summe += reih_teil

Abbildung 15.6: C-Programm georeih3.c

Hier haben wir als einzige Schleifenanweisung eine leere Anweisung. Für dieses Programm istreih_teil mit dem Wert 1 vorzubesetzen.

Der Komma-Operator erlaubt also, mehrere Ausdrücke zu einem einzigen Ausdruck zu ver-schmelzen. Diese Technik lässt sich vor allen Dingen bei der for -Schleife anwenden, wennmehrere Schleifenvariablen zu initialiseren und/oder zu reinitialisieren sind.

Generell sollte man jedoch darauf achten, den for -Schleifenkopf nicht zu überladen. Um dieÜbersichtlichkeit und Lesbarkeit eines Programms zu wahren, ist es des öfteren besser, Varia-blen in eigenen Anweisungen zu initialisieren oder zu verändern, wenn sie nicht unmittelbarzur Schleifensteuerung gehören.

135

Page 41: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 16

Die while-Anweisung

16.1 Die while-Anweisung

while (ausdruck)anweisung

anweisung kann wieder ein mit {..} zu klammernder Block von Anweisungen sein.

Die Funktionsweise der while -Schleife lässt sich am besten anhand der Abbildung 16.1 zeigen.

nächste Anweisung (außerh. der while-Schleife)

ausdruck?

anweisung

wahr(verschieden von 0)

falsch (gleich 0)

Vor jedem Schleifendurchlauf wird ausdruck be-rechnet. Solange das Ergebnis verschieden von 0(TRUE) ist, wird die Schleifen-anweisung ausge-führt. Erst, wenn die Auswertung von ausdruck 0(FALSE) liefert, wird die Schleife beendet und mitder nächsten nicht zur Schleife gehörigen Anwei-sung fortgefahren.Ist das Ergebnis von ausdruck bereits bei der erstenBerechnung gleich 0 (FALSE), so wird die Schleifegar nicht durchlaufen, sondern sofort mit dernächsten nicht zur Schleife gehörigen Anweisungfortgefahren.

nächste Anweisung (außerhalb der Schleife)

Schleifen-Anweisungen

while (ausdruck)

Abbildung 16.1: Programmablaufplan und Struktogramm zur while -Schleife

Da die Abfrage der Schleifen-Bedingung wie bei der for -Schleife am Anfang durchgeführtwird, wird die while -Schleife genauso wie die for -Schleife im Struktogramm dargestellt.

161

Page 42: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 17

Die do. . . while-Anweisung

17.1 Die do. . . while-Anweisung

doanweisung

while (ausdruck);

Die anweisung kann selbstverständlich wieder ein Block von Anweisungen sein, der dannmit {..} zu klammern ist.

Die Funktionsweise der do...while -Schleife lässt sich am besten anhand der Abbildung 17.1zeigen.

nächste Anweisung(außerh. der do...while-Schleife)

ausdruck?

anweisung

wahr

(verschieden von 0)

falsch (gleich 0)

Nach jedem Schleifendurchlauf wird ausdruckberechnet. Ist das Ergebnis verschieden von 0(TRUE), so wird die Schleifen-anweisung nochmalsausgeführt. Erst, wenn die Auwertung von aus-druck 0 (FALSE) liefert, wird die Schleife beendetund mit der nächsten nicht zur Schleife gehörigenAnweisung fortgefahren.

nächste Anweisung (außerhalb der Schleife)

anweisung (in Schleife)

while (ausdruck)

Abbildung 17.1: Programmablaufplan und Struktogramm zur do...while -Schleife

Da die Abfrage der Bedingung bei der do...while -Schleife am Ende stattfindet, wird dieseSchleife im Struktogramm – wie rechts in Abbildung 17.1 gezeigt – dargestellt.

175

Page 43: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 18

Die break-Anweisung

18.1 Die break-Anweisung

Nicht immer ist es sinnvoll, eine Schleife nur über das Abbruchkriterium zu verlassen. Diebreak -Anweisung dient dazu, um eine for -, while -, do...while -Schleife oder eine switch -Anweisung vorzeitig zu verlassen. Dazu muss lediglich break aufgerufen werden.

for-Schleife:for (ausdr1 ; ausdr2 ; ausdr3) {

.....

.....

+----break;

| .....

| .....

| }

+->anweisung; / * ausserhalb for-Schleife * /

while-Schleife:while (ausdruck) {

.....

.....

+----break;

| .....

| .....

| }

+->anweisung; / * ausserhalb while-Schleife * /

do...while-Schleife:do {

.....

.....

+----break;

| .....

| .....

| } while (ausdruck);

+->anweisung / * ausserhalb do...while * /

switch-Anweisung:

switch (ausdruck) {

.....

case x:

....

+-------break;

| .....

| .....

| }

+->anweisung; / * ausserhalb switch * /

179

Page 44: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 19

Die continue-Anweisung

19.1 Die continue-Anweisung

Die continue -Anweisung ist der break -Anweisung ähnlich. Sie bewirkt allerdings im Unter-schied zur break -Anweisung nicht den Abbruch der gesamten Schleife, sondern nur den Ab-bruch des aktuellen Schleifendurchlaufs, also einen Sprung zum Schleifenende. continue leitetsomit unverzüglich den nächsten Schleifendurchlauf ein und hat auch im Gegensatz zu break

keine Auswirkung auf switch -Anweisungen.Die continue -Anweisung bewirkt also eine sofortige Wiederholung der betreffenden Schleife.Bei while und do...while bedeutet dies, dass sofort wieder die Bedingung (ausdruck) ausge-wertet wird. Bei for wird als nächstes die Reinitialisierung (ausdr3) durchgeführt und dann zurSchleifenbedingung (ausdr2) verzweigt.Das folende C-Programm vollkomm.c gibt alle vollkommenen Zahlen zwischen x und y aus.Eine Zahl Z ist vollkommen, wenn die Summe aller ihrer Teiler (ohne Z selbst) gleich Z ist.

#include <stdio.h>

int main(void) {

long int sum, innen, aussen, von, bis;

printf("Vollkommene Zahlen von? "); scanf("%ld", &von);

printf("Vollkommene Zahlen bis? "); scanf("%ld", &bis);

for (aussen = von; aussen <= bis; aussen++) {

sum = 0;

for (innen = 1; innen <= aussen / 2; innen++) {

if ((aussen % innen) != 0)

continue;

sum += innen;

if (sum > aussen)

break;

}

if (sum == aussen)

printf("%ld\n",sum);

}

return 0;

}

183

Page 45: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 20

Marken und die goto-Anweisung

20.1 Marken und die goto-Anweisung

Die Syntax der goto -Anweisung ist:

goto marke;

Diese Anweisung bewirkt einen Sprung zu der Programmstelle, an dermarke:

angegeben ist.

Eine marke hat dabei die gleiche Form wie ein Variablenname1; anschließend folgt ein Doppel-punkt:

marke: anweisung;

marken können vor jeder Anweisung stehen, unabhängig davon, ob sie innerhalb des Pro-gramms mit goto angesprungen werden oder nicht. Nach einer marke muss immer mindestenseine Anweisung angegeben sein, eventuell auch nur die leere Anweisung:

marke: ;

In einem Programm darf dieselbe Marke nur einmal angegeben sein.

20.2 Programmiertechniken

20.2.1 goto nur im äußersten Notfall

Mit Einführung der Strukturierten Programmierung in den 60er Jahren wurde die Springereimit goto sehr verpönt. Damals waren Programme vor allen Dingen in Assembler geschrieben.Dort war und ist zum Teil noch der Sprung zu einer Code-Adresse ein fundamentales Prin-zip. Später wurde dieser Stil vor allen Dingen in BASIC übernommen. Man stellte damals sehrschnell fest, dass Programme, die mit Vorwärts- und Rückwärtssprüngen gespickt sind, nichtnur schwer verständlich, sondern auch kaum wartbar waren. Dies führte zu einer erheblichenVerteuerung der Software. Ein Ausweg aus diesem Dilemma war die Strukturierte Programmie-

1muss mit Buchstabe oder Unterstrich beginnen und des weiteren dürfen nur Buchstaben, Ziffern oder Unterstrichefolgen

197

Page 46: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 21

Grafikprogrammierung unter Linux

Im Rahmen dieses Buches wurde eine einfache Grafik-Bibliothek namens LCGI entwickelt, wel-che von der Homepage heruntergelden werden kann.

21.1 Benutzung von LCGI1. Inkludieren von <graphics.h>

Da die hier vorgestellten Funktionen in der Headerdatei graphics.h deklariert sind,sollte immer Folgendes angegeben werden, wenn man von diesen Funktionen in seinemProgramm Gebrauch macht.

#include <graphics.h>

2. Angabe von main() mit ParameternWenn Sie in Ihrem Programm Routinen aus diesem Kapitel aufrufen, müssen Sie statt

int main(void)

immer Folgendes angeben:

int main( int argc, char *argv[] )

3. Kompilieren und Linken von GrafikprogrammenWenn Sie ein Programm erstellt haben, das Routinen aus diesem Kapitel aufruft, müssenSie dieses immer mit dem mitgelieferten Kommando lcc statt gcc bzw. cc kompilierenund linken.Wenn Sie z. B. ein Programm polygon.c entworfen haben und dieses nun kompilierenwollen, müssen Sie z. B. Folgendes aufrufen:

user@linux:~ > lcc -o polygon polygon.c��

��←֓

lcc bietet die gleichen Optionen an wie das Kommando gcc bzw. cc .Geben Sie danach zum Testen die folgende Kommandozeile ein:

user@linux:~ > ./polygon��

��←֓

199

Page 47: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

21 Grafikprogrammierung unter Linux

21.2 Grafikmodus ein- und ausschalteninitgraph(int breite, int hoehe)

schaltet den Grafikmodus ein, indem ein Fenster eingeblendet wird, das breite Pixelbreit und hoehe Pixel hoch ist.

closegraph()

beendet den Grafikmodus. Da in diesem Fall auch das Grafikfenster gelöscht wird, wirdmeist vor closegraph() noch ein getch() angegeben, so dass erst auf einen Tastendruckdes Benutzers hin der Grafikmodus verlassen wird.

Typisch für die Grafikprogrammierung ist deshalb z. B. folgender Programmausschnitt:

#include <graphics.h>

.......

int main( int argc, char * argv[] )

{

initgraph( 640, 480 );

........

Grafik-Programmteil

........

getch(); / * auf einen Tastendruck warten * /

closegraph();

}

21.3 Eingaben im Grafikmodus

Während man im Grafikmodus arbeitet, kann man nicht mehr die Standardroutinen für die Ein-und Ausgabe (printf(), scanf(), getchar() und putchar() ) verwenden, sondern mussdie eigens dafür angebotenen Routinen verwenden, welche nachfolgend vorgestellt sind:

getcharacter(char * text, ...)

getstring(char * text, ...)

getint(char * text, ...)

getdouble(char * text, ...)

fordern den Benutzer durch Ausgabe des Textes text zur Eingabe eines Zeichens, einesTextes, einer ganzen Zahl oder einer Gleitpunktzahl auf und liefern diese Eingabe zurück.

kbhit()

prüft, ob eine Taste gedrückt wurde. Falls eine Taste gedrückt wurde, liefert kbhit()

einen int -Wert ungleich 0 (TRUE), falls nicht, liefert diese Funktion 0 (FALSE) zurück.Das dabei eingegebene Zeichen kann mit der nachfolgend vorgestellten Routine getch()

nachträglich erfragt werden.

getch()

liest ein Zeichen ein. Anders als bei getchar() findet hier jedoch keine Zwischenpuffe-rung statt, sondern das Zeichen wird direkt von der Tastatur gelesen. Das eingegebeneZeichen wird dabei nicht am Bildschirm angezeigt. In jedem Fall liefert diese Routine

200

Page 48: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

21 Grafikprogrammierung unter Linux

Abbildung 21.3: Wahrscheinlichkeit von 0.62 (links) und 0.7 (rechts) für das Eindringen von Öl

Beispiel:

Das folgende Programm pixel.c wählt zufällig eine Hintergrundfarbe und malt dann 1 000kleine Vierecke an zufällige Bildschirmpositionen mit zufällig gewählten Farben. Ein Vierecksind dabei 9 Pixel:

xxxxoxxxx

wobei nur der Mittelpunkt (o) zufällig gewählt ist. Danach wird der Inhalt dieses Fensters ge-löscht, mit einer zufälligen Hintergrundfarbe gefüllt und wieder mit neuen zufälligen kleinenRechtecken bemalt. Mit einem Tastendruck kann dieses Programm beendet werden.

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <graphics.h>

#define PIXEL_ZAHL 1000

int main( int argc, char * argv[] ) {

int i, maxx, maxy, x, y, farbe, max_farbe;

srand(time(NULL));

initgraph( 640, 480 );

maxx=getmaxx(); maxy=getmaxy(); max_farbe = getmaxcolor ();

while ( !kbhit()) {

cleardevice( rand()%(max_farbe+1) );

for (i=1 ; i<=PIXEL_ZAHL ; i++) {

x = rand()%maxx; y = rand()%maxy; farbe = rand()%(max_farbe +1);

putpixel(x, y, farbe); putpixel(x-1,y-1,farbe); putpixe l(x,y-1,farbe);

putpixel(x+1,y-1,farbe); putpixel(x+1,y,farbe); putpi xel(x+1,y+1,farbe);

putpixel(x,y+1,farbe); putpixel(x-1,y+1,farbe); putpi xel(x-1,y,farbe);

}

}

closegraph();

return 0;

}

206

Page 49: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

21.8 Bilder laden, Bildteile speichern und einblenden

Abbildung 21.10: Anzeige des Programms sandmann.c

Abbildung 21.10 zeigt das von Programm sandmann.c angezeigte Fenster zu einem bestimm-ten Zeitpunkt. Dieses Programm könnte z. B. gestartet werden, wenn man seinen Bildschirm-platz längere Zeit verlässt, und man Information am Bildschirm darüber ausgeben lassen möch-te, wo man sich gerade befindet und wann man wieder zurückkommt. Hierzu müsste man je-doch dann die auszugebende Meldung einlesen lassen. Eine entsprechende Anpassung diesesProgramms an die speziellen eigenen Bedürfnisse sollte aber nicht allzu schwierig sein.

Beispiel:

Das folgende Programm karten.c blendet bei jedem Tastendruck immer sieben zufällig aus-gewählte Karten ein, die es übereinander legt (siehe auch Abbildung 21.11). Mit der ESC-Tastekann dieses Programm beendet werden.

Abbildung 21.11: Unterschiedliche Anzeigen des Programms karten.c nach einem Tastendruck

219

Page 50: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 22

Funktionen

In der Programmierpraxis sind häufig Probleme anzutreffen, die einander von der Aufgaben-stellung her ähnlich sind. Dieser Tatsache wird in der Programmiersprache C mit so genanntenFunktionen (functions) Rechnung getragen.

22.1 Allgemeines zu Funktionen

Wir haben bisher schon – ohne es ausführlich zu erwähnen – mit Funktionen gearbeitet. Sohaben wir z. B. zur Ausgabe auf dem Bildschirm die Funktion printf() aufgerufen. Hinterdiesem Funktionsnamen verbirgt sich ein Programmteil, der in der Standardbibliothek definiertist und bei jedem Aufruf von printf() ausgeführt wird.

22.1.1 Allgemeines Beispiel zu Funktionen

Am besten können wir das Prinzip von Funktionen an einem allgemeinen Beispiel nachvoll-ziehen. In diesem Beispiel wird nicht die Programmiersprache C, sondern – zum besseren Ver-ständnis – die deutsche Sprache verwendet. Es soll bei der Personalabteilung einer Firma im-mer ein einheitliches Papier für die Spesenabrechnung abgegeben werden. Wir nehmen dazuan, dass in der Standardbibliothek eine Funktion (Schablone) mit Namen spesen() definiertsei, was natürlich nicht für die wirkliche Programmbibliothek gilt.

Funktionsname Liste der formalen Parameter| || vv __________________________________________________ _____________

spesen( name, stadt, preis, vor, haupt, nach, tagzeit, waehrung, datum ){

Drucke folgendes aus:"Herr/Frau name hat am datum in stadt

zu(m) tagzeit:vor als Vorspeisehaupt als Hauptspeise undnach als Nachspeise

gegessen.Der Preis fuer dieses Essen betrug preis waehrung."

}

231

Page 51: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

22.3 Die Parameter von Funktionen

In der Definition von tausch() werden mit der Deklaration

void tausch(int * a, int * b)

zwei Speicherplätze für int -Zeiger und ein Speicherplatz für die lokale Variable hilf reserviert.

Mit dem Aufruf

tausch(&zahl_1, &zahl_2);

werden dabei dann die Adressen von zahl_1 und zahl_2 als aktuelle Argumente an die Funk-tion tausch() übergeben; als Erinnerung: & = Adreßoperator. Bei dieser Übergabe werden alsoin die beiden reservierten Speicherplätze a und b der Funktion tausch() die Adressen vonzahl_1 und zahl_2 abgelegt; siehe Abbildung 22.11.

Abbildung 22.11: Übergabe der Adressen von zahl_1 und zahl_2 an tausch()

Der Ablauf innerhalb der Funktion tausch() ist bildlich in der Abbildung 22.12 dargestellt.

hilf = * a;

* a = * b;

* b = hilf;

Nach der Rückkehr aus der Funktion tausch()

sind nun die Werte von zahl_1 und zahl_2 ver-tauscht.

Abbildung 22.12: Call by Reference durch Übergabe von Adressen

259

Page 52: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

22.7 Zeiger auf Funktionen

und

float * welch_funktion(...);/ * welch_funktion = Funktion, die Zeiger auf float-Wert liefe rt * /

sollten Sie sich klarmachen.

Will man nun über den Zeiger welch_funktion eine Funktion aufrufen, so muss man * we-

lch_funktion angeben, da welch_funktion ein Zeiger und folglich * welch_funktion die ei-gentliche Funktion ist.

Wenn z. B. welch_funktion auf die Funktion zyl_vol() zeigt, dann entspricht die Anweisung

return rad * ( * welch_funktion)(rad);

der Anweisung

return rad * zyl_vol(rad);

wie dies auch in Abbildung 22.20 gezeigt ist.

welch_funktion

zyl_volkug_vol

1. Befehl der Funktion zyl_vol

2. Befehl der Funktion zyl_vol

1. Befehl der Funktion kug_vol

2. Befehl der Funktion kug_vol

Zeigerebene

Variablenebene

Werteebene

*welch_funktion

Abbildung 22.20: * welch_funktion entspricht zyl_vol()

Um das Zeigerprinzip bei Funktionen besser verstehen zu können, wollen wir ein weiteresDeklarations-Beispiel angeben:

float * ( * welch_funktion)(...);

Hier wäre welch_funktion ein Zeiger auf eine Funktion, die einen Zeiger auf einen float -Wertliefert.

22.7.2 Typische Anwendungen

Auswahl von Funktionen zur Programmlaufzeit

Ein typischer Anwendungsfall für Zeiger auf Funktionen liegt vor, wenn erst zum Zeitpunktder Programmausführung bekannt ist, welche Funktion auszuführen ist. Nehmen wir z. B. einSortierprogramm, bei dem erst während der Programmausführung bekannt ist, welche Datenzu sortieren sind: Ganze Zahlen, Zeichenketten oder sonstige Daten. In diesem Fall schreibtman nur eine Sortierfunktion, die neben anderen Parametern auch einen Zeiger auf eine Funk-tion erwartet, die für den Vergleich der einzelnen Daten zuständig ist. Ist dann während der

283

Page 53: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 23

Speicherklassen und Modultechnik

Es wurde schon einmal erwähnt, dass sich C-Programme aus mehreren Dateien zusammenset-zen können. Jede Programmdatei – auch Modul genannt – kann einzeln kompiliert werden, aberist für sich allein nicht lauffähig.

Diese getrennt kompilierten Module können anschließend mit Hilfe des Linkers zu einem ein-zigen Programm zusammengebunden werden.

23.1 Gültigkeitsbereich, Lebensdauer, Speicherort

23.1.1 Gültigkeitsbereich

Unter dem Gültigkeitsbereich eines Objekts (Funktionsname, Variablenname) versteht man dieBereiche in den einzelnen Programmeinheiten, in denen es angesprochen werden kann.

Beim Gültigkeitsbereich wird zwischen folgenden Arten unterschieden:

❏ modulglobal❏ programmglobal❏ lokal (in einem Block von { . . . })

Modulglobale Gültigkeit

Ein modulglobales Objekt ist innerhalb der gesamten Programmdatei (Modul) ansprechbar, inder es deklariert ist, aber nicht in einer anderen Programmdatei (Modul). Jede Variable, dieaußerhalb einer Funktion deklariert ist, werden wir als modulglobal bezeichnen.

Da modulglobale Variablen außerhalb von Funktionen vereinbart sind und somit vielen Funk-tionen zur Verfügung stehen, kann innerhalb von Funktionen auf modulglobale Variablen zu-gegriffen werden, ohne dass diese als Parameter zu übergeben sind.

Beispiel:

In diesem Beispiel werden wir ein C-Programm tausch3.c erstellen, das mit Hilfe einer Funk-tion tausch() die Werte zweier Variablen vertauscht. In diesem Programm werden die entspre-chenden Variablen jedoch nicht als Zeigervariablen übergeben.

287

Page 54: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 24

Präprozessor-Direktiven

Der Präprozessor verarbeitet den Quelltext einer Programmdatei, wobei alle Präprozessor-Kom-mandos (Präprozessor-Direktiven) mit dem Zeichen # beginnen. Zwischenraum-Zeichen (engl.whitespace: Leerzeichen, \f, \n, \r, \t oder \v) und Kommentare sind vor # zugelassen; zwi-schen # und Anfang der restlichen Präprozessor-Direktive sind nur Leerzeichen, \t und Kom-mentare zugelassen.

Beispiel:

So sind z. B. die folgenden drei Angaben erlaubte Präprozessor-Direktiven in C89 und C99:

/ * Kommentar * / #if TEST

# / * Kommentar * / if TEST

# if / * Kommen-

tar * / TEST

Üblicherweise ruft der Compiler automatisch den Präprozessor auf, bevor er mit der Überset-zung beginnt.

C89 schreibt vor, dass der Präprozessor wie ein eigener Schritt vor dem eigentlichen Compiler-lauf zu verstehen ist1.

Der Präprozessor bietet nun die folgenden Dienstleistungen an:

❏ Bedingte Kompilierung (#ifdef, ... )❏ Einkopieren von anderen Dateien (#include )❏ Makro-Ersetzung (#define )❏ Makrodefinition aufheben (#undef )❏ Vordefinierte Makronamen (__LINE__, __FILE__, ... )❏ Zeilenumerierung (#line )❏ Fehlermeldungen (#error )❏ Pragmas (#pragma )❏ Null-Direktive (#)

1Das heißt nicht, dass der Präprozessor-Lauf als eigener Durchgang (wie es in heutigen Compilern oft der Fall ist)realisiert sein muss, sondern sich nur so verhalten muss

331

Page 55: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

24.1 Bedingte Kompilierung

Beispiele:

#if bed1

progteil1

#elif bed2

progteil2

#elif bed3

progteil3

#else

progteil4

#endif

N

N

N

bed1erfüllt?

bed2erfüllt?

bed3erfüllt?

J

J

J

Kompilierung von progteil1

Kompilierung von progteil2

Kompilierung von progteil3

Kompilierung von progteil4

Abbildung 24.1: Programmablaufplan zu einer #if -Kaskade

Schachteln von#if -Konstruktionenist erlaubt, wie z. B.:#if beda

# if beda1

progteila1

# else

progteila2

# endif

#else

# if bedb1

progteilb1

# else

progteilb2

# endif

#endif

N

N

bedaerfüllt?

bedb1erfüllt?

J

Kompilierung von progteilb1

Kompilierung von progteilb2

N

beda1erfüllt?

J

Kompilierung von progteila2

Kompilierung von progteila1

J

Abbildung 24.2: Programmablaufplan zu einer geschachtelten #if -Konstruktion

333

Page 56: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 25

Zeiger und Arrays

In der Programmierpraxis sind häufig Probleme anzutreffen, bei denen man nicht mit einfachenVariablen auskommt, sondern einen ganzen Block von Variablen des gleichen Typs benötigt. EinBeispiel dafür wären die Monatumsätze eines Unternehmens für ein Jahr. In diesem Fall ist essehr nützlich, 12 double -Variablen in einem Block zu definieren, an dem nur ein Name verge-ben wird. Zur Unterscheidung der Monate wird dann z. B. ein Index (ganze Zahl) verwendet.

25.1 Eindimensionale Arrays

Ein Array ist die namentliche Zusammenfassung einer Anzahl von gleichartigen Objekten einesDatentyps, wie z. B. int - oder char -Variablen. Anstelle des Begriffes Array wird manchmalauch der Begriff Vektor verwendet. Hier werden wir immer den Begriff Array benutzen.

25.1.1 Eindimensionale Arrays

Ein eindimensionales Array mit 26 Elementen vom Typ char könnte wie folgt vereinbart wer-den:

char buchst[26];

Mit dieser Angabe wird ein Array buchst mit 26 Elementen vom Typ char definiert. Die Anzahlder Elemente wird bei der Definition in eckigen Klammern angegeben. Unter

char buchst[26];

können wir uns die Reservierung eines Speicherblocks mit Namen buchst und mit 26 auf-einanderfolgenden Elementen (hier also 26 char -Variablen) vorstellen, wie dies auch links inAbbildung 25.1 gezeigt ist. Mit der Definition

char buchst[26];

werden also, wenn man so will, auf einmal 26 char -Variablen (buchst[0], buchst[1],

buchst[2], ..., buchst[25] ) festgelegt.

Werden n Elemente (hier: n = 26) für ein Array definiert, so erfolgt die Adressierung über sogenannte Indizes von Element 0 bis Element n−1.

357

Page 57: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

25 Zeiger und Arrays

Beachten Sie, dass jedes Array mit der Elementnummer 0 und nicht mit 1 beginnt!

Mit den Anweisungen

buchst[3] =’a’;

buchst[0] =’!’;

buchst[24] =’H’;

ergäbe sich dann ein Speicherbild, wie es rechts in Abbildung 25.1 gezeigt ist.

. . .

. . .

. . .

. .

buchst [0]

buchst [1]

buchst [2]

buchst [3]

buchst [4]

buchst [23]

buchst [24]

buchst [25]

. . .

. . .

. . .

. .

. . .

. . .

. . .

. .

buchst [0]

buchst [1]

buchst [2]

buchst [3]

buchst [4]

buchst [23]

buchst [24]

buchst [25]

. . .

. . .

. . .

. .

'!'undefiniert

'a'

'H'

undefiniert

undefiniert

undefiniert

undefiniert

undefiniert

Abbildung 25.1: char -Array buchst mit 26 Speicherplätzen

Beispiele:

int tage[32];

definiert ein Array tage mit 32 int -Variablen tage[0], ..., tage[31] .

int * zeig[20];

definiert ein Array zeig mit 20 Zeigern zeig[0] , . . . ,zeig[19] auf int -Variablen.

Beispiel:

Wir wollen nun ein C-Programm buchstnr.c erstellen, das zunächst in einem Array buchst

alle Kleinbuchstaben speichert. Danach kann der Benutzer eine Nummer eingeben, zu der ihmder entsprechende Kleinbuchstabe am Bildschirm ausgegeben wird. Unser Programm soll zurErmittlung des Buchstabens auf das Array buchst zugreifen.

#include <stdio.h>

int main(void) {

char buchst[26];

int i, zahl;

for (i = 0; i < 26; i++) / * Array mit Kleinbuchstaben belegen * /

buchst[i] = ’a’ + i;

358

Page 58: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 26

Argumente auf der Kommandozeile

26.1 Die Parameter argc und argv der Funktion main()

Jedes C-Programm muss – wie wir wissen – einen Hauptprogrammteil main() besitzen. main()

ist aber nichts anderes als eine Funktion, die beim Start des C-Programms vom Betriebssystemoder dem C-Laufzeitsystem aufgerufen wird. Wir gingen bisher davon aus, dass main() ohneParameter arbeitet:

int main(void)

In Wirklichkeit werden aber bei jedem Aufruf der Funktion main() zwei Argumente mitgege-ben, die wie folgt definiert sind:

int main(int argc, char * argv[])

Die beiden Parameter argc und argv ermöglichen die Übergabe von Strings an das aufgerufeneProgramm, wobei gilt:

Erster Parameter argcist die Anzahl der übergebenen Strings (Worte).

Zweiter Parameter argvist ein Array von Zeigern, wobei jeder dieser Zeiger auf den Anfang eines Strings (Worts)aus der Kommandozeile zeigt.

Das folgende Programm argtest.c demonstriert die Verwendung von argc und argv :

#include <stdio.h>

int main(int argc, char * argv[]) {

int i;

for (i=0; i<argc; i++)

printf("Wort %d: %s\n", i, argv[i]);

return 0;

}

Üblicherweise wird ein solches Programm, nachdem es kompiliert und gelinkt wurde, wie z. B.:

user@linux:~ > cc -o argtest argtest.c��

��←֓

453

Page 59: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 27

Dynamische Speicher-Reservierung und-Freigabe

27.1 Nachteile von statischen Arrays

Das folgende Programm namsort1.c , das bis zu 100 Namen einliest und diese dann sortiertausgibt, zeigt die Nachteile von statischen Arrays in gewissen Anwendungen.

#include <stdio.h>

#include <string.h>

#define MAX_NAMEN 100

#define MAX_LAENGE 30

int main(void) {

int i, j, n;

char nam[MAX_NAMEN][MAX_LAENGE], hilf[MAX_LAENGE];

printf("Gib Deine Namen ein (Abschluss mit Leerzeile)\n") ; / * Einlesen der Namen * /

for (n = 0; n < MAX_NAMEN; n++) {

gets(nam[n]);

if (strlen(nam[n]) == 0)

break;

}

for (i = 0; i < n-1; i++) / * Sortieren der Namen * /

for (j = i+1; j < n; j++)

if (strcmp(nam[i], nam[j]) > 0) {

strcpy(hilf, nam[i]);

strcpy(nam[i], nam[j]);

strcpy(nam[j], hilf);

}

printf("----------------------- Sortierte Namensliste \n");

for (i = 0; i < n; i++)

printf("%s\n", nam[i]);

return 0;

}

463

Page 60: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 28

Strukturen

Unter einer Struktur versteht man die Zusammenfassung von einer oder mehreren Variablen,die – anders als bei Arrays – untereinander auch unterschiedliche Datentypen besitzen dürfen,zu einer Einheit.

28.1 Deklaration und Definition von Strukturen

28.1.1 Deklaration von Strukturen

Ein typisches Beispiel für eine einfache Struktur wäre die Zusammenfassung der Daten einesStudenten aus einer Studentenkartei zu einer einzigen Einheit, die wir stu_daten nennen. Einesolche Zusammenfassung wird in C z. B. folgendermaßen ausgedrückt:

struct stu_daten {

char name[20]; / * Nachname * /

char vorname[20]; / * Vorname * /

long postleit_zahl; / * Postleitzahl * /

char wohnort[20]; / * Wohnort * /

char strass_nr[20]; / * Strasse, Hausnummer * /

char geburtdat[11]; / * Geburtsdatum: tt.mm.jjjj * /

long matrikelnr; / * Matrikelnummer * /

short noten[10]; / * Prüfungsnoten * /

};

Bei der obigen Angabe handelt es sich um die Deklaration einer Struktur. Aus diesem Beispiel istder allgemeine Aufbau einer Strukturdeklaration erkennbar:

❏ Eine Strukturdeklaration beginnt immer mit dem Schlüsselwort struct . Nach Schlüssel-wort struct kann der Name der Struktur (oben: stu_daten ) angegeben werden.

❏ Eine Strukturdeklaration besteht aus einer Liste von Komponenten (Einzelvariablen, wiez. B. name, vorname, postleit_zahl usw.).

❏ Jede Komponente wird mit ihrem Datentyp und ihrem Namen deklariert.❏ Die ganze Komponentenliste ist mit {...} zu klammern.❏ Jede Strukturdeklaration ist mit Semikolon abzuschließen.

491

Page 61: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

28 Strukturen

Für unseren Fall ist die 1. Bedingung und somit auch die Gesamtbedingung erfüllt, so dassfolgende Anweisung ausgeführt wird:

knot_zeig->links = einordnen(knot_zeig->links);

Die Funktion einordnen() ruft sich also selbst wieder auf, so dass sich das in Abbildung 28.23gezeigte Bild ergibt.

Malloni

Ita

01/29/37.19

NULL-Zeiger

wurzel

Mueller

Sui

01/12/48.17

NULL-Zeiger

NULL-Zeiger

knot_zeig->links = einordnen(knot_zeig->links);

(1. rekursive Ebene von einordnen) if (knot_zeig==NULL) { knot_zeig = (struct knoten *)malloc(sizeof(struct knoten)); if (knot_zeig == NULL) { printf(".....Speicherplatzmangel...\n"); exit(1); } strcpy(knot_zeig->name, name); strcpy(knot_zeig->staat, staat); strcpy(knot_zeig->zeit, zeit); knot_zeig->links = knot_zeig->rechts = NULL; }

Abbildung 28.23: Einordnen von Mueller als linker Unterknoten von Malloni

Mit

return knot_zeig;

wird immer die Adresse des gerade behandelten Knotens an die übergeordnete Ebene zurück-gegeben. Von der ersten rekursiven Ebene wird hier z. B. die Adresse des Mueller -Knotenszurückgegeben. Diese Adresse wird wegen

knot_zeig->links = einordnen(knot_zeig->links);

im Malloni -Knoten unter der Komponente knot_zeig->links (hier wurzel->links ) gespei-chert. Nach der Rückkehr nach main() wird dort unter Zuhilfenahme der Funktion drucke_-

baum() folgender Zwischenstand ausgegeben:

Zwischenstand nach 2 Laeufer

=============================

Platz Name Land Zeit

1 Mueller Sui 01/12/48.17

2 Malloni Ita 01/29/37.19

3. eintreffender Läufer In der while -Schleife von main() werden nun die Daten des nächsteneintreffenden Läufers eingelesen:

552

Page 62: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

28.6 Zeiger und Strukturen

name: Hansonstaat: Swezeit: 01/20/10.33

Danach wird mit wurzel = einordnen(wurzel); wieder die Funktion einordnen() aufgeru-fen. In dieser Funktion wird nach Überprüfung der entsprechenden Bedingungen die Anwei-sung knot_zeig->links = einordnen(knot_zeig->links); ausgeführt. Bei diesem rekursi-ven Aufruf von einordnen() wird nach Überprüfung der vorgegebenen Bedingungen die An-weisung knot_zeig->rechts = einordnen(knot_zeig->rechts); ausgeführt, so dass sichdas in Abbildung 28.24 gezeigte Bild ergibt.

Malloni

Ita

01/29/37.19

NULL-Zeiger

wurzel

Mueller

Sui

01/12/48.17

NULL-Zeiger

knot_zeig->links = einordnen(knot_zeig->links);

(1. rekursive Ebene von einordnen)

if (knot_zeig==NULL) { knot_zeig = (struct knoten *)malloc(sizeof(struct knoten)); if (knot_zeig == NULL) { printf(".....Speicherplatzmangel...\n"); exit(1); } strcpy(knot_zeig->name, name); strcpy(knot_zeig->staat, staat); strcpy(knot_zeig->zeit, zeit); knot_zeig->links = knot_zeig->rechts = NULL; }

Hanson

Swe

01/20/10.33

NULL-Zeiger

NULL-Zeiger

(2. rekursive Ebene von einordnen)

knot_zeig->rechts = einordnen(knot_zeig->rechts);

Abbildung 28.24: Einordnen von Hanson als rechter Unterknoten von Mueller

Nach der Rückkehr nach main() wird dort unter Zuhilfenahme der Funktion drucke_baum()

folgender Zwischenstand ausgegeben:

Zwischenstand nach 3 Laeufer

=============================

Platz Name Land Zeit

1 Mueller Sui 01/12/48.17

2 Hanson Swe 01/20/10.33

3 Malloni Ita 01/29/37.19

553

Page 63: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

28 Strukturen

4. eintreffender Läufer In der while -Schleife von main() werden nun die Daten des nächsteneintreffenden Läufers eingelesen:

name: Bichlerstaat: Autzeit: 01/11/59.12

Danach wird mit wurzel = einordnen(wurzel); wieder die Funktion einordnen() aufge-rufen. Der rekursive Ablauf dieser Funktion soll durch das in Abbildung 28.25 gezeigte Bildverdeutlicht werden.

Malloni

Ita

01/29/37.19

NULL-Zeiger

wurzel

Mueller

Sui

01/12/48.17

knot_zeig->links = einordnen(knot_zeig->links);

(1. rekursive Ebene von einordnen)

if (knot_zeig==NULL) { knot_zeig = (struct knoten *)malloc(sizeof(struct knoten)); if (knot_zeig == NULL) { printf(".....Speicherplatzmangel...\n"); exit(1); } strcpy(knot_zeig->name, name); strcpy(knot_zeig->staat, staat); strcpy(knot_zeig->zeit, zeit); knot_zeig->links = knot_zeig->rechts = NULL; }

Hanson

Swe

01/20/10.33

NULL-Zeiger

NULL-Zeiger

(2. rekursive Ebene von einordnen)Bichler

Aut

01/11/59.12

NULL-Zeiger

NULL-Zeiger

knot_zeig->links = einordnen(knot_zeig->links);

Abbildung 28.25: Einordnen von Bichler als linker Unterknoten von Mueller

Nach der Rückkehr nach main() wird dort unter Zuhilfenahme der Funktion drucke_baum()

wieder der aktuelle Zwischenstand ausgegeben:

Zwischenstand nach 4 Laeufer

=============================

Platz Name Land Zeit

1 Bichler Aut 01/11/59.12

2 Mueller Sui 01/12/48.17

3 Hanson Swe 01/20/10.33

4 Malloni Ita 01/29/37.19

Hier können wir die Funktionsweise von drucke_baum() sehr schön erkennen: Es wird immerzuerst der vollständige linke Unterbaum ausgegeben, bevor ein Knoten selbst ausgegeben wird.

554

Page 64: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 29

Eigene Datentypen

29.1 Definition eigener Datentypnamen mit typedef

29.1.1 Vergabe neuer Namen an existierende Datentypen mit t ypedef

Mit dem Schlüsselwort typedef können an Datentypen neue, vom Benutzer wählbare Namenvergeben werden, wie z. B.:

typedef unsigned int UINT;typedef unsigned long ULONG;

Mit diesen Angaben wird festgelegt, dass UINT ein Synonym für unsigned int und ULONGeinesfür unsigned long ist. Nach der obigen typedef -Angabe könnte man z. B. folgende Definitio-nen angeben:

UINT zaehler, i; / * entspricht: unsigned int zaehler, i; * /UINT * zeigarray[10]; / * entspricht: unsigned int *zeigarray[10]; * /ULONG a, * b; / * entspricht: unsigned long a, *b; * /

Man könnte nun glauben, dass das Schlüsselwort typedef völlig überflüssig ist, da man dengleichen Effekt mit #define hätte erreichen können, wie z. B.:

#define UINT unsigned int#define ULONG unsigned long

Für diese einfachen Datentypdefinitionen ist dies zwar möglich, doch reicht bei komplexerenDatentypen der einfache Textersatz von #define nicht aus, wie z. B. bei:

#define STRING char *

In diesem Fall würde die folgende Definition:

STRING zgr1, zgr2;

nicht der erwarteten Definition

char * zgr1, * zgr2;

entsprechen, sondern der folgenden Definition:

char * zgr1, zgr2; / * zgr2 ist nicht - wie erwartet - ein Zeiger * /

569

Page 65: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 30

Dateien

Eine Datei (engl. file) ist letztendlich nichts anderes als eine Ansammlung von Daten, die aufeinem externen Speicher dauerhaft aufbewahrt werden. Aus Sicht von C kann man sich eineDatei als ein permanentes, großes char -Array vorstellen, in das ein Programm Daten schreibenund aus dem ein Programm Daten lesen kann.

Anders als in anderen Programmiersprachen, ist eine C-Datei nicht irgendwie strukturiert, son-dern nur eine Folge von Bytes, weswegen eine Datei in C oft auch als Datenstrom (byte stream)bezeichnet wird. Jedes einzelne dieser Zeichen (Bytes) kann über eine Positionsnummer in derDatei lokalisiert werden. So besitzt das erste Zeichen einer Datei die Positionsnummer 0, daszweite die Positionsnummer 1 usw.

Man kann in C grundsätzlich auf zwei Ebenen mit Dateien operieren, auf einer „unteren“ (lowlevel) oder einer „oberen“ (high level).

Die untere Ebene ist die der so genannten elementaren Dateizugriffe (Elementare Ein-/Ausgabe),bei denen Funktionen verwendet werden, die direkt auf die entsprechenden Routinen des Be-triebssystems (system calls) für Dateioperationen zurückgreifen. Diese elementaren Funktionensind natürlich vom Betriebssystem abhängig und gehören nicht zum C-Standard, was bei derPortierung von Programmen von großer Bedeutung ist.

Die obere Ebene ist die der so genannten höheren Dateizugriffe (Höhere Ein-/Ausgabe), bei denenFunktionen verwendet werden, die zum einen wesentlich komfortabler als die elementarensind und zum anderen auch dem C-Standard entsprechen und somit vom jeweiligen Betriebs-system unabhängig sind.

Nachfolgend werden nur die Höheren E/A-Funktionen vorgestellt.

30.1 Höhere E/A-Funktionen

In diesem Kapitel werden E/A-Funktionen beschrieben, die sich in der Standard-Bibliothekbefinden und in der Headerdatei <stdio.h> definiert sind. Die höheren E/A-Funktionen ar-beiten im Gegensatz zu den elementaren E/A-Funktionen mit eigenen optimal eingestelltenPuffern, so dass sich der Aufrufer darum nicht selbst kümmern muss. Ein solcher Dateipufferist ein Bereich im Arbeitsspeicher, in dem eine bestimmte Menge von Daten, die aus einer Dateigelesen oder in eine Datei geschrieben werden sollen, vor ihrer Übertragung zum Zielort zwi-schengespeichert werden kann. Dies ist ein Vorteil, denn auf diese Weise muss nicht für jedes

577

Page 66: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Kapitel 31

Anhang

31.1 Prioritätstabelle für die Operatoren

Operator (höchste Priorität oben; niedrigste unten) Assoziativität

( ) [ ] -> . (Punktoperator) von links her! ~ (Tilde) ++ -- + (Vorz.) - (Vorz.) sizeof & (Adreßop.) * (Zeigerzugriff) (casting) von rechts her* / % von links her+ - von links her

« » von links her< <= > >= von links her== != von links her& (bitweise AND) von links her^ von links her| von links her&& von links her|| von links her?: (Bedingter Operator) von rechts her= += -= *= /= %= »= «= &= |= ^= von rechts her, (Kommaoperator) von links her

31.2 C-Schlüsselwörter

In folgender Tabelle sind alle C-Schlüsselwörter angegeben, wobei die in C99 neu hinzugekom-menen Schlüsselwörter fett gedruckt sind.

auto break case char const continuedefault do double else enum externfloat for goto if int longregister return short signed sizeof staticstruct switch typedef union unsigned voidvolatile whileinline restrict _Bool _Complex _Imaginary

613

Page 67: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Index

< Operator, 23<<Operator, 37<= Operator, 23== Operator, 23> Operator, 23>= Operator, 23>>Operator, 37| Operator, 25, 28|| Operator, 26\ \, 67, 615\ ’, 67, 615\ ", 67, 615\ a, 67, 615\ b, 67, 615\ e, 67, 615\ f, 67, 615\ ooo, 67, 615\ r, 67, 615\ t, 67, 615\ v, 67, 615\ x, 67, 615++ Operator, 40, 43, Operator, 127, 133-- Operator, 40, 43<assert.h>, 339<ctype.h>, 60<errno.h>, 608<graphics.h>, 199<limits.h>, 101<math.h>, 86<stdarg.h>, 264<stdbool.h> , 24<stddef.h>, 72, 81<stdint.h>, 72, 81<stdio.h>, 577<stdlib.h>, 413<string.h>, 398<time.h>, 189?:, 119Übung

block3.c, 293zusop2.c, 46

# (Null-Direktive), 355# Operator, 345## Operator, 346#define, 47, 49, 342#elif, 332#else, 332#endif, 332#error, 355#if, 332#ifdef, 332#ifndef, 332#include, 51, 340

#line, 354#pragma, 355#undef, 349& Adresoperator, 260& Operator, 28&& Operator, 25, 26_Bool Datentyp, 24_IOFBF Konstante, 603_IOLBF Konstante, 603_IONBF Konstante, 604__DATE__, 353__FILE__, 353__LINE__, 353__STDC__, 353__TIME__, 353! Operator, 23^ Operator, 28Bit-Operatoren, 28Bitfelder, 564Makro

__DATE__, 353__FILE__, 353__LINE__, 353__STDC__, 353__TIME__, 353Vordefiniert, 353

acos(), 86add2.c, 84add2alt.c, 244add2neu.c, 244addalt.c, 243addiere.c, 58addmult.c, 41addneu.c, 243Adresoperator &, 260Aktuelle Koordinate, 204Aktueller Parameter, 233, 253Aktuelles Argument, 233, 253AND-Operator, 26ANSI, 1Anweisung, 20arc(), 210argreih.c, 261argtest.c, 453argtest2.c, 454argtest3.c, 455Argument, 233, 253Argumente

Kommandozeile, 453Optionen, 456

argvor.c, 260arithmetische Operatoren, 19arr_swap.c, 438

Array, 357Funktionsadressen, 451Initialisierung, 426mehrdimensional, 365Struktur, 507und Zeiger, 374zweidimensional, 365

Array-Zeiger, 436arryfeh2.c, 364arrygros.c, 362arrynoname.c, 429arryok.c, 364arrysize.c, 373arrystatic.c, 440artizahl.c, 512asctime(), 189asin(), 86assert(), 339Assoziativität, 43atan(), 86atan2(), 86atof(), 418atoi(), 417atol(), 418atoll(), 418Ausdruck, 20Ausgabe

ein Zeichen, 53gepuffert, 53printf(), 67, 615putchar(), 53

Auswertung, 20Auswertungszeitpunkt, 43auto, 296autoadr.c, 303autoggt.c, 297autokauf.c, 107

B Sprache, 1Balken

dreidimansional, 210zweidimensional, 210

bar(), 210bar3d(), 210Baum

Binär, 546BCPL Sprache, 1Bedingte Bewertung, 119Bedingte Kompilierung, 332Bibliothek, 51, 233bildschi.c, 323bildschi.h, 321Binärbaum, 546Binärmodus, 596

621

Page 68: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Index

binatext.c, 597bitand.c, 30bitfeld.c, 566bitfeld2.c, 568bitgleit.c, 34bitor.c, 32bitumdre.c, 336bitxor.c, 33Blöcke, 290block.c, 291block3.c, 293Blockstruktur, 290bonbon.c, 162bonbon2.c, 163bool Datentyp, 24Bottom-up, 316break, 179Breite eines Textes, 215briefmar.c, 150Bubble-Sort, 389bubble.c, 389buchstat.c, 611buchstnr.c, 358buchzaeh.c, 396BUFSIZ Konstante, 604byte stream, 577bytezahl.c, 583

C++, 1C89, 1C99, 1Call

by reference, 258by value, 258

calloc(), 474Cast, 98cast.c, 100casting, 98ceil(), 86char Datentyp, 8char-Konstanten, 11char-Zeiger, 392Chromsky-Grammatik, 277circle(), 209cleardevice(), 204clearerr(), 581clearviewport(), 223clock(), 189clock1.c, 185closegraph(), 200Compiler, 317const, 49, 310, 434const.c, 312continue, 183copyzeit.c, 593cos(), 86cosh(), 86ctime(), 189

dataus.c, 584datbytes.c, 600Datei

Öffnen, 578Binärmodus, 596EOF-Flag, 581Fehler-Flag, 581Löschen, 603Lesen (blockweise), 590Lesen (ein Zeichen), 581, 582Lesen (eine Zeile), 584Lesen (formatiert), 585Positionieren, 599, 601Pufferung, 604

Schliessen, 578, 580Schreiben (blockweise), 590Schreiben (ein Zeichen), 581, 582Schreiben (eine Zeile), 584Schreiben (formatiert), 585, 594Stream verknüpfen, 601Temporäre, 605Textmodus, 596Umbenennen, 603Zuruckschieben (ein Zeichen), 589

Datentyp, 9, 614_Bool, 24bool, 24char, 8double, 8FILE, 578float, 8fpos_t, 599Grund-, 7int, 8long, 8long long, 8short, 8signed, 8Tabelle, 9, 614unsigned, 8va_list, 264void, 238, 253Wertebereich, 9, 614

Datentypenund Operatoren, 43

Datentypumwandlung, 93, 98, 246casting, 98explizit, 98implizit, 93, 246implizite, 91

Datum des Tages, 193datuminfo.c, 194Datumsangaben, 189defined, 332Definition

Funktionen (Alt-C), 237Funktionen (C89/C99), 234Konstanten, 47, 49Variablen, 14

Dekrement-Operator --, 40delay(), 201dezimale Konstanten, 11dezumwa2.c, 379dezumwan.c, 359difftime(), 189Directory

Löschen, 603do. . . while, 175Doppelt verkettete Liste, 541double Datentyp, 8drawpoly(), 210dreichi1.c, 446dreichi2.c, 450dreizeic.c, 54dualbcd.c, 431dualzahl.c, 142Dynamische

Speicherallozierung, 463Strukturarrays, 522

dynarr.c, 435

E/A-Funktionen, 577E/A-Umlenkung, 586eifrau1.c, 182eifrau2.c, 182eimalei.c, 137einaus.c, 202

einauscp.c, 586Einer-Komplement, 28Eingabe

ein Zeichen, 53gepuffert, 53getchar(), 53scanf(), 77, 617

einkompl.c, 29einles.c, 293Einseitige

if-Anweisung, 110einzeich.c, 53Ellipse

ausgefüllt zeichnen, 209, 220zeichnen, 209

ellipse(), 209Ellipsen-Prototypen, 263endlos.c, 581Endlose for-Schleife, 143englzah1.c, 442englzah2.c, 443Entwurf

Bottom-up, 316Modularer, 316Top-Down, 316

enum, 573enumdemo.c, 576EOF-Flag, 581errno Variable, 608errodemo.c, 609erst.c, 3exp(), 86Explizite Datentypumwandlung, 98extern, 293

Füllmuster, 209fabs(), 86fakul.c, 273fakul2.c, 273FALSE, 24false Konstante, 24Farbpalette, 222farbstuf.c, 222fclose(), 580fehlausg.c, 269Fehler-Flag, 581fehler.c, 325, 610fehler.h, 322Fehlermeldung, 608fehlhand.c, 609feof(), 581ferror(), 581fflush(), 605fgetc(), 582fgetpos(), 601fgets(), 584fibonaci.c, 276figur.c, 211File

siehe Datei, 578FILE Datentyp, 578fillellipse(), 209fillpoly(), 210firmaelt.c, 498, 502firmver2.c, 522firmverw.c, 508float Datentyp, 8floataus.c, 22floatint.c, 97floor(), 86FLT_ROUNDS, 102fmod(), 86Font, 215

622

Page 69: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Index

fopen(), 578for, 129

endlos, 143fordrueb.c, 159Formaler Parameter, 233, 253fprintf(), 585fputc(), 582fputs(), 584Fraktale, 277fread(), 590free(), 481free1.c, 481free2.c, 482free3.c, 483freeimage(), 217Freigabe

Speicher, 463fremdspe.c, 398freopen(), 601freopen.c, 602frexp(), 86fscanf(), 585fseek(), 599fsetpos(), 601ftell(), 599funcbez.c, 271functions, 231funkproj.c, 227Funktion, 231

acos(), 86arc(), 210asctime(), 189asin(), 86atan(), 86atan2(), 86atof(), 418atoi(), 417atol(), 418atoll(), 418bar(), 210bar3d(), 210calloc(), 474ceil(), 86circle(), 209cleardevice(), 204clearerr(), 581clearviewport(), 223clock(), 189closegraph(), 200cos(), 86cosh(), 86ctime(), 189Definition (Alt-C), 237Definition (C89/C99), 234Deklaration, 241delay(), 201difftime(), 189drawpoly(), 210ellipse(), 209Ellipsen-Prototypen, 263exp(), 86fabs(), 86fclose(), 580feof(), 581ferror(), 581fflush(), 605fgetc(), 582fgetpos(), 601fgets(), 584fillellipse(), 209fillpoly(), 210floor(), 86fmod(), 86

fopen(), 578fprintf(), 585fputs(), 584fread(), 590free(), 481freeimage(), 217freopen(), 601frexp(), 86fscanf(), 585fseek(), 599fsetpos(), 601ftell(), 599fwrite(), 590getc(), 582getch(), 200getchar(), 581getcharacter(), 200getcolor(), 207getdouble(), 200getimage(), 217getint(), 200getmaxcolor(), 204getmaxx(), 204getmaxy(), 204getpixel(), 204gets, 584gets(), 422getstring(), 200getx(), 204gety(), 204gmtime(), 190initgraph(), 200isalnum(), 60isalpha(), 60isblank(), 60iscntrl(), 60isdigit(), 60isgraph(), 60islower(), 60isprint(), 60ispunct(), 60isspace(), 60isupper(), 60isxdigit(), 60kbhit(), 200ldexp(), 86line(), 207linerel(), 207lineto(), 207loadimage(), 217localtime(), 190log(), 86log10(), 86malloc(), 466memchr(), 413memcmp(), 412memcpy(), 411memmove(), 412memset(), 412mktime(), 190modf(), 86mouse_button(), 223mouse_getpos(), 223mouse_hide(), 223mouse_inwindow(), 223mouse_left(), 223mouse_mid(), 223mouse_right(), 223mouse_setcursor(), 224mouse_setpos(), 223mouse_setwindow(), 223mouse_show(), 223mouse_visible(), 223

moverel(), 207moveto(), 207outtextxy(), 201perror(), 608pieslice(), 220pow(), 86printf(), 585Prototypen, 242putchar(), 581putimage(), 217putpixel(), 204puts(), 422, 584qsort(), 390, 525realloc(), 475rectangle(), 209Rekursiv, 273remove(), 603rename(), 603rewind(), 601scanf(), 421, 585sector(), 220setbuf(), 604setcolor(), 207setfillstyle(), 209setlinestyle(), 207setpalette(), 222setrgbpalette(), 222settextjustify(), 215settextstyle(), 215setvbuf(), 604setviewport(), 223setwritemode(), 222sin(), 86sinh(), 86snprintf(), 595sprintf(), 419, 595sqrt(), 86sscanf(), 418, 595strcat(), 401strchr(), 403strcmp(), 402strcoll(), 410strcpy(), 395, 400strcspn(), 408strerror(), 410, 608strftime(), 190strlen(), 403strncat(), 401strncpy(), 400strpbrk(), 406strrchr(), 404strspn(), 408strstr(), 405strtod(), 416strtof(), 417strtol(), 413strtold(), 417strtoll(), 416strtoul(), 416strtoull(), 416Struktur, 514strxfrm(), 411tan(), 86tanh(), 86textheight(), 215textwidth(), 215time(), 191tmpfile(), 606tmpnam(), 606tolower(), 60toupper(), 60ungetc(), 589vfscanf(), 596

623

Page 70: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Index

vprintf(), 594vscanf(), 596vsnprintf(), 596vsprintf(), 596vsscanf(), 596Adresse, 451assert(), 339inline, 270va_arg() Makro, 264va_end() Makro, 264va_start() Makro, 264Zeiger auf, 280

funkzgr1.c, 284funkzgr2.c, 285fwrite(), 590

Ganzzahlige Konstanten, 11, 24Ganzzahltypen

Grenzwerte, 101geheim.c, 307georeih2.c, 134georeih3.c, 135georeih4.c, 154georeih5.c, 155georeihe.c, 132gepufferte Ausgabe, 53gepufferte Eingabe, 53gerade.c, 351Geschachtelte Schleifen, 137getc(), 582getch(), 200getchar(), 53, 581getcharacter(), 200getcolor(), 207getdouble(), 200getimage(), 217getint(), 200getmaxcolor(), 204getmaxx(), 204getmaxy(), 204getpixel(), 204gets(), 422, 584getstring(), 200getx(), 204gety(), 204ggtkgv.c, 177Gleichheitsoperatoren, 23gleitpkt.c, 562Gleitpunkt-Ausdruck, 21Gleitpunkt-Variable, 21Gleitpunktkonstanten, 12gleizae2.c, 158gleizae3.c, 158gleizae4.c, 158gleizaeh.c, 157gmtime(), 190goldbac1.c, 186goldbac2.c, 187goldbac3.c, 188Goldbach-Vermutung, 186, 188goto, 197Gröse von Text, 215Grafikmodus

ausschalten, 200einschalten, 200

GrenzwerteGanzzahltypen, 101

groesse.c, 215Grunddatentypen, 7guelt1.c, 300guelt2.c, 301guelt3.c, 302

Höhe eines Textes, 215hamming1.c, 156hamming2.c, 156haus.c, 130Headerdatei, 340

<assert.h>, 339<ctype.h>, 60<errno.h>, 608<graphics.h>, 199<limits.h>, 101<math.h>, 86<stdarg.h>, 264<stdbool.h> , 24<stddef.h>, 72, 81<stdint.h>, 72, 81<stdio.h>, 577<stdlib.h>, 413<string.h>, 398<time.h>, 189selbst.h, 63, 65

Headerdateien, 51, 233Hebräische Methode, 371hebrae.c, 371heron.c, 164heron2.c, 164heron3.c, 164Hexadezimal

Konstanten, 11Ziffer, 122, 124

hexd.c, 591hexextra.c, 589hexokdua.c, 139hexziff1.c, 122hexziff2.c, 124hintquad.c, 154hochdrei.c, 350

if, 105, 110Implizite Datentypumwandlung, 93, 246implizite Datentypumwandlung, 91Information Hidding, 314iniconst.c, 434initgraph(), 200Initialisieren Variable, 46Initialisierung, 19, 426

Struktur, 504inkrdekr.c, 41Inkrement-Operator ++, 40Inline-Funktion, 270inline.c, 270int Datentyp, 8int -Ausdruck, 21int -Variable, 21intaus.c, 21invest.c, 366isalnum(), 60isalpha(), 60isblank(), 60iscntrl(), 60isdigit(), 60isgraph(), 60islower(), 60isnrlow.c, 408ISO, 1ISO C99, 1isprint(), 60ispunct(), 60isspace(), 60isupper(), 60isxdigit(), 60

jaeger1.c, 172jaeger2.c, 173

just.c, 216

karten.c, 219kbhit(), 200keinadr.c, 83kleigro1.c, 61kleigro2.c, 61kleigro3.c, 64kleigros.c, 166Komma-Operator, 127, 133Kommandozeile, 453, 456

Argumente, 453Optionen, 456

Kommentar, 5Geschachtelt, 6

KomplementEiner, 28Zweier, 29

kompzahl.c, 514Konkatenation von Strings, 75Konstante

_IOFBF, 603_IOLBF, 603_IONBF, 604false, 24L_tmpnam, 606SEEK_CUR, 599SEEK_END, 599SEEK_SET, 599stderr, 580, 586stdin, 580, 586stdout, 580, 586TMP_MAX, 606true, 24

Konstanten, 11, 12, 47, 49char, 11Dezimal, 11Ganzzahlig, 11, 24Gleitpunkt, 12Hexadezimal, 11Oktal, 11

konto.c, 56konto2.c, 57Koordinate

aktuell, 204Maximales x, 204Maximales y, 204Transformation, 226

Kreisausgefüllt zeichnen, 220zeichnen, 209

kreis.c, 48Kreisbogen

zeichnen, 210kubikzah.c, 386Kuchenstück, 220kugzyvol.c, 280

L_tmpnam Konstante, 606ldexp(), 86Lebensdauer, 291leerpara.c, 253Lesbarkeit, 113Lindenmayer-Systeme, 277line(), 207linerel(), 207lineto(), 207Linie

absolut zeichnen, 207Art, 207Dicke, 207relativ zeichnen, 207zeichnen, 207

624

Page 71: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Index

linie.c, 207Linked List, 529, 534, 541Linker, 317Liste

Ausgeben, 534Doppelt verkettete, 541Einfügen, 534Löschen, 534Linked, 529, 534, 541Operationen, 534Sortierte, 534Verkettete, 529

loadimage(), 217localtime(), 190log(), 86log10(), 86Logische Operatoren, 24Logischer Operatoren, 25long Datentyp, 8long long Datentyp, 8lottoza2.c, 152lottoza3.c, 153lottozah.c, 151lshift.c, 37lsystem2.c, 278

Makro, 62, 342Makroaufruf, 62malloc(), 466manhat2.c, 147manhatan.c, 144mannweib.c, 119Marke, 197matadd.c, 368matadd2.c, 387mathverg.c, 88Matrix, 365Matrizen, 365mauscursor.c, 225mausdemo.c, 224Mausprogrammierung, 223max.c, 344max2zahl.c, 344Mehrdimensionale Arrays, 365memchr(), 413memcmp(), 412memcpy(), 411memcpy.c, 411memmove(), 412memmove.c, 412memset(), 412menue1.c, 117menue2.c, 118mfunk1.c, 87mineins.c, 116mineins2.c, 116mittwert.c, 142mktime(), 190modf(), 86Modul, 287, 314

bitumdre.c, 336fehler.c, 325paritaet.c, 326paturing.c, 324zahlwort.c, 339

Modularer Entwurf, 316Modultechnik, 314monataus.c, 432mouse_button(), 223mouse_getpos(), 223mouse_hide(), 223mouse_inwindow(), 223mouse_left(), 223

mouse_mid(), 223mouse_right(), 223mouse_setcursor(), 224mouse_setpos(), 223mouse_setwindow(), 223mouse_show(), 223mouse_visible(), 223moverel(), 207moveto(), 207mrz_dez.c, 98mrz_dez2.c, 99Muster, 209

nachvor.c, 55namlist1.c, 529namlist2.c, 535namlist3.c, 541namsort1.c, 463namsort2.c, 467namsort3.c, 468namsort4.c, 485namsort5.c, 486namsort6.c, 487namsort7.c, 487namsort8.c, 488namsort9.c, 488Nassi-Shneiderman-Diagramm, 106,

110, 121, 129, 161, 175NDEBUG, 339Negations-Operator, 25nreingab.c, 307Null-Direktive #, 355numsort1.c, 470numsort2.c, 475numsort3.c, 479numsort4.c, 484

oel.c, 205oelbohr.c, 171Oktal

Konstanten, 11Operation, 128Operationen mit Zeigern, 381Operationen und Datentypen, 43Operator

<<, 37>>, 37−>, 517| , 28, 31||, 26++, 40–, 40#, 345##, 346&, 28, 30&&, 26!, 25^, 28, 33Bit, 28| , 32++, 43--, 43Assoziativität, 43Auswertungszeitupnkt, 43cast-, 98Dekrement, 40Inkrement, 40Komma, 127, 133Postfix, 40Präfix, 40Priorität, 42, 128, 613sizeof, 91, 373und Datentypen, 43

AND, 26arithmetisch, 19Auswertung, 20Logischer, 25Negations-, 25OR, 26Pfeil-, 517Priorität, 20, 35, 38Punkt, 496relationaler, 23Shift, 37Tilde, 28Vergleichs-, 23Zuweisung, 17Zuweisungs-, 39

Operatoren, 19, 23, 25, 26, 28, 37, 39, 40,42, 43

Gleichheits-, 23Relationale, 23

opshift.c, 39OR-Operator, 26outtextxy(), 201

Parameter, 233, 253Struktur, 514

paritaet.c, 326paturing.c, 324perror(), 608pfeilfix.c, 518Pfeiloperator, 517piesarc.c, 221pieslice(), 220Pixel, 204pixel.c, 206Polygon

ausgeful̈lt zeichnen, 210zeichnen, 210

polygon.c, 213Positionieren

absolut, 207relativ, 207

Postfix-Operator, 40postprae.c, 44potenz.c, 235, 237potenz3.c, 239potenz4.c, 241pow(), 86Präfix-Operator, 40printf(), 67, 585, 615printf1.c, 69printf2.c, 71printf3.c, 72printf4.c, 73printf5.c, 74Priorität, 20, 35, 38, 42, 128, 613Privatisierungseffekt, 290Programm

add2.c, 84add2alt.c, 244add2neu.c, 244addalt.c, 243addiere.c, 58addmult.c, 41addneu.c, 243argreih.c, 261argtest.c, 453argtest2.c, 454argtest3.c, 455argvor.c, 260arr_swap.c, 438arryfeh2.c, 364arryfehl.c, 363arrygros.c, 362

625

Page 72: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Index

arrynoname.c, 429arryok.c, 364arrysize.c, 373arrystatic.c, 440artizahl.c, 512autoadr.c, 303autoggt.c, 297autokauf.c, 107binatext.c, 597bitand.c, 30bitfeld.c, 566bitfeld2.c, 568bitgleit.c, 34bitor.c, 32bitumdre.c, 336bitxor.c, 33block.c, 291block3.c, 293bonbon.c, 162bonbon2.c, 163briefmar.c, 150bubble.c, 389buchstat.c, 611buchstnr.c, 358buchzaeh.c, 396bytezahl.c, 583cast.c, 100clock1.c, 185const.c, 312copyzeit.c, 593dataus.c, 584datbytes.c, 600datuminfo.c, 194dezumwa2.c, 379dezumwan.c, 359dreichi1.c, 446dreichi2.c, 450dreizeic.c, 54dualbcd.c, 431dualzahl.c, 142dynarr.c, 435eifrau1.c, 182eifrau2.c, 182eimalei.c, 137einaus.c, 202einauscp.c, 586einkompl.c, 29einles.c, 293einzeich.c, 53endlos.c, 581englzah1.c, 442englzah2.c, 443enumdemo.c, 576errodemo.c, 609erst.c, 3fakul.c, 273fakul2.c, 273farbstuf.c, 222fehlausg.c, 269fehler.c, 610fehlhand.c, 609fibonaci.c, 276figur.c, 211firmaelt.c, 498, 502firmver2.c, 522firmverw.c, 508floataus.c, 22floatint.c, 97fordrueb.c, 159free1.c, 481free2.c, 482free3.c, 483fremdspe.c, 398

freopen.c, 602funcbez.c, 271funkproj.c, 227funkzgr1.c, 284funkzgr2.c, 285geheim.c, 307georeih2.c, 134georeih3.c, 135georeih4.c, 154georeih5.c, 155georeihe.c, 132gerade.c, 351ggtkgv.c, 177gleitpkt.c, 562gleizae2.c, 158gleizae3.c, 158gleizae4.c, 158gleizaeh.c, 157goldbac1.c, 186goldbac2.c, 187goldbac3.c, 188groesse.c, 215guelt1.c, 300guelt2.c, 301guelt3.c, 302hamming1.c, 156hamming2.c, 156haus.c, 130hebrae.c, 371heron.c, 164heron2.c, 164heron3.c, 164hexd.c, 591hexextra.c, 589hexokdua.c, 139hexziff1.c, 122hexziff2.c, 124hintquad.c, 154hochdrei.c, 350inline.c, 270iniconst.c, 434inkrdekr.c, 41intaus.c, 21invest.c, 366isnrlow.c, 408jaeger1.c, 172jaeger2.c, 173just.c, 216karten.c, 219keinadr.c, 83kleigro1.c, 61kleigro2.c, 61kleigro3.c, 64kleigros.c, 166kompzahl.c, 514konto.c, 56konto2.c, 57kreis.c, 48kubikzah.c, 386kugzyvol.c, 280leerpara.c, 253linie.c, 207lottoza2.c, 152lottoza3.c, 153lottozah.c, 151lshift.c, 37lsystem2.c, 278manhat2.c, 147manhatan.c, 144mannweib.c, 119matadd.c, 368matadd2.c, 387mathverg.c, 88

mauscursor.c, 225mausdemo.c, 224max.c, 344max2zahl.c, 344memcpy.c, 411memmove.c, 412menue1.c, 117menue2.c, 118mfunk1.c, 87mineins.c, 116mineins2.c, 116mittwert.c, 142monataus.c, 432mrz_dez.c, 98mrz_dez2.c, 99nachvor.c, 55namlist1.c, 529namlist2.c, 535namlist3.c, 541namsort1.c, 463namsort2.c, 467namsort3.c, 468namsort4.c, 485namsort5.c, 486namsort6.c, 487namsort7.c, 487namsort8.c, 488namsort9.c, 488nreingab.c, 307numsort1.c, 470numsort2.c, 475numsort3.c, 479numsort4.c, 484oel.c, 205oelbohr.c, 171ophift.c, 39pfeilfix.c, 518piesarc.c, 221pixel.c, 206polygon.c, 213postprae.c, 44potenz.c, 235, 237potenz3.c, 239potenz4.c, 241printf1.c, 69printf2.c, 71printf3.c, 72printf4.c, 73printf5.c, 74qsort1.c, 391quader.c, 64quadrat.c, 149quadrat2.c, 150rabatt.c, 253rabatt2.c, 255reaktion.c, 203realloc.c, 477rechne1.c, 451rechne2.c, 452regel1.c, 246regel1a.c, 93, 246regel1b.c, 94regel1c.c, 94regel5.c, 96romzahl.c, 249rueckwae.c, 274sandmann.c, 218scanf1.c, 78scanf2.c, 79scanf3.c, 80scanf4.c, 82scanf5.c, 85skatkart.c, 574

626

Page 73: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Index

skilang.c, 548sort1.c, 382spiel21.c, 397spieltor.c, 304sprintf.c, 419sscanf.c, 418, 595static1.c, 309static2.c, 309strcat.c, 401strchr.c, 404strcmp.c, 402strcpya.c, 394strcpyz.c, 395strein1.c, 421strein2.c, 421strein3.c, 422strein4.c, 422striche.c, 238strlen.c, 403strncmp(), 402strncpy.c, 400strrchr.c, 404strtok(), 409strtok.c, 409strtol.c, 414structnoname.c, 506struoper.c, 503struvararr.c, 558struzgr1.c, 516struzgr2.c, 518struzgr3.c, 521suchtext.c, 405tabelle.c, 480tausch.c, 18, 256tausch2.c, 258tausch3.c, 287textaus1.c, 75textaus2.c, 75tmpnam.c, 606typedef1.c, 570typgroes.c, 91union.c, 560unturing.c, 329va_args.c, 348vchiffre.c, 250vertausc.c, 111vfprintf(), 594vieladd1.c, 265vieladd2.c, 266vieladd3.c, 267vokzaeh2.c, 425vokzaehl.c, 407vollkom2.c, 184vollkomm.c, 183vormakro.c, 354welchdat.c, 193welchtag.c, 192wurzstruct.c, 506wurzzahl.c, 432wz.c, 456zahltab.c, 145zahltab2.c, 146zgrarry1.c, 424zgrarry2.c, 424zins.c, 262zufzahl2.c, 169zufzahl3.c, 170zufzahl4.c, 170zusop2.c, 46zweit.c, 4

Programmablaufplando. . . while, 175for, 129

if (einsetig), 110if (zweiseitig), 106while, 161

programmglobal, 289Projektion von Koordinaten, 226Prototypen, 242Prozeduren, 238, 239Puffer

leeren, 605Pufferung, 603

keine, 604Voll-, 603voreingestellt, 604Zeilen-, 603

Punkt Operator, 496putc(), 582putchar(), 581putimage(), 217putpixel(), 204puts(), 422, 584

qsort(), 390, 525qsort1.c, 391quader.c, 64quadrat.c, 149quadrat2.c, 150

Römische Zahlen, 249rabatt.c, 253rabatt2.c, 255reaktion.c, 203realloc(), 475realloc.c, 477rechne1.c, 451rechne2.c, 452Rechteck

ausgefüllt zeichnen, 210zeichnen, 209

rectangle(), 209regel1.c, 246regel1a.c, 93, 246regel1b.c, 94regel1c.c, 94regel5.c, 96register, 310Rekursive Funktion, 273Rekursive Strukturen, 529Relationale Operatoren, 23Relativ Positionieren, 207remove(), 603rename(), 603Reservierung

Speicher, 463restrict, 394return, 238rewind(), 601romzahl.c, 249rueckwae.c, 274

sandmann.c, 218scanf(), 77, 421, 585, 617scanf1.c, 78scanf2.c, 79scanf3.c, 80scanf4.c, 82scanf5.c, 85Schnittstellen, 245Schriftart, 215Schrittweise Verfeinerung, 316sector(), 220SEEK_CUR Konstante, 599SEEK_END Konstante, 599SEEK_SET Konstante, 599

selbst.h, 63, 65self-typing, 11setbuf(), 604setcolor(), 207setfillstyle(), 209setlinestyle(), 207setpalette(), 222setrgbpalette(), 222settextjustify(), 215settextstyle(), 215setvbuf(), 604setviewport(), 223setwritemode(), 222Shift-Operator, 37short Datentyp, 8signed Datentyp, 8sin(), 86sinh(), 86sizeof, 91, 373skatkart.c, 574skilang.c, 548snprintf(), 595sort1.c, 382Sortier-Algorithmus, 389Sortierte

Liste, 534Speicher

Dynamische Freigabe, 463Dynamische Reservierung, 463

Speicherort, 292spiel21.c, 397spieltor.c, 304sprintf(), 419, 595sprintf.c, 419sqrt(), 86sscanf(), 418, 595sscanf.c, 418, 595Stack, 254, 273, 292Standard-E/A-Funktionen, 577Standard-Headerdateien, 341Standardausgabe, 580, 586Standardbibliothek, 51, 233Standardeingabe, 580, 586Standardfehlerausgabe, 580, 586static, 304static1.c, 309static2.c, 309stderr Konstante, 580, 586stdin Konstante, 580, 586stdout Konstante, 580stdout Kontante, 586Steuerzeichen\\, 67, 615\’, 67, 615\", 67, 615\a, 67, 615\b, 67, 615\e, 67, 615\f, 67, 615\ooo, 67, 615\r, 67, 615\t, 67, 615\v, 67, 615\x, 67, 615

strcat(), 401strcat.c, 401strchr(), 403strchr.c, 404strcmp(), 402strcmp.c, 402strcoll(), 410strcpy(), 395, 400strcpya.c, 394

627

Page 74: C-Programmierung unter Linux/UNIX/Windows -  · PDF fileDr. Helmut Herold Dr. Jörg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

Index

strcpyz.c, 395strcspn(), 408stream, 577strein1.c, 421strein2.c, 421strein3.c, 422strein4.c, 422strerror(), 410, 608strftime(), 190striche.c, 238String

Konkatenation, 75Lesen (formatiert), 595, 596Schreiben (formatiert), 595, 596

Stringkonkatenation, 75Strings, 392strlen(), 403strlen.c, 403strncat(), 401strncmp(), 402strncpy(), 400strncpy.c, 400strpbrk(), 406strrchr(), 404strrchr.c, 404strspn(), 408strstr(), 405strtod(), 416strtof(), 417strtok(), 409strtok.c, 409strtol(), 413strtol.c, 414strtold(), 417strtoll(), 416strtoul(), 416strtoull(), 416structnoname.c, 506Struktogramm

do. . . while-Anweisung, 175for-Anweisung, 129if-Aweisung (einseitig), 110if-Aweisung (zweiseitig), 106switch-Anweisung, 121while-Anweisung, 161

StrukturBitfelder, 564Array, 507Funktion, 514Initialisierung, 504rekursiv, 529Zeiger, 516

Strukturarray, 507dynamisch, 522

struoper.c, 503struvararr.c, 558struzgr1.c, 516struzgr2.c, 518struzgr3.c, 521strxfrm(), 411suchtext.c, 405switch, 121

tabelle.c, 480tan(), 86tanh(), 86tausch.c, 18, 256tausch2.c, 258tausch3.c, 287Technik

Modul-, 314Temporäre Dateien, 605Text

Breite, 215Font, 215Gröse, 215Höhe, 215Schreibrichtung, 215Schriftart, 215Zeichensatz, 215

textaus1.c, 75textaus2.c, 75textheight(), 215Textmodus, 596textwidth(), 215Tilde Operator, 28time(), 191TMP_MAX Konstante, 606tmpfile(), 606tmpnam(), 606tmpnam.c, 606tolower(), 60Top-Down, 316toupper(), 60Transformation von Koordinaten, 226TRUE, 24true Konstante, 24turing.h, 322Turingmaschinen, 319Typ-Qualifizierer, 310typedef, 569typedef1.c, 570typgroes.c, 91

UmlenkungE/A, 586

ungetc(), 589uninitialisierte Variable, 45union, 559union.c, 560Unions, 559unsigned Datentyp, 8unturing.c, 329

va_arg(), 264va_args.c, 348va_end(), 264va_list, 264va_start(), 264Variable initialisieren, 46Variablen

Definition, 14Deklaration, 14Initialisierung, 19Name, 13nicht vorbesetzt, 45uninitialisiert, 45Vereinbarung, 14Vertauschen, 18, 111

vchiffre.c, 250Vektor, 357Vergleichsoperatoren, 23Verkettete Liste, 529, 541Verschiebechiffre, 250vertausc.c, 111Vertauschen von Variablen, 18, 111vfprintf(), 594vfscanf(), 596vieladd1.c, 265vieladd2.c, 266vieladd3.c, 267void, 238, 253vokzaeh2.c, 425vokzaehl.c, 407volatile, 310, 312Voll-Pufferung, 603

vollkom2.c, 184vollkomm.c, 183Vollkommene Zahlen, 183, 184Vordefinierte Makros, 353Voreingestellte Pufferung, 604vormakro.c, 354vprintf(), 594vscanf(), 596vsnprintf(), 596vsprintf(), 596vsscanf(), 596

welchdat.c, 193welchtag.c, 192Wertebereich von Datentypen, 9, 614while, 161Wochentag eines Datums, 192wurzstruct.c, 506wurzzahl.c, 432wz.c, 456

Zahlenzu große, 10zu kleine, 10

zahltab.c, 145zahltab2.c, 146zahlwort.c, 339Zeichenfarbe

erfragen, 207festlegen, 207

Zeichensatz, 215Zeichnen

zweidimensionalen Balken, 210ausgefüllte Ellipse, 209, 220ausgefüllter Kreis, 220ausgefülltes Polygon, 210ausgefülltes Rechteck, 210dreidimansionalen Balken, 210Ellipse, 209Kreis, 209Kreisbogen, 210Linie, 207Polygon, 210Rechteck, 209

Zeigerauf Funktionen, 280auf Zeiger, 436char, 392Funktionsadressen, 451Operationen mit, 381Pfeiloperator, 517Struktur, 516und Arrays, 374

Zeigerarrays, 436Zeilen-Pufferung, 603Zeilenummerierung, 354Zeitangaben, 189zgrarry1.c, 424zgrarry2.c, 424zins.c, 262zu große Zahlen, 10zu kleine Zahlen, 10zufzahl2.c, 169zufzahl3.c, 170zufzahl4.c, 170zusop2.c, 46Zuweisung, 17Zuweisungsoperator, 17, 39zweidimensionale Arrays, 365Zweier-Komplement, 29Zweiseitige if-Anweisung, 105zweit.c, 4

628