C-Programmierung unter Linux/UNIX/Windows - . Helmut Herold Dr. Jrg Arndt C-Programmierung unter Linux/UNIX/Windows Beispiele, Anwendungen, Programmiertechniken

  • Published on
    06-Feb-2018

  • View
    213

  • Download
    1

Transcript

Dr. Helmut HeroldDr. Jrg ArndtC-Programmierung unterLinux / UNIX / WindowsBeispiele, Anwendungen,ProgrammiertechnikenAlle in diesem Buch enthaltenen Programme, Darstellungen und Informationen wurden nach bestem Wis-sen erstellt und mit Sorgfalt getestet. Dennoch sind Fehler nicht ganz auszuschlieen. 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 wren und daher von jedermannverwendet werden drften.Alle Warennamen werden ohne Gewhrleistung der freien Verwendbarkeit benutzt und sind mglicher-weise eingetragene Warenzeichen. Der Verlag richtet sich im Wesentlichen nach den Schreibweisen derHersteller. Andere hier genannte Produkte knnen Warenzeichen des jeweiligen Herstellers sein.Dieses Werk ist urheberrechtlich geschtzt.Alle Rechte, auch die der bersetzung, des Nachdruckes und der Vervielfltigung 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 fr Zwecke der Unter-richtsgestaltung, reproduziert oder unter Verwendung elektronischer Systeme verarbeitet, vervielfltigtoder verbreitet werden.Bibliografische Information Der Deutschen BibliothekDie 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.deGesamtlektorat: Nicolaus MillinFachlektorat: Dieter Bloms, Jrg Dippel, Klaas Freitag, Bruno Gerz, Bernhard Hoelcker, Bjrn Jacke, An-dreas Jaeger, Dirk Pankonin, Wolfgang Rosenauer, Christian Steinrcken, Peter VarkolySatz: LATEXDruck: druckhaus kthen GmbH, Kthen (http://www.koethen.dePrinted in Germany on acid free paper.Inhaltsverzeichnis1 Einfhrendes Beispiel 31.1 Erste wesentliche C-Regeln . . . . . . . . . . 31.2 Zeilen-Kommentare mit // (neu in C99) . . . . . . . 51.3 Gute Lesbarkeit von Programmen . . . . . . . . . 51.4 Vermeiden von geschachtelten Kommentaren . . . . . . 62 Elementare Datentypen 72.1 Die Grunddatentypen in C . . . . . . . . . . 72.2 Wertebereiche fr die einzelnen Datentypen . . . . . . . 92.3 Fallgrube: Verlust von Bits bei zu groen Zahlen . . . . . . 103 Konstanten 113.1 char-Konstanten . . . . . . . . . . . . 113.2 Ganzzahlige Konstanten . . . . . . . . . . . 113.3 Gleitpunktkonstanten . . . . . . . . . . . 124 Variablen 134.1 Variablen und die C-Regeln fr Variablennamen . . . . . . 134.2 Tipps zur Wahl der Variablennamen . . . . . . . . 144.3 Deklaration von Variablen . . . . . . . . . . 144.4 Tipp: Variablen bereits bei Deklaration dokumentieren . . . . 165 Ausdrcke und Operatoren 175.1 Der einfache Zuweisungsoperator . . . . . . . . . 175.1.1 Allgemeines zum einfachen Zuweisungsoperator . . . . 175.1.2 Initialisierung von Variablen . . . . . . . . 195.2 Arithmetische Operatoren . . . . . . . . . . 195.2.1 Die arithmetischen Operatoren . . . . . . . . 19VInhaltsverzeichnis5.2.2 Die C-Begriffe Ausdruck und Anweisung . . . . . . 205.2.3 Ausgabe von int-Variablen und -Ausdrcken . . . . . 215.2.4 Ausgabe von Gleitpunkt-Variablen und -Ausdrcken . . . 215.2.5 Fallgrube: Ganzzahl- statt Gleitpunktdivision . . . . . 225.3 Vergleichsoperatoren . . . . . . . . . . . 235.3.1 Die unterschiedlichen Vergleichsoperatoren . . . . . 235.3.2 Die zwei Wahrheitswerte von Vergleichen . . . . . . 235.3.3 Prioritten der Vergleichsoperatoren . . . . . . . 235.4 Logische Operatoren . . . . . . . . . . . 245.4.1 TRUE und FALSE in C . . . . . . . . . . 245.4.2 Der Datentyp _Bool (neu in C99) . . . . . . . 245.4.3 Die C-Operatoren fr NOT, AND und OR im berblick . . . 255.4.4 Der Negations-Operator ! . . . . . . . . . 255.4.5 Der AND-Operator && . . . . . . . . . 265.4.6 Der OR-Operator || . . . . . . . . . . 265.4.7 Die Prioritt der logischen Operatoren . . . . . . 265.4.8 Keine unntige Auswertung rechts von &&und || . . . . 275.4.9 bung: berprfungen mit logischen Operatoren . . . . 285.5 Bit-Operatoren . . . . . . . . . . . . . 285.5.1 Bitweise Invertierung mit ~ . . . . . . . . . 285.5.2 Bitweise AND-Verknpfung mit & . . . . . . . 305.5.3 Bitweise OR-Verknpfung mit | . . . . . . . . 315.5.4 Bitweise XOR-Verknpfung mit ^ . . . . . . . 335.5.5 Bit-Operatoren nur fr ganzzahlige Datentypen erlaubt . . . 345.5.6 Fallgruben . . . . . . . . . . . . 345.5.7 bung: berprfungen mit Bit-Operatoren . . . . . 365.6 Shift-Operatoren . . . . . . . . . . . . 375.6.1 Die beiden Shift-Operatoren . . . . . . 375.6.2 Shift-Operatoren nur fr ganzzahlige Datentypen erlaubt . . 385.6.3 Prioritt der Shift-Operatoren . . . . . . . . 385.7 Zusammengesetzte Zuweisungsoperatoren . . . . . . . 395.7.1 Die zusammengesetzten Zuweisungsoperatoren . . . . 395.8 Inkrement- und Dekrement-Operatoren . . . . . . . . 405.8.1 Inkrementieren und Dekrementieren mit ++ und -- . . . . 405.8.2 Prfix- und Postfix-Schreibweise fr ++ und -- . . . . . 405.8.3 ++ und -- ist nur fr Variablen erlaubt . . . . . . 425.8.4 ++ und -- ist nicht auf linken Seite einer Zuweisung erlaubt . . 42VIInhaltsverzeichnis5.9 Priorittstabelle fr Operatoren . . . . . . . . . 425.10 Assoziativitt der Operatoren . . . . . . . . . . 435.11 Erlaubte und unerlaubte Operationen fr C-Datentypen . . . . 435.12 Prioritt und Auswertungszeitpunkt bei ++ und -- . . . . . 435.13 Fallgrube: Zugriff auf nicht vorbesetzte Variablen . . . . . . 455.14 bungen . . . . . . . . . . . . . . 466 Symbolische Konstanten 476.1 Konstanten-Definition mit #define . . . . . . . . . 476.1.1 Die Direktive #define . . . . . . . . . . 476.1.2 Regeln fr Konstanten-Namen bei #define . . . . . . 496.1.3 Konstanten machen Programm leicht nderbar . . . . . 496.2 Konstanten-Definition mit const . . . . . . . . . 497 Ein- und Ausgabe 517.1 Headerdateien und #include . . . . . . . . . . 517.1.1 Bibliotheken und Headerdateien . . . . . . . 517.1.2 Eigene Headerdateien . . . . . . . . . . 527.2 Ein- und Ausgabe eines Zeichens . . . . . . . . . 537.2.1 getchar() und putchar() . . . . . . . . . 537.2.2 Gepufferte Eingabe bei getchar() . . . . . . . . 537.2.3 Puffer-Bereinigung mit Dummy getchar() . . . . . . 577.2.4 Puffer-Bereinigung ist nicht immer notwendig . . . . . 587.2.5 Fallgrube: Zahlen nicht mit getchar() einlesen . . . . . 607.2.6 Die Headerdatei . . . . . . . . 607.2.7 Einfache Makros . . . . . . . . . . . 627.3 Die Ausgabe mit printf() . . . . . . . . . . . 677.3.1 Die Funktion printf() . . . . . . . . . . 677.3.2 Fallgruben . . . . . . . . . . . . 747.3.3 Tipps . . . . . . . . . . . . . 757.4 Die Eingabe mit scanf() . . . . . . . . . . . 777.4.1 Die Funktion scanf() . . . . . . . . . . 777.4.2 Fallgruben . . . . . . . . . . . . 837.4.3 Die Headerdatei . . . . . . . . . 867.4.4 Fallgrube: Vergessen von #include . . . . . 888 Datentypumwandlungen 918.1 Implizite Datentypumwandlungen . . . . . . . . 91VIIInhaltsverzeichnis8.1.1 Der sizeof-Operator . . . . . . . . . . 918.1.2 Implizite Datentypumwandlungen . . . . . . . 938.1.3 Fallgrube: Zuweisen von Ganzzahlausdrcken an Gleitpunktvariablen 978.2 Explizite Datentypumwandlungen . . . . . . . . . 988.2.1 Explizite Datentypumwandlungen mit cast-Operator . . . 988.2.2 Fallgruben . . . . . . . . . . . . 989 Die Headerdateien Inhaltsverzeichnis15 Die for-Anweisung 12915.1 Die for-Anweisung . . . . . . . . . . . . 12915.2 Die for-Schleife und der Komma-Operator . . . . . . . 13315.3 Fallgrube: Semikolon am Ende des for-Schleifenkopfs . . . . . 13615.4 Geschachtelte Schleifen . . . . . . . . . . . 13715.5 Eine endlose for-Schleife . . . . . . . . . . . 14315.6 for bei Durchlufen mit festen Schrittweiten . . . . . . . 14315.7 Variablendeklaration im for-Schleifenkopf (neu in C99) . . . . 14615.8 Programmiertechniken . . . . . . . . . . . 14615.8.1 Anhalten einer Bildschirmausgabe . . . . . . . 14615.8.2 Zeilenvorschbe bei geschachtelten Schleifen . . . . . 14915.8.3 Kombinieren mit for-Schleifen . . . . . . . . 15015.8.4 Zwischeninformationen bei rechenintensiven Programmen . . 15215.8.5 Merker in for-Schleifen bei Eintreten von Ereignissen . . . 15315.9 Fallgruben . . . . . . . . . . . . . 15415.9.1 Niemals die Laufvariable im Schleifenkrper ndern . . . 15415.9.2 Gleitpunktzahlen niemals auf Gleichheit prfen . . . . 15715.9.3 Laufvariable einer for-Schleife luft ber Endwert hinaus . . 15916 Die while-Anweisung 16116.1 Die while-Anweisung . . . . . . . . . . . 16116.2 Programmiertechniken . . . . . . . . . . . 16316.2.1 while bei unbekannter Zahl von Schleifendurchlufen . . . 16316.2.2 Konsistenzprfungen bei Eingaben . . . . . . . 16516.2.3 Die Konstante EOF . . . . . . . . . . 16616.2.4 Minimum und Maximum in einer Zahlenfolge . . . . . 16716.3 Zufallszahlen in C . . . . . . . . . . . . 16817 Die do. . . while-Anweisung 17517.1 Die do. . . while-Anweisung . . . . . . . . . . 17517.2 Programmiertechniken . . . . . . . . . . . 17717.2.1 do. . . while-Schleifen nicht so oft wie while-Schleifen . . . 17717.2.2 Abschlieendes } while immer in einer Zeile . . . . 17818 Die break-Anweisung 17918.1 Die break-Anweisung . . . . . . . . . . . 17918.2 break bewirkt Verlassen einer Schleifenebene . . . . . . 18018.3 Programmiertechniken . . . . . . . . . . . 180IXInhaltsverzeichnis18.3.1 Sofortiges Verlassen von Schleifen und switch . . . . . 18018.3.2 Endlosschleifen und break . . . . . . . . . 18219 Die continue-Anweisung 18319.1 Die continue-Anweisung . . . . . . . . . . . 18319.2 Programmiertechniken . . . . . . . . . . . 18419.2.1 continue nur im uersten Notfall . . . . . . . 18419.2.2 Korrekte Programme mssen auch schnell sein . . . . . 18519.3 Datums- und Zeitangaben () . . . . . . . . 18919.3.1 Konstanten und Datenytpen . . . . . . . . 18919.3.2 Funktionen . . . . . . . . . . . . 18919.3.3 Beispiele zu Funktionen aus . . . . . . 19220 Marken und die goto-Anweisung 19720.1 Marken und die goto-Anweisung . . . . . . . . . 19720.2 Programmiertechniken . . . . . . . . . . . 19720.2.1 goto nur im uersten Notfall . . . . . . . . 19720.2.2 Lesbarere und schnellere Programme mit goto . . . . . 19821 Grafikprogrammierung unter Linux 19921.1 Benutzung von LCGI . . . . . . . . . . . 19921.2 Grafikmodus ein- und ausschalten . . . . . . . . . 20021.3 Eingaben im Grafikmodus . . . . . . . . . . 20021.4 Bildschirm-, Farben- und Pixel-Operationen . . . . . . . 20421.5 Positionieren, Linien zeichnen und Farbe einstellen . . . . . 20721.6 Figuren zeichnen und ausfllen . . . . . . . . . 20921.7 Einstellungen fr Textausgaben . . . . . . . . . 21521.8 Bilder laden, Bildteile speichern und einblenden . . . . . . 21721.9 Kuchenstcke malen . . . . . . . . . . . 22021.10Grafikpaket neu bzw. anders einrichten . . . . . . . . 22221.11Arbeiten mit mehreren Zeichenfenstern . . . . . . . . 22321.12Programmierung der Maus . . . . . . . . . . 22321.13Transformation mathematischer Koordinaten . . . . . . 22622 Funktionen 23122.1 Allgemeines zu Funktionen . . . . . . . . . . 23122.1.1 Allgemeines Beispiel zu Funktionen . . . . . . . 23122.1.2 Die Begriffe Parameter und Argumente . . . . . . 233XInhaltsverzeichnis22.1.3 Bibliotheken und Headerdateien . . . . . . . 23322.2 Erstellen eigener Funktionen . . . . . . . . . . 23422.2.1 Definition von Funktionen in C89/C99 . . . . . . 23422.2.2 Definition von Funktionen in Alt-C . . . . . . . 23722.2.3 Die return-Anweisung . . . . . . . . . . 23822.2.4 Funktionen ohne Rckgabewert . . . . . . . . 23822.2.5 Forward-Deklarationen . . . . . . . . . 23922.2.6 Funktions-Prototypen . . . . . . . . . . 24222.2.7 Implizite Datentypumwandlung beim Funktionsaufruf . . . 24622.2.8 Typische Anwendungsgebiete von Funktionen . . . . . 24822.3 Die Parameter von Funktionen . . . . . . . . . 25322.3.1 Leere Parameterliste durch Angabe von void . . . . . 25322.3.2 Bei Funktionsaufrufen findet nur Wertbergabe statt . . . 25322.3.3 Call by reference . . . . . . . . . . . 25822.3.4 Auswertung der Argumente findet vor Funktionsaufruf statt . . 26022.3.5 Fallgruben . . . . . . . . . . . . 26122.4 Ellipsen-Prototypen fr Funktionen mit variabler Argumentzahl . . 26322.4.1 Reihenfolge der Argument-Ablage im Stack . . . . . 26322.4.2 Ellipsen-Prototypen . . . . . . . . . . 26422.4.3 Abarbeiten variabel langer Argumentlisten . . . . . 26422.4.4 Verfahren zum Abarbeiten variabel langer Argumentlisten . . 26522.4.5 Fallgruben . . . . . . . . . . . . 26922.5 Neuheiten in C99 . . . . . . . . . . . . 27022.5.1 Inline-Funktionen . . . . . . . . . . 27022.5.2 Der vordefinierte Name __func__ . . . . . . . 27122.5.3 Keine Untersttzung von implizitem int . . . . . . 27222.5.4 Keine impliziten Funktionsdeklarationen . . . . . . 27222.5.5 Einschrnkungen bei return . . . . . . . . 27222.6 Rekursive Funktionen . . . . . . . . . . . 27322.6.1 Allgemeines zu rekursiven Funktionen . . . . . . 27322.6.2 Einige typische Anwendungen fr die Rekursion . . . . 27622.7 Zeiger auf Funktionen . . . . . . . . . . . 28022.7.1 Zeiger auf Funktionen . . . . . . . . . . 28022.7.2 Typische Anwendungen . . . . . . . . . 28323 Speicherklassen und Modultechnik 28723.1 Gltigkeitsbereich, Lebensdauer, Speicherort . . . . . . 287XIInhaltsverzeichnis23.1.1 Gltigkeitsbereich . . . . . . . . . . 28723.1.2 Lebensdauer . . . . . . . . . . . . 29123.1.3 Speicherort . . . . . . . . . . . . 29223.1.4 Gltigkeit, Lebensdauer und Speicherort im berblick . . . 29223.1.5 bung: Ausgabe des Programms block3.c . . . . . 29323.2 Schlsselwrter extern, auto, static und register . . . . . . 29323.2.1 Das Schlsselwort extern . . . . . . . . . 29323.2.2 Das Schlsselwort auto . . . . . . . . . 29623.2.3 Fallgrube: Niemals Adressen von auto-Variablen zurckgeben . 30323.2.4 Das Schlsselwort static . . . . . . . . . 30423.2.5 Das Schlsselwort register . . . . . . . . . 31023.3 Die Schlsselwrter const und volatile . . . . . . . . 31023.3.1 Das Schlsselwort const . . . . . . . . . 31023.3.2 Das Schlsselwort volatile . . . . . . . . . 31223.3.3 Kombination von const und volatile . . . . . . . 31323.4 Modultechnik und Information Hiding . . . . . . . . 31423.4.1 Linker und Compiler . . . . . . . . . . 31723.4.2 Beispiel: Simulation von Turingmaschinen . . . . . 31924 Prprozessor-Direktiven 33124.1 Bedingte Kompilierung . . . . . . . . . . . 33224.1.1 Prprozessor-Direktiven zur bedingten Kompilierung . . . 33224.1.2 Typische Anwendungen . . . . . . . . . 33424.1.3 Testen mit Makro assert() aus Headerdatei . . . 33924.2 Einkopieren von anderen Headerdateien . . . . . . . 34024.2.1 Die Prprozessor-Direktive #include . . . . . . . 34024.2.2 Typische Anwendungen . . . . . . . . . 34124.3 Definition von Makros (#define und #undef) . . . . . . . 34224.3.1 Definition von Konstanten mit #define . . . . . . 34224.3.2 Definition von Funktionsmakros mit #define . . . . . 34324.3.3 Operator #: Ersetzung von Makroparametern durch String . . 34524.3.4 Operator ##: Zusammensetzen neuer Namen . . . . . 34624.3.5 Rekursive Makrodefinitionen . . . . . . . . 34624.3.6 Makros mit variabler Anzahl von Argumenten (neu in C99) . . 34824.3.7 Makrodefinitionen mit #undef wieder aufheben . . . . 34924.3.8 Unterschiede zwischen Funktionen und Makros . . . . 34924.4 Vordefinierte Makronamen . . . . . . . . . . 353XIIInhaltsverzeichnis24.5 Die restlichen Prprozessor-Direktiven . . . . . . . . 35424.5.1 #line Festlegen einer neuen Zeilennumerierung . . . . 35424.5.2 #error Ausgeben von Fehlermeldungen . . . . . . 35524.5.3 #pragma Festlegen von compilerspezifischem Verhalten . . 35524.5.4 # Die Null-Direktive . . . . . . . . . . 35525 Zeiger und Arrays 35725.1 Eindimensionale Arrays . . . . . . . . . . . 35725.1.1 Eindimensionale Arrays . . . . . . . . . 35725.1.2 Nur statische Arrays erlaubt (in C89) . . . . . . . 36125.1.3 Von Arrays belegter Speicherplatz . . . . . . . 36225.1.4 Fallgruben . . . . . . . . . . . . 36325.2 Mehrdimensionale Arrays . . . . . . . . . . 36525.2.1 Zweidimensionale Arrays . . . . . . . . . 36525.2.2 Drei-, vier-, fnf- und sonstige mehrdimensionale Arrays . . 37325.2.3 sizeof liefert die Gre eines Arrays . . . . . . . 37325.3 Zusammenhnge zwischen Arrays und Zeigern . . . . . . 37425.3.1 Arrayname ist konstanter Zeiger auf erstes Element . . . . 37425.3.2 Zugriff auf Arrayelemente ist auch ber Zeiger mglich . . . 37725.3.3 Unterschied zwischen Arraynamen und echtem Zeiger . . . 38025.3.4 Erlaubte Operationen mit Zeigern . . . . . . . 38125.3.5 Unerlaubte Operationen mit Zeigern . . . . . . . 38125.3.6 bergabe eines Arrays an eine Funktion mittels Adresse . . . 38425.3.7 call by value fr Arrays (Zeiger) . . . . . . . . 38825.3.8 Nachlese zu Arrays und Zeiger . . . . . . . . 38925.3.9 Algorithmus: Der Bubble-Sort . . . . . . . . 38925.3.10 Verwendung der Bibliotheksfunktion qsort() . . . . . 39025.4 Strings und char-Zeiger . . . . . . . . . . . 39225.4.1 Besonderheiten von C-Strings . . . . . . . . 39225.4.2 Das Schlsselwort restrict fr Zeiger (neu in C99) . . . . 39425.4.3 Eigene Realisierung der Funktion strcpy() mit Arrays . . . 39425.4.4 Eigene Realisierung der Funktion strcpy() mit Zeigern . . . 39525.4.5 Die Headerdatei . . . . . . . . . 39825.4.6 Umwandeln von Strings in numerische Werte . . . . . 41325.4.7 Umwandeln von numerischen Werten in Strings . . . . 41925.4.8 Besonderheiten beim Einlesen von Strings mit scanf() . . . 42125.4.9 Ein- und Ausgabe von Strings mit gets() und puts() . . . . 422XIIIInhaltsverzeichnis25.4.10 Unterschied zwischen Zeiger- und Array-Deklaration . . . 42325.4.11 Direkter Zugriff auf Zeichen in einer String-Konstante . . . 42525.5 Array-Initialisierungen . . . . . . . . . . . 42625.5.1 Initialisierung von Arrays . . . . . . . . . 42625.5.2 Dimensionierungsangaben bei der Initialisierung . . . . 42825.5.3 Zeiger auf unbenamte Arrays (neu in C99) . . . . . 42925.5.4 Implizite Initialisierung bei static-Variablen/Arrays . . . . 43025.5.5 Initialisierung lokaler Variablen auch mit Nicht-Konstanten . . 43125.5.6 Initialisierung von lokalen Arrays in C89/C99 . . . . . 43225.5.7 Initialisierung von lokalen Arrays mit variablen Werten (neu in C99) 43225.5.8 Initialisierung von lokalen Arrays mit 0 oder NULL . . . . 43325.5.9 Initialisierte Arrays mit const vor berschreiben schtzen . . 43425.6 Lokale Arrays variabler Lnge (neu in C99) . . . . . . . 43525.7 Zeigerarrays und Zeiger auf Zeiger . . . . . . . . 43625.7.1 Einfache Zeigerarrays . . . . . . . . . . 43625.7.2 Zeiger auf Arrays . . . . . . . . . . . 43725.7.3 Vertauschen von zwei Arrays ber Zeiger . . . . . . 43825.7.4 bergabe von Arrays an Funktionen . . . . . . . 44025.7.5 Zeiger-Zeiger . . . . . . . . . . . 44125.7.6 Unterschiede bei zweidimensionalen Arrays und Zeigerarrays . 44225.7.7 Zugriff auf beliebige Elemente in einem Zeigerarray . . . 44525.7.8 Zeigerarrays mit Funktionsadressen . . . . . . . 45126 Argumente auf der Kommandozeile 45326.1 Die Parameter argc und argv der Funktion main() . . . . . 45326.2 Optionen auf der Kommandozeile . . . . . . . . . 45627 Dynamische Speicher-Reservierung und -Freigabe 46327.1 Nachteile von statischen Arrays . . . . . . . . . 46327.1.1 Gefahr der Speicherberschreibung . . . . . . . 46427.1.2 Speicherplatzvergeudung . . . . . . . . . 46527.2 Speicher reservieren mit malloc() . . . . . . . . . 46627.2.1 Die Funktion malloc() . . . . . . . . . . 46627.2.2 Dynamische Arrays fr beliebige Datentypen . . . . . 47027.2.3 Konvertierung von void-Zeigern . . . . . . . 47327.3 Speicher reservieren und initialisieren mit calloc() . . . . . 47427.4 Grennderung eines allozierten Speichers mit realloc() . . . . 475XIVInhaltsverzeichnis27.4.1 Die Funktion realloc() . . . . . . . . . . 47527.4.2 Besonderheiten der Funktion realloc() . . . . . . 47827.4.3 Schnellere Programme mit greren Speicherblcken . . . 47927.5 Freigeben von dynamisch reservierten Speicherbereich . . . . 48127.5.1 Die Funktion free() . . . . . . . . . . 48127.5.2 Fallgrube: free() setzt bergebenen Zeiger nicht auf NULL . . 48127.5.3 Tipp: Eigenes Makro zur Freigabe von dynamischen Speicher . . 48327.6 Fallgruben . . . . . . . . . . . . . 48427.6.1 free() nur auf von malloc(), calloc() und realloc() gelieferte Zeiger . 48427.6.2 Allozieren von Speicherplatz in einer Funktion . . . . . 48527.7 Programmiertechnik: Dynamische Zeiger-Arrays . . . . . . 48827.8 Fallgrube: free() bei Zeiger-Arrays . . . . . . . . . 48928 Strukturen 49128.1 Deklaration und Definition von Strukturen . . . . . . . 49128.1.1 Deklaration von Strukturen . . . . . . . . . 49128.1.2 Wichtige Regeln und Hinweise fr Strukturdeklarationen . . 49228.1.3 Definition von Strukturvariablen . . . . . . . 49328.1.4 Zusammenfassung von Strukturdeklaration und -definition . . 49428.1.5 Namenlose Strukturen . . . . . . . . . . 49528.2 Operationen mit Strukturvariablen . . . . . . . . . 49628.2.1 Zugriff auf Strukturkomponenten mittels Punktoperator . . . 49628.2.2 Zuweisung zwischen Strukturkomponenten . . . . . 49728.2.3 Zuweisung ganzer Strukturvariablen . . . . . . . 50228.2.4 Vergleich von Strukturvariablen ist nicht mglich . . . . 50228.2.5 Casting fr komplette Strukturvariable ist nicht mglich . . . 50328.2.6 Adre- und sizeof-Operator fr Strukturvariablen erlaubt . . 50328.3 Initialisierung von Strukturvariablen . . . . . . . . 50428.3.1 Initialisierung von Strukturvariablen in C89 und C99 . . . 50428.3.2 Initialisierung von Strukturvariablen (nur in C99) . . . . 50528.4 Strukturarrays . . . . . . . . . . . . . 50728.5 Strukturen als Funktionsparameter . . . . . . . . 51428.6 Zeiger und Strukturen . . . . . . . . . . . 51628.6.1 Allgemeines zu Zeiger und Strukturen . . . . . . 51628.6.2 Dynamische Strukturarrays . . . . . . . . 52228.6.3 Rekursive Strukturen . . . . . . . . . . 52928.7 Strukturen mit variabel langen Arrays (neu in C99) . . . . . 558XVInhaltsverzeichnis28.8 Spezielle Strukturen (Unions und Bitfelder) . . . . . . . 55928.8.1 Unions . . . . . . . . . . . . . 55928.8.2 Bitfelder . . . . . . . . . . . . 56429 Eigene Datentypen 56929.1 Definition eigener Datentypnamen mit typedef . . . . . . 56929.1.1 Vergabe neuer Namen an existierende Datentypen mit typedef . 56929.1.2 Hhere Portabilitt und bessere Lesbarkeit durch typedef . . 57229.2 Definition eigener Datentypen mit enum . . . . . . . 57329.2.1 Definition eigener Datentypen mit enum . . . . . . 57329.2.2 Regeln fr enum . . . . . . . . . . . 57530 Dateien 57730.1 Hhere E/A-Funktionen . . . . . . . . . . . 57730.1.1 Vordefinierte Struktur FILE . . . . . . . . . 57830.1.2 ffnen und Schlieen von Dateien . . . . . . . 57830.1.3 Lesen und Schreiben in Dateien . . . . . . . . 58030.1.4 Unterschied zwischen Text- und Binrmodus . . . . . 59630.1.5 Positionieren in Dateien . . . . . . . . . 59830.1.6 ffnen einer Datei mit existierenden Stream . . . . . 60130.1.7 Lschen und Umbenennen von Dateien . . . . . . 60330.1.8 Pufferung . . . . . . . . . . . . 60330.1.9 Temporre Dateien . . . . . . . . . . 60530.1.10 Ausgabe von System-Fehlermeldungen . . . . . . 60831 Anhang 61331.1 Priorittstabelle fr die Operatoren . . . . . . . . 61331.2 C-Schlsselwrter . . . . . . . . . . . . 61331.3 Wertebereiche fr die einzelnen Datentypen . . . . . . . 61431.4 Die Funktion printf() . . . . . . . . . . . 61531.5 Die Funktion scanf() . . . . . . . . . . . 61731.6 ASCII-Tabelle . . . . . . . . . . . . . 619XVIInhaltsverzeichnisVorwortEin paar Worte zu C und seiner GeschichteZu Beginn wird hier kurz auf die Historie von C und die verschiedenen Standardisierungenvon C eingegangen.Die Entstehung von CDie 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. Vorlufer 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 vollstndig in C geschrieben wurde. In den 80er Jah-ren hat sich aber C als eine universell einsetzbare Sprache entpuppt, was dazu fhrte, 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 fr alle C-Fragen. Diese Bibel lie jedoch einige Fragen offen. Sowurde bereits in den frhen 80er Jahren die Notwendigkeit fr einen wirklichen C-Standarderkannt: C89 der erste Standard fr 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 fr CIm Jahre 1999 wurde ein neuer Standard fr C geschaffen. Diese Version nennt sich ISOC99, oder kurz auch nur C99. C99 enthlt 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 grere nderungen von einem anderen C99-Compiler auf einer anderen Ma-schine in eine ablauffhige Version bersetzt werden knnen.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 hheren Sphren der objektorientierten Programmierung aufsteigen kann.1ANSI (American National Standard Institute) ist eine amerikanische Organisation, welche Mitglied derInternational Standards Organisation (ISO) ist.1InhaltsverzeichnisHinweise zu diesem BuchDieses Buch beschreibt die Theorie der Programmiersprache C anhand vieler Beispiele. Da-bei begngt 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 fr eine erfolgreiche Programmierung in C unverzicht-bar ist.Nach dem Durcharbeiten dieses Buches verfgt der Leser ber ein gesundes und breites C-Fundament, und ist in der Lage, erfolgreich in C zu programmieren. Die Intention dieses Buchesist es nmlich: den C-Anfnger systematisch vom C-Basiswissen bis hin zu den fortgeschrittenen Tech-niken der Programmierung zu fhren. dem bereits erfahrenen C-Programmierer aufgrund der Vielzahl von Tipps, fundamen-talen Algorithmen und ntzlichen Programmiertechniken eine Vertiefung bzw. Ergn-zung seines C-Wissens zu ermglichen.Layout der Programme in diesem BuchEs sei vorweg darauf hingewiesen, dass sich die in diesem Buch vorgestellten Programme nichtimmer an die allgemein gltigen Programmier-Richtlinien halten. So befinden sich z. B. manch-mal mehrere Anweisungen in einer Zeile. Dies wurde sowohl aus Platzgrnden 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 Grnden hinsichtlich Lesbarkeit ungnstiger alsein Programm, das sich vollstndig auf einer Seite befindet, ohne dass der Leser stndig vor-und zurckblttern muss.Downloads zu diesem BuchAlle Programme in diesem Buch knnen von folgender Webseitehttp://www.millin.deheruntergeladen werden.Windows-KompatibilittAuch wenn dieses Buch ursprnglich fr die C-Programmierung unter Linux konzipiert wur-de, so sind doch nahezu alle in diesem Buch vorgestellten Programme auch unter Windows-Compilern lauffhig. Einschrnkungen 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 ursprnglich fr Linux eigens im Rahmen dieses Buches entwickelten Graphik-bibliothek LCGI existiert zwischenzeitlich eine Windows-Version, die von der oben erwhntenWebseite heruntergeladen werden kann.2Kapitel 1Einfhrendes Beispiel1.1 Erste wesentliche C-RegelnDas erste C-Programm erst.c:/***************************************************************//* Einfuehrendes Beispiel *//***************************************************************/#include 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. Vorlufig mssen alle C-Programme die Zeichenfolge int main(void) enthalten, wasden eigentlichen Programmanfang kennzeichnet.2. Der zu main() gehrige Programmteil ist in geschweiften Klammern einzubetten. Dabeikennzeichnet:{ den Anfang und} das Ende des entsprechenden Programmteils.3. Ein Kommentar wird mit /* ..... */ geklammert. Kommentare sind Informationen fr denProgrammierer und werden vom C-bersetzer (auch C-Compiler genannt) nicht beachtet.Um ein Programm mglichst lesbar zu machen, sollte es mglichst gut kommentiert sein.4. Bildschirmausgaben sind mit printf("Text") mglich. Auszugebender Text muss dabeimit Anfhrungszeichen geklammert sein.31 Einfhrendes Beispiel5. Um die einzelnen C-Anweisungen voneinander zu trennen, muss immer ein Semikolonals Trennzeichen angegeben werden. Vor und nach einem Semikolon knnen beliebig vie-le Leerzeichen oder auch Leerzeilen angegeben werden; gilt brigens auch fr andereWrter wie main, printf oder return.6. #include stdio.h sollte zunchst immer am Anfang (vor main()) angegeben wer-den. Ebenso sollte vor der abschlieenden 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 nchsten Zeile gesprungen wird. Das Steuerzeichen \n,das immer in Anfhrungszeichen 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 nch-sten printf in der gleichen Zeile (an der alten Bildschirmposition) mit der Ausgabe fortgefah-ren, wie es das C-Programm zweit.c verdeutlicht:#include 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 ?ENDENDEEine Angabe wie:printf("Guten Tag");ergibt einen Fehler, da ein Zeilenwechsel innerhalb der in . . . eingebetteten Zeichenkette nichterlaubt ist.41.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 zustzlich nochwie C++ auch die Zeichenfolge // zum Kommentieren eingefhrt: Alle Zeichen ab // bis zumZeilenende werden dabei als Kommentar interpretiert:printf("Frau Holle, "); /* Normaler C-Kommentar, der sich bermehrere Zeilen erstrecken kann undauch weiterhin verwendet werden kann.*/printf("wie gehts?\n"); // Ab hier bis zum Zeilenende Kommentar (neu in C99)// Bei mehrzeiligen Kommentare ist erneut // anzugeben1.3 Gute Lesbarkeit von ProgrammenEinrcken von untergeordneten ProgrammteilenWie einzurcken ist, wurde bereits in den vorherigen Programmbeispielen fr die Anweisun-gen innerhalb der geschweiften Klammern von main() gezeigt. Es gibt keine allgemeingltigeRegel, wie viele Leerzeichen einzurcken sind; blich ist jedoch das Einrcken um drei, vieroder auch acht Leerzeichen.Sinnvolle KommentareDa Kommentare in einem C-Programm der Mensch/Mensch-Kommunikation dienen, sind sieein wichtiges Hilfsmittel, um die Lesbarkeit eines Programms zu erhhen und somit das Ver-stndnis zu erleichtern. Kommentare sollten zustzliche Information enthaltenDie Befehlsbedeutung ist nicht zu kommentieren. Kommentare wiei=i+1; /* i wird um 1 erhoeht */sind nicht nur berflssig, sondern sogar schdlich, da sie den Programmtext unntigaufblhen, was eher zur Unbersichtlichkeit und damit zu einer schlechteren Lesbarkeitfhrt. Nicht zuviel Programmtext auf einmal kommentierenDrei Seiten zusammenhngender Kommentar, um die nchsten drei Seiten Programm-text zu beschreiben, dient nicht der besseren Verstndlichkeit eines Programms, sondernlsst sich auch nicht leicht ndern, wenn sich der betreffende Programmteil grundlegendndert. Ein falscher Kommentar ist schlimmer als gar kein KommentarKommentare mssen bei jeder nderung des Programms aktualisiert werden. Einige gute treffende Stze sind mehr wert als RomaneBei Kommentaren geht es meist darum, den Nagel auf den Kopf zu treffen. Die Profes-sionalitt und Gte eines Programmierers lsst sich unter anderem an seinem Stil derKommentierung erkennen.51 Einfhrendes Beispiel1.4 Vermeiden von geschachtelten KommentarenObwohl 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 verstt man gegen die in der SW-Entwicklung wichtige Forde-rung der Portabilitt, da ein solches Programm eventuell auf anderen C89- bzw. C99-Compilernnicht mehr ablauffhig ist.Es gilt nmlich, dass ab dem ersten Vorkommen von /* bis zum ersten Auftreten von */ alles alsKommentar interpretiert wird. Fr obige Angabe wrde dies bedeuten, dass der fett gedruckteTeil vom Compiler als Kommentar interpretiert wird, so dass er dann mit dem Rest nichts mehranfangen kann.6Kapitel 2Elementare Datentypen2.1 Die Grunddatentypen in CIn 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-DatentypenOrdnet 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 fr die Typen intund double Versionen mit unterschiedlichen Genauigkeiten gibt:72 Elementare Datentypenchar Daten dieses Typs belegen ein Byte Speicherplatz und reprsentieren Zeichen. In ei-nem Byte (8 Bit) kann genau ein Zeichen des ASCII-Zeichenvorrats gespeichert werden.Vor char darf dabei eines der beiden folgenden Schlsselwrter angegeben werden:signed 1. Bit ist Vorzeichenbit.unsigned 1. Bit ist kein Vorzeichenbit.int Dieser Datentyp reprsentiert ganze Zahlen; dafr sind im allgemeinen 4 Bytes vorge-sehen, also viermal soviel Speicherplatz wie fr char. Mit diesen 4 Bytes (32 Bit) knnenZahlen im Bereich -2147483648 . . .+2147483647 dargestellt werden.Vor int darf dabei eines der folgenden Schlsselwrter angegeben werden:short Durch Voranstellen dieses Schlsselworts (short int) werden typischerweise 2Bytes (16 Bits) reserviert, was dem Zahlenbereich -32768 ...+32767 entspricht.long Durch Voranstellen dieses Schlsselworts (long int) wird auf 32-Bit Maschinenblicherweise 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 fr 32-BitComputer die Mglichkeit, mit einem greren Wertebereich zu arbeiten, als ihn dieProzessorregister bieten.unsigned Das Voranstellen dieses Schlsselworts (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 knnen.Die obigen Schlsselwrter knnen 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 intund unsigned entspricht unsigned int.float Dieser Datentyp ist fr 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 tatschlich belegt,kann mit dem folgenden Programm ermittelt werden (Beispiel fr long double):#include int main(void){printf( "Der Datentyp belegt %d Bytes \n", sizeof(long double) );return 0;}82.2 Wertebereiche fr die einzelnen Datentypen2.2 Wertebereiche fr die einzelnen DatentypenTabelle 2.1 zeigt fr 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 fr 64-Bit Architekturen enthlt, verdeutlicht, dass sich auf 64-Bit Computernlediglich der Wertebereich des Datentyps long ndert.Tabelle 2.1: Typische Wertebereiche fr die einzelnen Datentypen auf 32-Bit-ArchitekturenDatentyp-Bezeichnung Bitanzahl Wertebereichchar, signed char 8 -128 .. 127unsigned char 8 0 .. 255short, signed short,short int, signed short int 16 -32 768 .. 32 767unsigned short, unsigned short int 16 0 .. 65 535int, signed, signed int 32 -2 147 483 648 .. 2 147 483 647unsigned, unsigned int 32 0 .. 4 294 967 295long, signed longlong int, signed long int 32 -2 147 483 648 .. 2 147 483 647unsigned long, unsigned long int 32 0 .. 4 294 967 295long 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 807unsigned long long (C99)unsigned long long int (C99) 64 0 .. 18446744073709551615float 32 1.2 1038..3.41038double 64 2.2 10308..1.810308long double 96 3.4 104932..1.1104932Tabelle 2.2: Typische Wertebereiche fr die einzelnen Datentypen auf 64-Bit-ArchitekturenDatentyp-Bezeichnung Bitanzahl Wertebereichint, signed, signed int 32 -2 147 483 648 .. 2 147 483 647long, signed long 64 -9 223 372 036 854 775 808 ..long int, signed long int .. 9 223 372 036 854 775 807unsigned long, unsigned long int 64 0 .. 18 446 744 073 709 551 615unsigned long long, (C99)unsigned long long int (C99) 64 0 .. 18446744073709551615long 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 8079Kapitel 3KonstantenDie 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-KonstantenDer Datentyp char wird meist durch 1 Byte realisiert. char-Konstanten mssen mit einfachemHochkomma (z. B.: a) geklammert werden. Im Byte des char-Datentyps wird dann der zuge-hrige ASCII-Wert gespeichert, der dieses Zeichen reprsentiert, wie z. B.:char-Konstante Dezimaler ASCII-Wert Dualdarstellung im char-Bytea 97 01100001W 87 01010111* 42 001010108 56 00111000Bei 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 mglich, 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. Whrend also z. B. fr 8 derASCII-Wert 56, der dieses Zeichen reprsentiert als Dualzahl (00111000) abgelegt wird, wirddagegen fr die Dezimalzahl 8 die dieser Zahl entsprechende Dualzahl (00001000) im char-Da-tentyp abgelegt.3.2 Ganzzahlige KonstantenEs 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 mssen Hexadezimal-Konstanten, die immer mit 0x oder 0X beginnen mssen.11Kapitel 4Variablen4.1 Variablen und die C-Regeln fr VariablennamenDie Eigenschaft von Variablen ist, dass sich ihre Werte stndig ndern knnen. Es handelt sichbei Variablen um eine Art Beschriftung eines Speicherbereichs. Whrend 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. Natrlich 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 nchsten 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 drfen 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 hhere Programmiersprache verfgt auch C ber einen festen Wortschatz vonBefehlen (siehe unten). Solche Befehle drfen natrlich nicht als Variablennamen verwen-det werden, weil sonst der C-Compiler nicht entscheiden knnte, 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 erwhnt, drfen C-Schlsselwrter nicht als Variablennamen verwendet werden. Infolgender Tabelle sind alle C-Schlsselwrter angegeben, wobei die in C99 neu hinzugekom-menen Schlsselwrter fett gedruckt sind. Whrend die Verwendung von Schlsselwrtern alsalleinstehende Variablennamen verboten ist, drfen sie jedoch in Variablennamen eingebettetsein; z. B. wre 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 _Imaginary13Kapitel 5Ausdrcke und Operatoren5.1 Der einfache Zuweisungsoperator5.1.1 Allgemeines zum einfachen ZuweisungsoperatorDer Zuweisungsoperator hinterlegt einen Wert in einer Variablen. Durch die Anweisungzahl_var = 5;wird z. B. in der Variablen zahl_var der Wert 5 abgelegt. Soll nun der Wert -17 in zahl_vargespeichert werden, so ist lediglichzahl_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 ursprngliche Inhalt von zahl_1 wurde mit dem Inhalt der Variablen zahl_2 berschrie-ben.175 Ausdrcke und OperatorenBeispiel:Das C-Programm tausch.c vertauscht die Werte von zwei int-Variablen:#include int main(void){int variab_1, variab_2, hilf; /* Deklaration von drei ganzzahligen Variablen mit den Namenvariab_1, variab_2, hilf */variab_1 = 105; /* _______________variab_1 I 105 II_____________I */variab_2 = -14; /* _______________variab_1 I 105 II_____________Ivariab_2 I -14 II_____________I *//***************************************** Vertauschen ***********************************//* Zwischenspeichern der Werte von variab_1 in der "Hilfsvariable" hilf */hilf = variab_1; /* _______________variab_1 I 105 II_____________Ivariab_2 I -14 II_____________Ihilf I 105 II_____________I *//* Speichern des Wertes von variab_2 in variab_1, (d. h. der urspruenglicheWert von variab_1 wird ueberschrieben).Der urpruengliche Wert von variab_1 wurde zuvor in hilf gesichert */variab_1 = variab_2; /* _______________variab_1 I -14 II_____________Ivariab_2 I -14 II_____________Ihilf I 105 II_____________I *//* Speichern des in hilf gespeicherten Wertes in variab_2. Nach dieser Zuweisung sinddie urspruenglichen Werte von variab_1 und variab_2 vertauscht. */variab_2 = hilf; /* _______________variab_1 I -14 II_____________Ivariab_2 I 105 II_____________Ihilf I 105 II_____________I */return 0;}185 Ausdrcke und Operatoren5.5.5 Bit-Operatoren nur fr ganzzahlige Datentypen erlaubtDie Bit-Operatoren ~, &, | und ^ drfen nicht auf Operanden angewendet werden, die vomDatentyp float oder double sind. Z. B. wrde fr das folgende C-Programm bitgleit.c einFehler gemeldet:#include 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 FallgrubenLogische Operatoren und Bit-Operatoren unterscheiden sichDas 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;Vorzeichen=16384214=8192213=4096212=2048211=1024210=51229=25628=12827=6426=3225=1624=823=422=221=120z1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 = 2z2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 = 5z1 & z2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 = 0z = z1 && z2;Vorzeichen=16384214=8192213=4096212=2048211=1024210=51229=25628=12827=6426=3225=1624=823=422=221=120z1 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)345.5 Bit-OperatorenHat 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; Vorzeichen=16384214=8192213=4096212=2048211=1024210=51229=25628=12827=6426=3225=1624=823=422=221=120z1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 = 2z2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 = 5z1 | z2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 = 7z = z1 || z2; Vorzeichen=16384214=8192213=4096212=2048211=1024210=51229=25628=12827=6426=3225=1624=823=422=221=120z1 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 Prioritt der dyadischen Bit-OperatorenDie Bitoperatoren lassen sich wie in Tabelle 5.2 gezeigt - in die Priorittstabelle der bisherkennengelernten Operatoren einordnen.In Tabelle 5.2 ist erkennbar, dass die Prioritt der Bitoperatoren sehr niedrig ist. Dies fhrt hu-fig zu uerst rgerlichen und schwer auffindbaren Fehlern in der praktischen Programmie-rung.( ) ! (Tilde) + (Vorz.) (Vorz.) hhere / % Prioritt+ < >= == ! = & | && niedrigere|| Prioritt= Tabelle 5.2: Prioritt der Bit-Operatoren35Kapitel 6Symbolische KonstantenDie Programmiersprache C sieht die Mglichkeit 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 knnen auf zwei verschiedene Arten sym-bolische Namen an Konstanten vergeben werden: Definition mit #define oder Definition unter Verwendung des Schlsselworts const.6.1 Konstanten-Definition mit #define6.1.1 Die Direktive #defineNehmen wir einmal an, dass Sie ein Programm erstellen sollen, in dem die Zahl immer mit9 Stellen Genauigkeit nach dem Komma verwendet werden muss. Sie mssten dann bei je-dem Vorkommen von die Zahlenschlange 3.141592654 eintippen. Mit der Verwendung von#define ist es nun jedoch mglich, am Anfang des Programms einem Zahlenwert einen Namenzuzuordnen, wie z. B.#define PI 3.141592654Anstelle des Zahlenwerts 3.141592654 knnen Sie dann bei den entsprechenden Anweisungenim gesamten Programm den symbolischen Namen (PI) verwenden. Dies kann eine erheblicheArbeitsersparnis fr das restliche Programm bedeuten, da nicht ein stndiges 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.47Kapitel 7Ein- und AusgabeBevor wir die beiden Bibliotheks-Funktionen printf() und scanf() in diesem Kapitel aus-fhrlich behandeln, werden wir uns zunchst mit den sogenannten Headerdateien beschfti-gen.7.1 Headerdateien und #include7.1.1 Bibliotheken und HeaderdateienZu jedem C-Compiler wird eine Bibliothek mitgeliefert, in der Funktionen hinterlegt sind. Wieder Aufbau einer Funktion ist, knnen 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 gehrige Funktion sucht und zu Ihrem Programm dazubindet. Sie kn-nen also z. B. die Funktion printf() benutzen und Bildschirmausgaben veranlassen, obwohlSie den dazugehrigen Programmteil (Funktion) nicht selbst programmiert haben; dies hat derCompiler-Hersteller bereits fr Sie getan.Seit C89 sind die Funktionsnamen und deren Funktionalitt, 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 fr den Linker bind-baren Objekt-Code dieser Funktionen enthlt.Damit aber auch bereits dem C-Compiler Informationen zu solchen Standardfunktionen be-kannt sind, existieren so genannte Headerdateien, in denen die Funktionskpfe der entspre-51Kapitel 8Datentypumwandlungen8.1 Implizite Datentypumwandlungen8.1.1 Der sizeof-OperatorBevor wir uns genauer mit den impliziten Datentypumwandlungen beschftigen, 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 mglich: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 bentigt werden.Um festzustellen, wie viele Bytes Ihr Compiler fr die Grunddatentypen verwendet, kann z. B.das folgende Programm typgroes.c dienen.#include int main(void) {printf("%20s: %d Bytes\n", "char", sizeof(char));printf("%20s: %d Bytes\n", "signed char", sizeof(signed char));printf("%20s: %d Bytes\n", "unsigned char", sizeof(unsigned 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(unsigned short));printf("------------------------------------------\n");printf("%20s: %d Bytes\n", "int", sizeof(int));printf("%20s: %d Bytes\n", "signed int", sizeof(signed int));printf("%20s: %d Bytes\n", "unsigned int", sizeof(unsigned int));printf("------------------------------------------\n");printf("%20s: %d Bytes\n", "long", sizeof(long));printf("%20s: %d Bytes\n", "signed long", sizeof(signed long));printf("%20s: %d Bytes\n", "unsigned long", sizeof(unsigned long));printf("------------------------------------------\n");91Kapitel 9Die Headerdateien Kapitel 10Anweisungen und BlckeFgt man zu einem Ausdruck wie schieb >>= 4 oder scanf("%d", &zahl) oder zaehl = 7oder nieder-- ein Semikolon hinzu, so erhlt 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 knnen, mssen 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, whrend z. B. in Pascal ein Semikolon einTrennzeichen zwischen den einzelnen Anweisungen ist.2. Wie wir spter sehen werden, knnen in einem Block auch Variablen vereinbart werden.103Kapitel 11Die if-Anweisung11.1 Die zweiseitige if-AnweisungDie if-Anweisung wird fr Programmverzweigungen bentigt: if (deutsch Wenn) und else(deutsch Sonst). Die Syntax fr die vollstndige (zweiseitige) if-Anweisung ist:if (ausdruck)anweisung1elseanweisung2anweisung1 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 erfllt bzw. der Wert dieses Ausdrucks von 0 verschieden, dann wird anweisung1, sonstanweisung2 ausgefhrt, 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) ?janeinanweisung anweisung1 2Abbildung 11.1: Programmablaufplan zur if-Anweisung105Kapitel 12Die bedingte Bewertung ?:Wenn wir das Maximum der beiden Variablen zahl1 und zahl2 an die Variable max zuweisenwollen, so wrden wir mit unseren bisherigen Kenntnissen folgenden Programmteil erstellen:if (zahl1 > zahl2)max=zahl1;elsemax=zahl2;Ist der Wert von zahl1 grer als der Wert von zahl2, so wird der Wert von zahl1der Variablenmax, andernfalls der Wert von zahl2 der Variablen max zugewiesen.Mit der bedingten Bewertung htten wir diesen Programmteil auch wie folgt angeben knnen:max = (zahl1 > zahl2) ? zahl1 : zahl2;Zunchst 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 : ausdr3Zunchst 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 Ausdrcke ausdr2 oder ausdr3 bewertet;dieser Wert ist dann das Ergebnis der gesamten bedingten Bewertung.Da der Operator ? : eine sehr niedrige Prioritt besitzt, sind runde Klammern bei ausdr1,ausdr2 und ausdr3 meist nicht notwendig, erhhen aber die Lesbarkeit.Das folgende C-Programm mannweib.c zeigt eine Anwendung des bedingten Operators:#include 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;}119Kapitel 13Die switch-Anweisung13.1 Die switch-AnweisungMit der switch-Anweisung kann unter mehreren Alternativen, nicht nur unter zwei wie beider if-Anweisung, ausgewhlt werden. Die Syntax fr 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-Ausdrcken, die int- oder char- Werte (Konstanten) liefern mssen, 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 ausgefhrt. 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-Anweisung121Kapitel 14Der Komma-Operator14.1 Der Komma-OperatorDer Komma-Operator fasst mehrere Ausdrcke syntaktisch zu einem einzigen Ausdruck zu-sammen.Sind mehrere Ausdrcke 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 nchsten Kapitel behandeln werden,wird dieser Komma-Operator hufig verwendet. Der Komma-Operator erlaubt nmlich dieUnterbringung von mehreren Zuweisungen an einer Stelle, wo sonst nur eine erlaubt wre.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 htte man schreiben mssen:if (...) {zaehl++;printf ("\n Zaehler erhoeht\n");}Aus Grnden der besseren Lesbarkeit ist aber immer die zweite Vorgehensweise vorzuziehen.127Kapitel 15Die for-Anweisung15.1 Die for-AnweisungSyntaktisch sieht die for-Schleife wie folgt aus:for (ausdruck1; ausdruck2; ausdruck3)anweisungDie anweisung kann ein Block von Anweisungen sein, der mit {...} zu klammern ist.- ausdruck1 initialisiert die Schleifenvariable(n).- ausdruck2 legt das Abbruchkriterium fr die Schleife fest, wenn ausdruck2 nicht erfllt ist.- ausdruck3 reinitialisiert die Schleifenvariable(n).Die Komponenten (ausdrcke) knnen einzeln oder auch insgesamt fehlen, jedoch mssen dieSemikolons in der Klammer an den richtigen Stellen verbleiben.nchste Anweisung(auerh. der for-Schleife)ausdruck1ausdruck2?ausdruck3anweisungwahr(verschieden von 0)falsch (gleich 0)Abbildung 15.1: Programmablaufplan zur for-Schleife12915.2 Die for-Schleife und der Komma-OperatorJetzt wollen wir nochmals die geometrische Reihe berechnen, wobei wir alle erforderlichenSchleifenanweisungen im for-Schleifenkopf unterbringen, so dass berhaupt keine Schleifenan-weisung mehr brigbleibt.#include 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 Kapitel 16Die while-Anweisung16.1 Die while-Anweisungwhile (ausdruck)anweisunganweisung kann wieder ein mit {..} zu klammernder Block von Anweisungen sein.Die Funktionsweise der while-Schleife lsst sich am besten anhand der Abbildung 16.1 zeigen.nchste Anweisung (auerh. der while-Schleife)ausdruck?anweisungwahr(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-fhrt. Erst, wenn die Auswertung von ausdruck 0(FALSE) liefert, wird die Schleife beendet und mitder nchsten nicht zur Schleife gehrigen Anwei-sung fortgefahren.Ist das Ergebnis von ausdruck bereits bei der erstenBerechnung gleich 0 (FALSE), so wird die Schleifegar nicht durchlaufen, sondern sofort mit dernchsten nicht zur Schleife gehrigen Anweisungfortgefahren.nchste Anweisung (auerhalb der Schleife)Schleifen-Anweisungenwhile (ausdruck)Abbildung 16.1: Programmablaufplan und Struktogramm zur while-SchleifeDa die Abfrage der Schleifen-Bedingung wie bei der for-Schleife am Anfang durchgefhrtwird, wird die while-Schleife genauso wie die for-Schleife im Struktogramm dargestellt.161Kapitel 17Die do. . . while-Anweisung17.1 Die do. . . while-Anweisungdoanweisungwhile (ausdruck);Die anweisung kann selbstverstndlich wieder ein Block von Anweisungen sein, der dannmit {..} zu klammern ist.Die Funktionsweise der do...while-Schleife lsst sich am besten anhand der Abbildung 17.1zeigen.nchste Anweisung(auerh. der do...while-Schleife)ausdruck?anweisungwahr(verschieden von 0)falsch (gleich 0)Nach jedem Schleifendurchlauf wird ausdruckberechnet. Ist das Ergebnis verschieden von 0(TRUE), so wird die Schleifen-anweisung nochmalsausgefhrt. Erst, wenn die Auwertung von aus-druck 0 (FALSE) liefert, wird die Schleife beendetund mit der nchsten nicht zur Schleife gehrigenAnweisung fortgefahren.nchste Anweisung (auerhalb der Schleife)anweisung (in Schleife)while (ausdruck)Abbildung 17.1: Programmablaufplan und Struktogramm zur do...while-SchleifeDa die Abfrage der Bedingung bei der do...while-Schleife am Ende stattfindet, wird dieseSchleife im Struktogramm wie rechts in Abbildung 17.1 gezeigt dargestellt.175Kapitel 18Die break-Anweisung18.1 Die break-AnweisungNicht 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 */179Kapitel 19Die continue-Anweisung19.1 Die continue-AnweisungDie 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 unverzglich den nchsten Schleifendurchlauf ein und hat auch im Gegensatz zu breakkeine 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 nchstes die Reinitialisierung (ausdr3) durchgefhrt 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 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 Kapitel 20Marken und die goto-Anweisung20.1 Marken und die goto-AnweisungDie 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; anschlieend folgt ein Doppel-punkt:marke: anweisung;marken knnen vor jeder Anweisung stehen, unabhngig 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 Programmiertechniken20.2.1 goto nur im uersten NotfallMit Einfhrung der Strukturierten Programmierung in den 60er Jahren wurde die Springereimit goto sehr verpnt. 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. Spter wurde dieser Stil vor allen Dingen in BASIC bernommen. Man stellte damals sehrschnell fest, dass Programme, die mit Vorwrts- und Rckwrtssprngen gespickt sind, nichtnur schwer verstndlich, sondern auch kaum wartbar waren. Dies fhrte zu einer erheblichenVerteuerung der Software. Ein Ausweg aus diesem Dilemma war die Strukturierte Programmie-1muss mit Buchstabe oder Unterstrich beginnen und des weiteren drfen nur Buchstaben, Ziffern oder Unterstrichefolgen197Kapitel 21Grafikprogrammierung unter LinuxIm 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 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 2. Angabe von main() mit ParameternWenn Sie in Ihrem Programm Routinen aus diesem Kapitel aufrufen, mssen Sie stattint 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, mssenSie 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, mssen Sie z. B. Folgendes aufrufen:user@linux:~ > lcc -o polygon polygon.clcc bietet die gleichen Optionen an wie das Kommando gcc bzw. cc.Geben Sie danach zum Testen die folgende Kommandozeile ein:user@linux:~ > ./polygon19921 Grafikprogrammierung unter Linux21.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 gelscht wird, wirdmeist vor closegraph() noch ein getch() angegeben, so dass erst auf einen Tastendruckdes Benutzers hin der Grafikmodus verlassen wird.Typisch fr die Grafikprogrammierung ist deshalb z. B. folgender Programmausschnitt:#include .......int main( int argc, char *argv[] ){initgraph( 640, 480 );........Grafik-Programmteil........getch(); /* auf einen Tastendruck warten */closegraph();}21.3 Eingaben im GrafikmodusWhrend man im Grafikmodus arbeitet, kann man nicht mehr die Standardroutinen fr die Ein-und Ausgabe (printf(), scanf(), getchar() und putchar()) verwenden, sondern mussdie eigens dafr 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 zurck.kbhit()prft, ob eine Taste gedrckt wurde. Falls eine Taste gedrckt wurde, liefert kbhit()einen int-Wert ungleich 0 (TRUE), falls nicht, liefert diese Funktion 0 (FALSE) zurck.Das dabei eingegebene Zeichen kann mit der nachfolgend vorgestellten Routine getch()nachtrglich 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 Routine20021 Grafikprogrammierung unter LinuxAbbildung 21.3: Wahrscheinlichkeit von 0.62 (links) und 0.7 (rechts) fr das Eindringen von lBeispiel:Das folgende Programm pixel.c whlt zufllig eine Hintergrundfarbe und malt dann 1 000kleine Vierecke an zufllige Bildschirmpositionen mit zufllig gewhlten Farben. Ein Vierecksind dabei 9 Pixel:xxxxoxxxxwobei nur der Mittelpunkt (o) zufllig gewhlt ist. Danach wird der Inhalt dieses Fensters ge-lscht, mit einer zuflligen Hintergrundfarbe gefllt und wieder mit neuen zuflligen kleinenRechtecken bemalt. Mit einem Tastendruck kann dieses Programm beendet werden.#include #include #include #include #define PIXEL_ZAHL 1000int 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 ; i21.8 Bilder laden, Bildteile speichern und einblendenAbbildung 21.10: Anzeige des Programms sandmann.cAbbildung 21.10 zeigt das von Programm sandmann.c angezeigte Fenster zu einem bestimm-ten Zeitpunkt. Dieses Programm knnte z. B. gestartet werden, wenn man seinen Bildschirm-platz lngere Zeit verlsst, und man Information am Bildschirm darber ausgeben lassen mch-te, wo man sich gerade befindet und wann man wieder zurckkommt. Hierzu msste man je-doch dann die auszugebende Meldung einlesen lassen. Eine entsprechende Anpassung diesesProgramms an die speziellen eigenen Bedrfnisse sollte aber nicht allzu schwierig sein.Beispiel:Das folgende Programm karten.c blendet bei jedem Tastendruck immer sieben zufllig aus-gewhlte 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 Tastendruck219Kapitel 22FunktionenIn der Programmierpraxis sind hufig 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 FunktionenWir haben bisher schon ohne es ausfhrlich zu erwhnen 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() ausgefhrt wird.22.1.1 Allgemeines Beispiel zu FunktionenAm besten knnen wir das Prinzip von Funktionen an einem allgemeinen Beispiel nachvoll-ziehen. In diesem Beispiel wird nicht die Programmiersprache C, sondern zum besseren Ver-stndnis die deutsche Sprache verwendet. Es soll bei der Personalabteilung einer Firma im-mer ein einheitliches Papier fr die Spesenabrechnung abgegeben werden. Wir nehmen dazuan, dass in der Standardbibliothek eine Funktion (Schablone) mit Namen spesen() definiertsei, was natrlich nicht fr 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 stadtzu(m) tagzeit:vor als Vorspeisehaupt als Hauptspeise undnach als Nachspeisegegessen.Der Preis fuer dieses Essen betrug preis waehrung."}23122.3 Die Parameter von FunktionenIn der Definition von tausch() werden mit der Deklarationvoid tausch(int *a, int *b)zwei Speicherpltze fr int-Zeiger und ein Speicherplatz fr die lokale Variable hilf reserviert.Mit dem Aufruftausch(&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: & = Adreoperator. Bei dieser bergabe werden alsoin die beiden reservierten Speicherpltze 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 Rckkehr 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 Adressen25922.7 Zeiger auf Funktionenundfloat *welch_funktion(...);/* welch_funktion = Funktion, die Zeiger auf float-Wert liefert */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 Anweisungreturn rad*(*welch_funktion)(rad);der Anweisungreturn rad * zyl_vol(rad);wie dies auch in Abbildung 22.20 gezeigt ist.welch_funktionzyl_volkug_vol1. Befehl der Funktion zyl_vol2. Befehl der Funktion zyl_vol1. Befehl der Funktion kug_vol2. Befehl der Funktion kug_volZeigerebeneVariablenebeneWerteebene*welch_funktionAbbildung 22.20: *welch_funktion entspricht zyl_vol()Um das Zeigerprinzip bei Funktionen besser verstehen zu knnen, wollen wir ein weiteresDeklarations-Beispiel angeben:float *(*welch_funktion)(...);Hier wre welch_funktion ein Zeiger auf eine Funktion, die einen Zeiger auf einen float-Wertliefert.22.7.2 Typische AnwendungenAuswahl von Funktionen zur ProgrammlaufzeitEin typischer Anwendungsfall fr Zeiger auf Funktionen liegt vor, wenn erst zum Zeitpunktder Programmausfhrung bekannt ist, welche Funktion auszufhren ist. Nehmen wir z. B. einSortierprogramm, bei dem erst whrend der Programmausfhrung 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 fr den Vergleich der einzelnen Daten zustndig ist. Ist dann whrend der283Kapitel 23Speicherklassen und ModultechnikEs wurde schon einmal erwhnt, dass sich C-Programme aus mehreren Dateien zusammenset-zen knnen. Jede Programmdatei auch Modul genannt kann einzeln kompiliert werden, aberist fr sich allein nicht lauffhig.Diese getrennt kompilierten Module knnen anschlieend mit Hilfe des Linkers zu einem ein-zigen Programm zusammengebunden werden.23.1 Gltigkeitsbereich, Lebensdauer, Speicherort23.1.1 GltigkeitsbereichUnter dem Gltigkeitsbereich eines Objekts (Funktionsname, Variablenname) versteht man dieBereiche in den einzelnen Programmeinheiten, in denen es angesprochen werden kann.Beim Gltigkeitsbereich wird zwischen folgenden Arten unterschieden: modulglobal programmglobal lokal (in einem Block von { . . . })Modulglobale GltigkeitEin modulglobales Objekt ist innerhalb der gesamten Programmdatei (Modul) ansprechbar, inder es deklariert ist, aber nicht in einer anderen Programmdatei (Modul). Jede Variable, dieauerhalb einer Funktion deklariert ist, werden wir als modulglobal bezeichnen.Da modulglobale Variablen auerhalb von Funktionen vereinbart sind und somit vielen Funk-tionen zur Verfgung 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.287Kapitel 24Prprozessor-DirektivenDer Prprozessor verarbeitet den Quelltext einer Programmdatei, wobei alle Prprozessor-Kom-mandos (Prprozessor-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 Prprozessor-Direktive sind nur Leerzeichen, \t und Kom-mentare zugelassen.Beispiel:So sind z. B. die folgenden drei Angaben erlaubte Prprozessor-Direktiven in C89 und C99:/* Kommentar */ #if TEST# /* Kommentar */ if TEST# if /* Kommen-tar */ TESTblicherweise ruft der Compiler automatisch den Prprozessor auf, bevor er mit der berset-zung beginnt.C89 schreibt vor, dass der Prprozessor wie ein eigener Schritt vor dem eigentlichen Compiler-lauf zu verstehen ist1.Der Prprozessor 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 heit nicht, dass der Prprozessor-Lauf als eigener Durchgang (wie es in heutigen Compilern oft der Fall ist)realisiert sein muss, sondern sich nur so verhalten muss33124.1 Bedingte KompilierungBeispiele:#if bed1progteil1#elif bed2progteil2#elif bed3progteil3#elseprogteil4#endifNNNbed1erfllt?bed2erfllt?bed3erfllt?JJJKompilierung von progteil1Kompilierung von progteil2Kompilierung von progteil3Kompilierung von progteil4Abbildung 24.1: Programmablaufplan zu einer #if-KaskadeSchachteln von#if-Konstruktionenist erlaubt, wie z. B.:#if beda# if beda1progteila1# elseprogteila2# endif#else# if bedb1progteilb1# elseprogteilb2# endif#endifNNbedaerfllt?bedb1erfllt?JKompilierung von progteilb1Kompilierung von progteilb2Nbeda1erfllt?JKompilierung von progteila2Kompilierung von progteila1JAbbildung 24.2: Programmablaufplan zu einer geschachtelten #if-Konstruktion333Kapitel 25Zeiger und ArraysIn der Programmierpraxis sind hufig Probleme anzutreffen, bei denen man nicht mit einfachenVariablen auskommt, sondern einen ganzen Block von Variablen des gleichen Typs bentigt. EinBeispiel dafr wren die Monatumstze eines Unternehmens fr ein Jahr. In diesem Fall ist essehr ntzlich, 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 ArraysEin 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 ArraysEin eindimensionales Array mit 26 Elementen vom Typ char knnte wie folgt vereinbart wer-den:char buchst[26];Mit dieser Angabe wird ein Array buchstmit 26 Elementen vom Typ char definiert. Die Anzahlder Elemente wird bei der Definition in eckigen Klammern angegeben. Unterchar buchst[26];knnen 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 Definitionchar 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) fr ein Array definiert, so erfolgt die Adressierung ber sogenannte Indizes von Element 0 bis Element n1.35725 Zeiger und ArraysBeachten Sie, dass jedes Array mit der Elementnummer 0 und nicht mit 1 beginnt!Mit den Anweisungenbuchst[3] =a;buchst[0] =!;buchst[24] =H;ergbe 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'undefiniertundefiniertundefiniertundefiniertundefiniertAbbildung 25.1: char-Array buchst mit 26 SpeicherpltzenBeispiele: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 zunchst in einem Array buchstalle 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 int main(void) {char buchst[26];int i, zahl;for (i = 0; i < 26; i++) /* Array mit Kleinbuchstaben belegen */buchst[i] = a + i;358Kapitel 26Argumente auf der Kommandozeile26.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 ermglichen 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 int main(int argc, char *argv[]) {int i;for (i=0; i cc -o argtest argtest.c453Kapitel 27Dynamische Speicher-Reservierung und-Freigabe27.1 Nachteile von statischen ArraysDas folgende Programm namsort1.c, das bis zu 100 Namen einliest und diese dann sortiertausgibt, zeigt die Nachteile von statischen Arrays in gewissen Anwendungen.#include #include #define MAX_NAMEN 100#define MAX_LAENGE 30int 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;}463Kapitel 28StrukturenUnter einer Struktur versteht man die Zusammenfassung von einer oder mehreren Variablen,die anders als bei Arrays untereinander auch unterschiedliche Datentypen besitzen drfen,zu einer Einheit.28.1 Deklaration und Definition von Strukturen28.1.1 Deklaration von StrukturenEin typisches Beispiel fr eine einfache Struktur wre die Zusammenfassung der Daten einesStudenten aus einer Studentenkartei zu einer einzigen Einheit, die wir stu_daten nennen. Einesolche Zusammenfassung wird in C z. B. folgendermaen ausgedrckt: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]; /* Prfungsnoten */};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 Schlsselwort struct. Nach Schlssel-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 abzuschlieen.49128 StrukturenFr unseren Fall ist die 1. Bedingung und somit auch die Gesamtbedingung erfllt, so dassfolgende Anweisung ausgefhrt 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.MalloniIta01/29/37.19NULL-ZeigerwurzelMuellerSui01/12/48.17NULL-ZeigerNULL-Zeigerknot_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 MalloniMitreturn knot_zeig;wird immer die Adresse des gerade behandelten Knotens an die bergeordnete Ebene zurck-gegeben. Von der ersten rekursiven Ebene wird hier z. B. die Adresse des Mueller-Knotenszurckgegeben. Diese Adresse wird wegenknot_zeig->links = einordnen(knot_zeig->links);im Malloni-Knoten unter der Komponente knot_zeig->links (hier wurzel->links) gespei-chert. Nach der Rckkehr nach main() wird dort unter Zuhilfenahme der Funktion drucke_-baum() folgender Zwischenstand ausgegeben:Zwischenstand nach 2 Laeufer=============================Platz Name Land Zeit1 Mueller Sui 01/12/48.172 Malloni Ita 01/29/37.193. eintreffender Lufer In der while-Schleife von main()werden nun die Daten des nchsteneintreffenden Lufers eingelesen:55228.6 Zeiger und Strukturenname: Hansonstaat: Swezeit: 01/20/10.33Danach wird mit wurzel = einordnen(wurzel); wieder die Funktion einordnen() aufgeru-fen. In dieser Funktion wird nach berprfung der entsprechenden Bedingungen die Anwei-sung knot_zeig->links = einordnen(knot_zeig->links); ausgefhrt. Bei diesem rekursi-ven Aufruf von einordnen() wird nach berprfung der vorgegebenen Bedingungen die An-weisung knot_zeig->rechts = einordnen(knot_zeig->rechts); ausgefhrt, so dass sichdas in Abbildung 28.24 gezeigte Bild ergibt.MalloniIta01/29/37.19NULL-ZeigerwurzelMuellerSui01/12/48.17NULL-Zeigerknot_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; }HansonSwe01/20/10.33NULL-ZeigerNULL-Zeiger(2. rekursive Ebene von einordnen)knot_zeig->rechts = einordnen(knot_zeig->rechts);Abbildung 28.24: Einordnen von Hanson als rechter Unterknoten von MuellerNach der Rckkehr nach main() wird dort unter Zuhilfenahme der Funktion drucke_baum()folgender Zwischenstand ausgegeben:Zwischenstand nach 3 Laeufer=============================Platz Name Land Zeit1 Mueller Sui 01/12/48.172 Hanson Swe 01/20/10.333 Malloni Ita 01/29/37.1955328 Strukturen4. eintreffender Lufer In der while-Schleife von main()werden nun die Daten des nchsteneintreffenden Lufers eingelesen:name: Bichlerstaat: Autzeit: 01/11/59.12Danach 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.MalloniIta01/29/37.19NULL-ZeigerwurzelMuellerSui01/12/48.17knot_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; }HansonSwe01/20/10.33NULL-ZeigerNULL-Zeiger(2. rekursive Ebene von einordnen)BichlerAut01/11/59.12NULL-ZeigerNULL-Zeigerknot_zeig->links = einordnen(knot_zeig->links);Abbildung 28.25: Einordnen von Bichler als linker Unterknoten von MuellerNach der Rckkehr nach main() wird dort unter Zuhilfenahme der Funktion drucke_baum()wieder der aktuelle Zwischenstand ausgegeben:Zwischenstand nach 4 Laeufer=============================Platz Name Land Zeit1 Bichler Aut 01/11/59.122 Mueller Sui 01/12/48.173 Hanson Swe 01/20/10.334 Malloni Ita 01/29/37.19Hier knnen wir die Funktionsweise von drucke_baum() sehr schn erkennen: Es wird immerzuerst der vollstndige linke Unterbaum ausgegeben, bevor ein Knoten selbst ausgegeben wird.554Kapitel 29Eigene Datentypen29.1 Definition eigener Datentypnamen mit typedef29.1.1 Vergabe neuer Namen an existierende Datentypen mit typedefMit dem Schlsselwort typedef knnen an Datentypen neue, vom Benutzer whlbare Namenvergeben werden, wie z. B.:typedef unsigned int UINT;typedef unsigned long ULONG;Mit diesen Angaben wird festgelegt, dass UINT ein Synonym fr unsigned int und ULONG einesfr unsigned long ist. Nach der obigen typedef-Angabe knnte 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 knnte nun glauben, dass das Schlsselwort typedef vllig berflssig ist, da man dengleichen Effekt mit #define htte erreichen knnen, wie z. B.:#define UINT unsigned int#define ULONG unsigned longFr diese einfachen Datentypdefinitionen ist dies zwar mglich, doch reicht bei komplexerenDatentypen der einfache Textersatz von #define nicht aus, wie z. B. bei:#define STRING char *In diesem Fall wrde die folgende Definition:STRING zgr1, zgr2;nicht der erwarteten Definitionchar *zgr1, *zgr2;entsprechen, sondern der folgenden Definition:char *zgr1, zgr2; /* zgr2 ist nicht - wie erwartet - ein Zeiger */569Kapitel 30DateienEine 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, groes 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 grundstzlich 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) fr Dateioperationen zurckgreifen. Diese elementaren Funktionensind natrlich vom Betriebssystem abhngig und gehren nicht zum C-Standard, was bei derPortierung von Programmen von groer Bedeutung ist.Die obere Ebene ist die der so genannten hheren Dateizugriffe (Hhere 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 unabhngig sind.Nachfolgend werden nur die Hheren E/A-Funktionen vorgestellt.30.1 Hhere E/A-FunktionenIn diesem Kapitel werden E/A-Funktionen beschrieben, die sich in der Standard-Bibliothekbefinden und in der Headerdatei definiert sind. Die hheren 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 kmmern 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 fr jedes577Kapitel 31Anhang31.1 Priorittstabelle fr die OperatorenOperator (hchste Prioritt oben; niedrigste unten) Assoziativitt( ) [ ] -> . (Punktoperator) von links her! ~ (Tilde) ++ -- + (Vorz.) - (Vorz.) sizeof & (Adreop.) * (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 her31.2 C-SchlsselwrterIn folgender Tabelle sind alle C-Schlsselwrter angegeben, wobei die in C99 neu hinzugekom-menen Schlsselwrter 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 _Imaginary613Index< 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, 339, 60, 608, 199, 101, 86, 264, 24, 72, 81, 72, 81, 577, 413, 398, 189?:, 119bungblock3.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, 353acos(), 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, 253ArgumenteKommandozeile, 453Optionen, 456argvor.c, 260arithmetische Operatoren, 19arr_swap.c, 438Array, 357Funktionsadressen, 451Initialisierung, 426mehrdimensional, 365Struktur, 507und Zeiger, 374zweidimensional, 365Array-Zeiger, 436arryfeh2.c, 364arrygros.c, 362arrynoname.c, 429arryok.c, 364arrysize.c, 373arrystatic.c, 440artizahl.c, 512asctime(), 189asin(), 86assert(), 339Assoziativitt, 43atan(), 86atan2(), 86atof(), 418atoi(), 417atol(), 418atoll(), 418Ausdruck, 20Ausgabeein Zeichen, 53gepuffert, 53printf(), 67, 615putchar(), 53Auswertung, 20Auswertungszeitpunkt, 43auto, 296autoadr.c, 303autoggt.c, 297autokauf.c, 107B Sprache, 1Balkendreidimansional, 210zweidimensional, 210bar(), 210bar3d(), 210BaumBinr, 546BCPL Sprache, 1Bedingte Bewertung, 119Bedingte Kompilierung, 332Bibliothek, 51, 233bildschi.c, 323bildschi.h, 321Binrbaum, 546Binrmodus, 596621Indexbinatext.c, 597bitand.c, 30bitfeld.c, 566bitfeld2.c, 568bitgleit.c, 34bitor.c, 32bitumdre.c, 336bitxor.c, 33Blcke, 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, 583C++, 1C89, 1C99, 1Callby reference, 258by value, 258calloc(), 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(), 189dataus.c, 584datbytes.c, 600Dateiffnen, 578Binrmodus, 596EOF-Flag, 581Fehler-Flag, 581Lschen, 603Lesen (blockweise), 590Lesen (ein Zeichen), 581, 582Lesen (eine Zeile), 584Lesen (formatiert), 585Positionieren, 599, 601Pufferung, 604Schliessen, 578, 580Schreiben (blockweise), 590Schreiben (ein Zeichen), 581, 582Schreiben (eine Zeile), 584Schreiben (formatiert), 585, 594Stream verknpfen, 601Temporre, 605Textmodus, 596Umbenennen, 603Zuruckschieben (ein Zeichen), 589Datentyp, 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, 614Datentypenund Operatoren, 43Datentypumwandlung, 93, 98, 246casting, 98explizit, 98implizit, 93, 246implizite, 91Datum des Tages, 193datuminfo.c, 194Datumsangaben, 189defined, 332DefinitionFunktionen (Alt-C), 237Funktionen (C89/C99), 234Konstanten, 47, 49Variablen, 14Dekrement-Operator --, 40delay(), 201dezimale Konstanten, 11dezumwa2.c, 379dezumwan.c, 359difftime(), 189DirectoryLschen, 603do. . . while, 175Doppelt verkettete Liste, 541double Datentyp, 8drawpoly(), 210dreichi1.c, 446dreichi2.c, 450dreizeic.c, 54dualbcd.c, 431dualzahl.c, 142DynamischeSpeicherallozierung, 463Strukturarrays, 522dynarr.c, 435E/A-Funktionen, 577E/A-Umlenkung, 586eifrau1.c, 182eifrau2.c, 182eimalei.c, 137einaus.c, 202einauscp.c, 586Einer-Komplement, 28Eingabeein Zeichen, 53gepuffert, 53getchar(), 53scanf(), 77, 617einkompl.c, 29einles.c, 293Einseitigeif-Anweisung, 110einzeich.c, 53Ellipseausgefllt zeichnen, 209, 220zeichnen, 209ellipse(), 209Ellipsen-Prototypen, 263endlos.c, 581Endlose for-Schleife, 143englzah1.c, 442englzah2.c, 443EntwurfBottom-up, 316Modularer, 316Top-Down, 316enum, 573enumdemo.c, 576EOF-Flag, 581errno Variable, 608errodemo.c, 609erst.c, 3exp(), 86Explizite Datentypumwandlung, 98extern, 293Fllmuster, 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, 211Filesiehe Datei, 578FILE Datentyp, 578fillellipse(), 209fillpoly(), 210firmaelt.c, 498, 502firmver2.c, 522firmverw.c, 508float Datentyp, 8floataus.c, 22floatint.c, 97floor(), 86FLT_ROUNDS, 102fmod(), 86Font, 215622Indexfopen(), 578for, 129endlos, 143fordrueb.c, 159Formaler Parameter, 233, 253fprintf(), 585fputc(), 582fputs(), 584Fraktale, 277fread(), 590free(), 481free1.c, 481free2.c, 482free3.c, 483freeimage(), 217FreigabeSpeicher, 463fremdspe.c, 398freopen(), 601freopen.c, 602frexp(), 86fscanf(), 585fseek(), 599fsetpos(), 601ftell(), 599funcbez.c, 271functions, 231funkproj.c, 227Funktion, 231acos(), 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(), 86fopen(), 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(), 223moverel(), 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(), 596623Indexvprintf(), 594vscanf(), 596vsnprintf(), 596vsprintf(), 596vsscanf(), 596Adresse, 451assert(), 339inline, 270va_arg() Makro, 264va_end() Makro, 264va_start() Makro, 264Zeiger auf, 280funkzgr1.c, 284funkzgr2.c, 285fwrite(), 590Ganzzahlige Konstanten, 11, 24GanzzahltypenGrenzwerte, 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, 197Grse von Text, 215Grafikmodusausschalten, 200einschalten, 200GrenzwerteGanzzahltypen, 101groesse.c, 215Grunddatentypen, 7guelt1.c, 300guelt2.c, 301guelt3.c, 302Hhe eines Textes, 215hamming1.c, 156hamming2.c, 156haus.c, 130Headerdatei, 340, 339, 60, 608, 199, 101, 86, 264, 24, 72, 81, 72, 81, 577, 413, 398, 189selbst.h, 63, 65Headerdateien, 51, 233Hebrische Methode, 371hebrae.c, 371heron.c, 164heron2.c, 164heron3.c, 164HexadezimalKonstanten, 11Ziffer, 122, 124hexd.c, 591hexextra.c, 589hexokdua.c, 139hexziff1.c, 122hexziff2.c, 124hintquad.c, 154hochdrei.c, 350if, 105, 110Implizite Datentypumwandlung, 93, 246implizite Datentypumwandlung, 91Information Hidding, 314iniconst.c, 434initgraph(), 200Initialisieren Variable, 46Initialisierung, 19, 426Struktur, 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(), 60jaeger1.c, 172jaeger2.c, 173just.c, 216karten.c, 219kbhit(), 200keinadr.c, 83kleigro1.c, 61kleigro2.c, 61kleigro3.c, 64kleigros.c, 166Komma-Operator, 127, 133Kommandozeile, 453, 456Argumente, 453Optionen, 456Kommentar, 5Geschachtelt, 6KomplementEiner, 28Zweier, 29kompzahl.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, 24Konstanten, 11, 12, 47, 49char, 11Dezimal, 11Ganzzahlig, 11, 24Gleitpunkt, 12Hexadezimal, 11Oktal, 11konto.c, 56konto2.c, 57Koordinateaktuell, 204Maximales x, 204Maximales y, 204Transformation, 226Kreisausgefllt zeichnen, 220zeichnen, 209kreis.c, 48Kreisbogenzeichnen, 210kubikzah.c, 386Kuchenstck, 220kugzyvol.c, 280L_tmpnam Konstante, 606ldexp(), 86Lebensdauer, 291leerpara.c, 253Lesbarkeit, 113Lindenmayer-Systeme, 277line(), 207linerel(), 207lineto(), 207Linieabsolut zeichnen, 207Art, 207Dicke, 207relativ zeichnen, 207zeichnen, 207624Indexlinie.c, 207Linked List, 529, 534, 541Linker, 317ListeAusgeben, 534Doppelt verkettete, 541Einfgen, 534Lschen, 534Linked, 529, 534, 541Operationen, 534Sortierte, 534Verkettete, 529loadimage(), 217localtime(), 190log(), 86log10(), 86Logische Operatoren, 24Logischer Operatoren, 25long Datentyp, 8long long Datentyp, 8lottoza2.c, 152lottoza3.c, 153lottozah.c, 151lshift.c, 37lsystem2.c, 278Makro, 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, 314bitumdre.c, 336fehler.c, 325paritaet.c, 326paturing.c, 324zahlwort.c, 339Modularer Entwurf, 316Modultechnik, 314monataus.c, 432mouse_button(), 223mouse_getpos(), 223mouse_hide(), 223mouse_inwindow(), 223mouse_left(), 223mouse_mid(), 223mouse_right(), 223mouse_setcursor(), 224mouse_setpos(), 223mouse_setwindow(), 223mouse_show(), 223mouse_visible(), 223moverel(), 207moveto(), 207mrz_dez.c, 98mrz_dez2.c, 99Muster, 209nachvor.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, 484oel.c, 205oelbohr.c, 171OktalKonstanten, 11Operation, 128Operationen mit Zeigern, 381Operationen und Datentypen, 43Operator, 37>, 517| , 28, 31||, 26++, 40, 40#, 345##, 346&, 28, 30&&, 26!, 25^, 28, 33Bit, 28| , 32++, 43--, 43Assoziativitt, 43Auswertungszeitupnkt, 43cast-, 98Dekrement, 40Inkrement, 40Komma, 127, 133Postfix, 40Prfix, 40Prioritt, 42, 128, 613sizeof, 91, 373und Datentypen, 43AND, 26arithmetisch, 19Auswertung, 20Logischer, 25Negations-, 25OR, 26Pfeil-, 517Prioritt, 20, 35, 38Punkt, 496relationaler, 23Shift, 37Tilde, 28Vergleichs-, 23Zuweisung, 17Zuweisungs-, 39Operatoren, 19, 23, 25, 26, 28, 37, 39, 40,42, 43Gleichheits-, 23Relationale, 23opshift.c, 39OR-Operator, 26outtextxy(), 201Parameter, 233, 253Struktur, 514paritaet.c, 326paturing.c, 324perror(), 608pfeilfix.c, 518Pfeiloperator, 517piesarc.c, 221pieslice(), 220Pixel, 204pixel.c, 206Polygonausgefullt zeichnen, 210zeichnen, 210polygon.c, 213Positionierenabsolut, 207relativ, 207Postfix-Operator, 40postprae.c, 44potenz.c, 235, 237potenz3.c, 239potenz4.c, 241pow(), 86Prfix-Operator, 40printf(), 67, 585, 615printf1.c, 69printf2.c, 71printf3.c, 72printf4.c, 73printf5.c, 74Prioritt, 20, 35, 38, 42, 128, 613Privatisierungseffekt, 290Programmadd2.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, 362625Indexarrynoname.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, 398freopen.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, 88mauscursor.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, 574626Indexskilang.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, 4Programmablaufplando. . . while, 175for, 129if (einsetig), 110if (zweiseitig), 106while, 161programmglobal, 289Projektion von Koordinaten, 226Prototypen, 242Prozeduren, 238, 239Pufferleeren, 605Pufferung, 603keine, 604Voll-, 603voreingestellt, 604Zeilen-, 603Punkt Operator, 496putc(), 582putchar(), 581putimage(), 217putpixel(), 204puts(), 422, 584qsort(), 390, 525qsort1.c, 391quader.c, 64quadrat.c, 149quadrat2.c, 150Rmische Zahlen, 249rabatt.c, 253rabatt2.c, 255reaktion.c, 203realloc(), 475realloc.c, 477rechne1.c, 451rechne2.c, 452Rechteckausgefllt zeichnen, 210zeichnen, 209rectangle(), 209regel1.c, 246regel1a.c, 93, 246regel1b.c, 94regel1c.c, 94regel5.c, 96register, 310Rekursive Funktion, 273Rekursive Strukturen, 529Relationale Operatoren, 23Relativ Positionieren, 207remove(), 603rename(), 603ReservierungSpeicher, 463restrict, 394return, 238rewind(), 601romzahl.c, 249rueckwae.c, 274sandmann.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, 599selbst.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, 389SortierteListe, 534SpeicherDynamische Freigabe, 463Dynamische Reservierung, 463Speicherort, 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, 615strcat(), 401strcat.c, 401strchr(), 403strchr.c, 404strcmp(), 402strcmp.c, 402strcoll(), 410strcpy(), 395, 400strcpya.c, 394627Indexstrcpyz.c, 395strcspn(), 408stream, 577strein1.c, 421strein2.c, 421strein3.c, 422strein4.c, 422strerror(), 410, 608strftime(), 190striche.c, 238StringKonkatenation, 75Lesen (formatiert), 595, 596Schreiben (formatiert), 595, 596Stringkonkatenation, 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, 506Struktogrammdo. . . while-Anweisung, 175for-Anweisung, 129if-Aweisung (einseitig), 110if-Aweisung (zweiseitig), 106switch-Anweisung, 121while-Anweisung, 161StrukturBitfelder, 564Array, 507Funktion, 514Initialisierung, 504rekursiv, 529Zeiger, 516Strukturarray, 507dynamisch, 522struoper.c, 503struvararr.c, 558struzgr1.c, 516struzgr2.c, 518struzgr3.c, 521strxfrm(), 411suchtext.c, 405switch, 121tabelle.c, 480tan(), 86tanh(), 86tausch.c, 18, 256tausch2.c, 258tausch3.c, 287TechnikModul-, 314Temporre Dateien, 605TextBreite, 215Font, 215Grse, 215Hhe, 215Schreibrichtung, 215Schriftart, 215Zeichensatz, 215textaus1.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, 91UmlenkungE/A, 586ungetc(), 589uninitialisierte Variable, 45union, 559union.c, 560Unions, 559unsigned Datentyp, 8unturing.c, 329va_arg(), 264va_args.c, 348va_end(), 264va_list, 264va_start(), 264Variable initialisieren, 46VariablenDefinition, 14Deklaration, 14Initialisierung, 19Name, 13nicht vorbesetzt, 45uninitialisiert, 45Vereinbarung, 14Vertauschen, 18, 111vchiffre.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, 603vollkom2.c, 184vollkomm.c, 183Vollkommene Zahlen, 183, 184Vordefinierte Makros, 353Voreingestellte Pufferung, 604vormakro.c, 354vprintf(), 594vscanf(), 596vsnprintf(), 596vsprintf(), 596vsscanf(), 596welchdat.c, 193welchtag.c, 192Wertebereich von Datentypen, 9, 614while, 161Wochentag eines Datums, 192wurzstruct.c, 506wurzzahl.c, 432wz.c, 456Zahlenzu groe, 10zu kleine, 10zahltab.c, 145zahltab2.c, 146zahlwort.c, 339Zeichenfarbeerfragen, 207festlegen, 207Zeichensatz, 215Zeichnenzweidimensionalen Balken, 210ausgefllte Ellipse, 209, 220ausgefllter Kreis, 220ausgeflltes Polygon, 210ausgeflltes Rechteck, 210dreidimansionalen Balken, 210Ellipse, 209Kreis, 209Kreisbogen, 210Linie, 207Polygon, 210Rechteck, 209Zeigerauf Funktionen, 280auf Zeiger, 436char, 392Funktionsadressen, 451Operationen mit, 381Pfeiloperator, 517Struktur, 516und Arrays, 374Zeigerarrays, 436Zeilen-Pufferung, 603Zeilenummerierung, 354Zeitangaben, 189zgrarry1.c, 424zgrarry2.c, 424zins.c, 262zu groe Zahlen, 10zu kleine Zahlen, 10zufzahl2.c, 169zufzahl3.c, 170zufzahl4.c, 170zusop2.c, 46Zuweisung, 17Zuweisungsoperator, 17, 39zweidimensionale Arrays, 365Zweier-Komplement, 29Zweiseitige if-Anweisung, 105zweit.c, 4628

Recommended

View more >