12.07.2015 Aufrufe

Einführung in C/C++ - Alex-weingarten.de

Einführung in C/C++ - Alex-weingarten.de

Einführung in C/C++ - Alex-weingarten.de

MEHR ANZEIGEN
WENIGER ANZEIGEN
  • Keine Tags gefunden...

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

E<strong>in</strong>führung <strong>in</strong> C/<strong>C++</strong>Wulf <strong>Alex</strong>2008Karlsruhe


VorwortThere is an old system called UNIX,suspected by many to do nix,but <strong>in</strong> fact it does morethan all systems before,and comprises astonish<strong>in</strong>g uniques.Die Skripten richten sich an Leser mit wenigen Vorkenntnissen<strong>in</strong> <strong>de</strong>r Elektronischen Datenverarbeitung; sie sollen – wieFRITZ REUTERS Urgeschicht von Meckelnborg – ok för Schaulk<strong>in</strong>nertau bruken s<strong>in</strong>. Für die wissenschaftliche Welt zitiere ichaus <strong>de</strong>m Vorwort zu e<strong>in</strong>em Buch <strong>de</strong>s Mathematikers RICHARDCOURANT: Das Buch wen<strong>de</strong>t sich an e<strong>in</strong>en weiten Kreis: an Schülerund Lehrer, an Anfänger und Gelehrte, an Philosophen undIngenieure. Das Lernziel ist e<strong>in</strong>e Vertrautheit mit Betriebssystemen<strong>de</strong>r Gattung UNIX e<strong>in</strong>schließlich L<strong>in</strong>ux, <strong>de</strong>r ProgrammierspracheC/<strong>C++</strong> und <strong>de</strong>m weltumspannen<strong>de</strong>n Internet, die so weitreicht, dass <strong>de</strong>r Leser mit <strong>de</strong>r Praxis beg<strong>in</strong>nen und sich selbständigweiterbil<strong>de</strong>n kann. Ausgelernt hat man nie.Zusammen bil<strong>de</strong>ten die Skripten die Grundlage für das BuchUNIX. C und Internet, im Jahr 1999 <strong>in</strong> zweiter Auflage imSpr<strong>in</strong>ger-Verlag erschienen (ISBN 3-540-65429-1). Das Buch istvergriffen und wird auch nicht weiter gepflegt, da ich mich aufDebian GNU/L<strong>in</strong>ux konzentriere. Me<strong>in</strong>e Debian-Bücher (ISBN3-540-43267-1 und 3-540-23786-0) s<strong>in</strong>d ebenfalls bei Spr<strong>in</strong>ger erschienen,aber nicht im Netz veröffentlicht. Die Skripten dagegenbleiben weiterh<strong>in</strong> im Netz verfügbar und wer<strong>de</strong>n bei Gelegenheitimmer wie<strong>de</strong>r überarbeitet.Warum e<strong>in</strong> L<strong>in</strong>ux/UNIX? Die Betriebssysteme <strong>de</strong>r GattungUNIX laufen auf e<strong>in</strong>er Vielzahl von Computertypen. Unter <strong>de</strong>nverbreiteten Betriebssystemen s<strong>in</strong>d sie die ältesten und ausgereift.Die UNIXe haben sich lange ohne kommerzielle E<strong>in</strong>flüsseentwickelt und tun das teilweise heute noch, siehe L<strong>in</strong>ux,FreeBSD, NetBSD, OpenBSD und an<strong>de</strong>re. Programmierer, nichtdas Market<strong>in</strong>g, haben die Ziele gesetzt. Die UNIXe haben vonAnfang an gemischte Hardware und die Zusammenarbeit mehrererBenutzer unterstützt. In Verb<strong>in</strong>dung mit <strong>de</strong>m X W<strong>in</strong>dowiii


ivSystem, e<strong>in</strong>em netzfähigen Fenstersystem, s<strong>in</strong>d die UNIXe unter<strong>de</strong>n Betriebssystemen mittlerer Größe die leistungsfähigsten.L<strong>in</strong>ux/UNIX-Rechner waren von Anbeg<strong>in</strong>n im Internet dabeiund haben se<strong>in</strong>e Entwicklung bestimmt.Warum C/<strong>C++</strong>? Die universelle Programmiersprache C mitihrer mächtigen Erweiterung <strong>C++</strong> ist – im Vergleich zu BASICetwa – ziemlich e<strong>in</strong>heitlich. Der Anfang ist leicht, an die Grenzenstoßen wenige Benutzer. Das Zusammenspiel zwischen C/<strong>C++</strong>-Programmen und L<strong>in</strong>ux/UNIX funktioniert reibungslos.Warum das Internet? Das Internet ist das größte Computernetzdieser Er<strong>de</strong>, e<strong>in</strong> Zusammenschluss vieler regionaler Netze.Ursprünglich auf Hochschulen und Behör<strong>de</strong>n beschränkt, s<strong>in</strong>dmittlerweile auch Industrie, Han<strong>de</strong>l und Privatpersonen beteiligt.Unser berufliches Leben und zunehmend unser privatesDase<strong>in</strong> wer<strong>de</strong>n vom Internet berührt. E<strong>in</strong>e Email-Anschrift istso wichtig gewor<strong>de</strong>n wie e<strong>in</strong> Telefonanschluss. Als Informationsquelleist das Netz unentbehrlich.Bei <strong>de</strong>r Stoffauswahl habe ich mich von me<strong>in</strong>er Arbeit als Benutzer,Verwalter und Programmierer leiten lassen. Beson<strong>de</strong>rerWert wird auf die Erläuterung <strong>de</strong>r zahlreichen Fachbegriffe gelegt,die <strong>de</strong>m Anfänger das Leben erschweren. Die typische Frage,vor <strong>de</strong>r auch ich immer wie<strong>de</strong>r stehe, lautet: Was ist XYZ undwozu kann man es gebrauchen? H<strong>in</strong>sichtlich vieler E<strong>in</strong>zelheitenverweise ich auf die Referenz-Handbücher zu <strong>de</strong>n Rechenanlagenund Programmiersprachen o<strong>de</strong>r auf Monografien, um <strong>de</strong>nText nicht über die Maßen aufzublähen; er ist e<strong>in</strong> Kompromissaus Breite und Tiefe. Alles über UNIX, C und das Internet istke<strong>in</strong> Buch, son<strong>de</strong>rn e<strong>in</strong> Bücherschrank.An e<strong>in</strong>igen Stellen gehe ich außer auf das Wie auch auf dasWarum e<strong>in</strong>. Von Zeit zu Zeit sollte man <strong>de</strong>n Blick weg von <strong>de</strong>nWellen auf das Meer richten, sonst erwirbt man nur kurzlebigesWissen.Man kann <strong>de</strong>n Gebrauch e<strong>in</strong>es Betriebssystems, e<strong>in</strong>er Programmierspracheo<strong>de</strong>r <strong>de</strong>r Netzdienste nicht alle<strong>in</strong> aus Büchernerlernen – das ist wie beim Klavierspielen o<strong>de</strong>r Kuchenbacken.Die Beispiele und Übungen wur<strong>de</strong>n auf e<strong>in</strong>er Hewlett-Packard9000/712 unter HP-UX 10.20 und e<strong>in</strong>em PC <strong>de</strong>r Marke We<strong>in</strong>gartenerKatzenberg Auslese unter Debian GNU/L<strong>in</strong>ux entwickelt.Als Shell wur<strong>de</strong>n Bourne-Abkömml<strong>in</strong>ge bevorzugt, als Compiler


wur<strong>de</strong> neben <strong>de</strong>m von Hewlett-Packard <strong>de</strong>r GNU gcc verwen<strong>de</strong>t.Die vollständigen Quellen <strong>de</strong>r Beispiele stehen im Netz.Dem Text liegen eigene Erfahrungen aus fünf Jahrzehntenzugrun<strong>de</strong>. Se<strong>in</strong>e Wurzeln gehen zurück auf e<strong>in</strong>e Erste Hilfe fürBenutzer <strong>de</strong>r Hewlett-Packard 9000 Mo<strong>de</strong>ll 550 unter HP-UX, imJahr 1986 aus zwanzig Aktenordnern <strong>de</strong>stilliert, die die Masch<strong>in</strong>ebegleiteten. Gegenwärtig verschiebt sich <strong>de</strong>r Schwerpunkt <strong>in</strong>Richtung Debian GNU/L<strong>in</strong>ux. Ich habe auch frem<strong>de</strong> Hilfe beanspruchtund danke Kollegen <strong>in</strong> <strong>de</strong>n Universitäten Karlsruhe undLyon sowie Mitarbeitern <strong>de</strong>r Firmen IBM und Hewlett-Packardfür schriftliche Unterlagen und mündlichen Rat sowie zahlreichenStu<strong>de</strong>nten für Anregungen und Diskussionen. Darüber h<strong>in</strong>aushabe ich fleißig das Internet angezapft und viele dort umlaufen<strong>de</strong>Gui<strong>de</strong>s, Primers, HOWTOs, Tutorials und Sammlungenvon Frequently Asked Questions (FAQs) verwen<strong>de</strong>t.vWe<strong>in</strong>garten (Ba<strong>de</strong>n), 15. Februar 2006Wulf <strong>Alex</strong>


Überblick1 Programmieren <strong>in</strong> C/<strong>C++</strong> 2A Zahlensysteme 291B Zeichensätze 298C UNIX-Systemaufrufe 314D C-Lexikon 317E Karlsruher Test 329F GNU Lizenzen 345G Zeittafel 365H Zum Weiterlesen 377vi


Inhalt1 Programmieren <strong>in</strong> C/<strong>C++</strong> 21.1 Grundbegriffe . . . . . . . . . . . . . . . . . . . . 21.1.1 Wozu Programmierkenntnisse? . . . . . . . . 21.1.2 Warum braucht man Programmiersprachen? 31.1.3 Sprachenfamilien . . . . . . . . . . . . . . . . 81.1.4 Imperative Programmiersprachen . . . . . . 101.1.5 Objektorientierte Programmiersprachen . . . 151.1.6 Interpreter – Compiler – L<strong>in</strong>ker . . . . . . . . 181.1.7 Qualität und Stil . . . . . . . . . . . . . . . . 211.1.8 Programmiertechnik . . . . . . . . . . . . . . 231.1.9 Aufgabenanalyse und Entwurf . . . . . . . . 251.1.9.1 Aufgabenstellung . . . . . . . . . . 251.1.9.2 Zerlegen <strong>in</strong> Teilaufgaben . . . . . . 261.1.9.3 Zusammensetzen aus Teilaufgaben 271.1.10 Prototyp<strong>in</strong>g . . . . . . . . . . . . . . . . . . . . 281.1.11 Flussdiagramme . . . . . . . . . . . . . . . . . 281.1.12 Memo Grundbegriffe . . . . . . . . . . . . . . 301.1.13 Übung Grundbegriffe . . . . . . . . . . . . . . 311.2 Programmer’s Workbench . . . . . . . . . . . . . 311.2.1 Nochmals die Editoren . . . . . . . . . . . . . 321.2.2 Compiler und L<strong>in</strong>ker (cc, ccom, ld) . . . . . . 321.2.3 Unentbehrlich (make) . . . . . . . . . . . . . . 351.2.4 Debugger (xdb, gdb) . . . . . . . . . . . . . . . 391.2.5 Profiler (time, gprof) . . . . . . . . . . . . . . 411.2.6 Archive, Bibliotheken (ar) . . . . . . . . . . . 431.2.7 Weitere Werkzeuge . . . . . . . . . . . . . . . 461.2.8 Versionsverwaltung mit RCS, SCCS und CVS 481.2.9 Systemaufrufe . . . . . . . . . . . . . . . . . . 571.2.9.1 Was s<strong>in</strong>d Systemaufrufe? . . . . . 571.2.9.2 Beispiel Systemzeit (time) . . . . . 591.2.9.3 Beispiel Datei-Informationen(access, stat, open, close) . . . . . . 631.2.9.4 Beispiel Prozesserzeugung (exec,fork) . . . . . . . . . . . . . . . . . . 69vii


viiiINHALT1.2.10 Begriffe Programmer’s Workbench . . . . . . 701.2.11 Memo Programmer’s Workbench . . . . . . . 701.2.12 Übung Programmer’s Workbench . . . . . . . 711.2.13 Fragen Programmer’s Workbench . . . . . . . 761.3 Bauste<strong>in</strong>e e<strong>in</strong>es Quelltextes . . . . . . . . . . . . 761.3.1 Übersicht . . . . . . . . . . . . . . . . . . . . . 761.3.2 Syntax-Diagramme . . . . . . . . . . . . . . . 771.3.3 Kommentar . . . . . . . . . . . . . . . . . . . 781.3.4 Namen . . . . . . . . . . . . . . . . . . . . . . 801.3.5 Schlüsselwörter . . . . . . . . . . . . . . . . . 811.3.6 Operan<strong>de</strong>n . . . . . . . . . . . . . . . . . . . . 821.3.6.1 Konstanten und Variable . . . . . 831.3.6.2 Typen – Grundbegriffe . . . . . . . 831.3.6.3 E<strong>in</strong>fache Typen . . . . . . . . . . . 851.3.6.4 Zusammengesetzte Typen (Arrays,Strukturen) . . . . . . . . . . 901.3.6.5 Union . . . . . . . . . . . . . . . . . 931.3.6.6 Aufzählungstypen . . . . . . . . . 941.3.6.7 Po<strong>in</strong>ter (Zeiger) . . . . . . . . . . . 941.3.6.8 Weitere Namen für Typen (type<strong>de</strong>f)1031.3.6.9 Speicherklassen . . . . . . . . . . . 1051.3.6.10 Geltungsbereich . . . . . . . . . . . 1061.3.6.11 Lebensdauer . . . . . . . . . . . . . 1071.3.7 Operationen . . . . . . . . . . . . . . . . . . . 1081.3.7.1 Ausdrücke . . . . . . . . . . . . . . 1081.3.7.2 Zuweisung . . . . . . . . . . . . . . 1081.3.7.3 Arithmetische Operationen . . . . 1091.3.7.4 Logische Operationen . . . . . . . 1101.3.7.5 Vergleiche . . . . . . . . . . . . . . 1121.3.7.6 Bitoperationen . . . . . . . . . . . 1141.3.7.7 st o<strong>in</strong>teroperationen . . . . . . . . 1151.3.7.8 E<strong>in</strong>- und Ausgabe-Operationen . . 1161.3.7.9 Sonstige Operationen . . . . . . . 1191.3.7.10 Vorrang und Reihenfolge . . . . . . 1201.3.8 Anweisungen . . . . . . . . . . . . . . . . . . . 1221.3.8.1 Leere Anweisung . . . . . . . . . . 1221.3.8.2 Zuweisung als Anweisung . . . . . 1231.3.8.3 Kontrollanweisungen . . . . . . . . 1231.3.8.4 Rückgabewert . . . . . . . . . . . . 1311.3.9 Memo Bauste<strong>in</strong>e . . . . . . . . . . . . . . . . . 134


INHALTix1.3.10 Übung Bauste<strong>in</strong>e . . . . . . . . . . . . . . . . 1351.4 Funktionen . . . . . . . . . . . . . . . . . . . . . . 1361.4.1 Aufbau und Deklaration . . . . . . . . . . . . 1361.4.2 Po<strong>in</strong>ter auf Funktionen . . . . . . . . . . . . . 1371.4.3 Parameterübergabe . . . . . . . . . . . . . . . 1371.4.4 Kommandozeilenargumente, ma<strong>in</strong>() . . . . . 1511.4.5 Funktionen mit wechseln<strong>de</strong>r Argumentanzahl. . . . . . . . . . . . . . . . . . . . . . . . 1531.4.6 Iterativer Aufruf e<strong>in</strong>er Funktion . . . . . . . 1571.4.7 Rekursiver Aufruf e<strong>in</strong>er Funktion . . . . . . 1591.4.8 Assemblerrout<strong>in</strong>en . . . . . . . . . . . . . . . 1611.4.9 Memo Funktionen . . . . . . . . . . . . . . . . 1681.4.10 Übung Funktionen . . . . . . . . . . . . . . . 1691.5 Funktions-Bibliotheken . . . . . . . . . . . . . . . 1691.5.1 Zweck und Aufbau . . . . . . . . . . . . . . . 1691.5.2 Standardbibliothek . . . . . . . . . . . . . . . 1701.5.2.1 Übersicht . . . . . . . . . . . . . . . 1701.5.2.2 Standard-C-Bibliothek . . . . . . . 1711.5.2.3 Standard-Mathematik-Bibliothek 1741.5.2.4 Standard-Grafik-Bibliothek . . . . 1761.5.2.5 Weitere Teile <strong>de</strong>r Standardbibliothek. . . . . . . . . . . . . . . . . . 1761.5.3 Xlib, Xt und Xm (X W<strong>in</strong>dow System) . . . . . 1761.5.4 NAG-Bibliothek . . . . . . . . . . . . . . . . . 1771.5.5 Eigene Bibliotheken . . . . . . . . . . . . . . . 1781.5.6 Speichermo<strong>de</strong>lle (PC-DOS) . . . . . . . . . . . 1781.5.7 Memo Bibliotheken . . . . . . . . . . . . . . . 1791.5.8 Übung Bibliotheken . . . . . . . . . . . . . . . 1801.6 Klassen . . . . . . . . . . . . . . . . . . . . . . . . 1801.6.1 Warum C mit Klassen? . . . . . . . . . . . . . 1801.6.2 Datenabstraktion, Klassenbegriff . . . . . . . 1811.6.3 Klassenhierarchie, abstrakte Klassen, Vererbung. . . . . . . . . . . . . . . . . . . . . . 1841.6.4 Memo Klassen . . . . . . . . . . . . . . . . . . 1911.6.5 Übung Klassen . . . . . . . . . . . . . . . . . . 1921.7 Klassen-Bibliotheken . . . . . . . . . . . . . . . . 1921.7.1 <strong>C++</strong>-Standardbibliothek . . . . . . . . . . . . 1921.7.2 Standard Template Library (STL) . . . . . . . 1931.7.3 C-XSC . . . . . . . . . . . . . . . . . . . . . . . 1951.7.3.1 Was ist C-XSC? . . . . . . . . . . . 195


xINHALT1.7.3.2 Datentypen, Operatoren undFunktionen . . . . . . . . . . . . . 1961.7.3.3 Teilfel<strong>de</strong>r von Vektoren und Matrizen. . . . . . . . . . . . . . . . . 1971.7.3.4 Genaue Auswertung von Ausdrücken. . . . . . . . . . . . . . . 1981.7.3.5 Dynamische Langzahl-Arithmetik 2001.7.3.6 E<strong>in</strong>- und Ausgabe <strong>in</strong> C-XSC . . . . 2021.7.3.7 C-XSC-Numerikbibliothek . . . . . 2031.7.3.8 Beispiel Intervall-Newton-Verfahren . . . . . . . . . . . . . . 2031.7.4 X11-Programmierung mit <strong>de</strong>m Qt-Toolkit . . 2051.8 Überla<strong>de</strong>n von Operatoren . . . . . . . . . . . . . 2101.9 Präprozessor . . . . . . . . . . . . . . . . . . . . . 2131.9.1 <strong>de</strong>f<strong>in</strong>e-Anweisungen . . . . . . . . . . . . . . . 2131.9.2 <strong>in</strong>clu<strong>de</strong>-Anweisungen . . . . . . . . . . . . . . 2151.9.3 Bed<strong>in</strong>gte Kompilation (#if<strong>de</strong>f) . . . . . . . . . 2181.9.4 Memo Präprozessor . . . . . . . . . . . . . . . 2211.9.5 Übung Präprozessor . . . . . . . . . . . . . . 2211.10 Dokumentation . . . . . . . . . . . . . . . . . . . . 2211.10.1 Zweck . . . . . . . . . . . . . . . . . . . . . . . 2211.10.2 Anfor<strong>de</strong>rungen (DIN 66 230) . . . . . . . . . . 2221.10.3 Erstellen e<strong>in</strong>er man-Seite . . . . . . . . . . . 2231.11 Weitere C-Programme . . . . . . . . . . . . . . . . 2251.11.1 Name . . . . . . . . . . . . . . . . . . . . . . . 2251.11.2 Aufbau . . . . . . . . . . . . . . . . . . . . . . 2261.11.3 Fehlersuche . . . . . . . . . . . . . . . . . . . 2291.11.4 Optimierung . . . . . . . . . . . . . . . . . . . 2301.11.5 curses – Fluch o<strong>de</strong>r Segen? . . . . . . . . . . . 2331.11.6 Mehr o<strong>de</strong>r weniger zufällig . . . . . . . . . . . 2371.11.7 E<strong>in</strong> Herz für Po<strong>in</strong>ter . . . . . . . . . . . . . . 2421.11.7.1 Nullpo<strong>in</strong>ter . . . . . . . . . . . . . 2431.11.7.2 Po<strong>in</strong>ter auf Typ void . . . . . . . . 2431.11.7.3 Arrays und Po<strong>in</strong>ter . . . . . . . . . 2461.11.7.4 Arrays von Funktionspo<strong>in</strong>tern . . 2511.11.8 Verarbeitung von Str<strong>in</strong>gs . . . . . . . . . . . . 2571.11.9 Dynamische Speicherverwaltung (malloc) . . 2581.11.10 X W<strong>in</strong>dow System . . . . . . . . . . . . . . . . 2651.11.11 cgi-Programme . . . . . . . . . . . . . . . . . . 2711.12 Obfuscated C . . . . . . . . . . . . . . . . . . . . . 278


INHALTxi1.13 Portieren von Programmen . . . . . . . . . . . . . 2801.13.1 Regeln . . . . . . . . . . . . . . . . . . . . . . . 2801.13.2 Übertragen von ALGOL nach C . . . . . . . . 2821.13.3 Übertragen von FORTRAN nach C . . . . . . 2851.14 Exkurs über Algorithmen . . . . . . . . . . . . . . 289A Zahlensysteme 291B Zeichensätze 298B.1 EBCDIC, ASCII, Roman8, IBM-PC . . . . . . . . 298B.2 German-ASCII . . . . . . . . . . . . . . . . . . . . 305B.3 ASCII-Steuerzeichen . . . . . . . . . . . . . . . . 305B.4 Lat<strong>in</strong>-1 (ISO 8859-1) . . . . . . . . . . . . . . . . . 306C UNIX-Systemaufrufe 314D C-Lexikon 317D.1 Schlüsselwörter . . . . . . . . . . . . . . . . . . . 317D.2 Operatoren . . . . . . . . . . . . . . . . . . . . . . 320D.3 Standardfunktionen . . . . . . . . . . . . . . . . . 321D.4 pr<strong>in</strong>tf(3), scanf(3) . . . . . . . . . . . . . . . . . . 326D.5 Inclu<strong>de</strong>-Dateien . . . . . . . . . . . . . . . . . . . 326D.6 Präprozessor-Anweisungen . . . . . . . . . . . . . 327E Karlsruher Test 329F GNU Lizenzen 345F.1 GNU General Public License . . . . . . . . . . . . 345F.2 GNU Free Documentation License . . . . . . . . 354G Zeittafel 365H Zum Weiterlesen 377


Abbildungen1.1 Flussdiagramm . . . . . . . . . . . . . . . . . . . 291.2 Nassi-Shnei<strong>de</strong>rman-Diagramm . . . . . . . . . . 301.3 Syntax-Diagramm . . . . . . . . . . . . . . . . . . 79xii


Tabellen1.1 Länge von Datentypen . . . . . . . . . . . . . . . . . 86xiii


Programme und an<strong>de</strong>re Quellen1.1 LISP-Programm . . . . . . . . . . . . . . . . . . . 91.2 SCHEME-Programm . . . . . . . . . . . . . . . . 91.3 PROLOG-Programm . . . . . . . . . . . . . . . . 101.4 Programm Z 22 . . . . . . . . . . . . . . . . . . . . 111.5 COBOL-Programm . . . . . . . . . . . . . . . . . 121.6 JAVA-Programm . . . . . . . . . . . . . . . . . . . 171.7 Makefile . . . . . . . . . . . . . . . . . . . . . . . . 361.8 Erweitertes Makefile . . . . . . . . . . . . . . . . 371.9 C-Programm mit Funktionsbibliothek . . . . . . 451.10 C-Funktion Mittelwert . . . . . . . . . . . . . . . 461.11 C-Funktion Varianz . . . . . . . . . . . . . . . . . 461.12 Makefile zum Sortierprogramm . . . . . . . . . . 511.13 Inclu<strong>de</strong>-Datei zum Sortierprogramm . . . . . . . 511.14 C-Programm Sortieren . . . . . . . . . . . . . . . 531.15 C-Funktion Bubblesort . . . . . . . . . . . . . . . 551.16 C-Programm Systemzeit . . . . . . . . . . . . . . 611.17 FORTRAN-Programm Systemzeit . . . . . . . . . 611.18 C-Programm Datei-Informationen . . . . . . . . . 681.19 C-Programm Fork-Bombe . . . . . . . . . . . . . . 691.20 C-Programm mit Fehlern . . . . . . . . . . . . . . 721.21 C-Programm Kommentar . . . . . . . . . . . . . . 801.22 C-Programm character und <strong>in</strong>teger . . . . . . . . 881.23 C-Programm Po<strong>in</strong>terarithmetik . . . . . . . . . . 1021.24 C-Programm Bitweise Negation . . . . . . . . . . 1121.25 C-Programm Bitoperationen . . . . . . . . . . . . 1151.26 C-Programm Ausgabe per Systemaufruf . . . . . 1171.27 C-Programm Ausgabe per Standardfunktion . . 1181.28 C-Programm e<strong>in</strong>fache for-Schleife . . . . . . . . . 1271.29 C-Programm zusammengesetzte for-Schleife . . 1281.30 C-Programm mit goto, grauenvoll . . . . . . . . . 1301.31 C-Programm, verbessert . . . . . . . . . . . . . . 1311.32 C-Programm return-Anweisungen . . . . . . . . 1331.33 C-Programm Funktionsprototyp . . . . . . . . . . 1371.34 C-Funktion Parameterübergabe by value . . . . 1391.35 C-Funktion Parameterübergabe by reference . . 140xiv


Programme und an<strong>de</strong>re Quellenxv1.36 FORTRAN-Funktion Parameterübergabe byreference . . . . . . . . . . . . . . . . . . . . . . . 1401.37 PASCAL-Funktion Parameterübergabe by value 1411.38 PASCAL-Funktion Parameterübergabe by reference. . . . . . . . . . . . . . . . . . . . . . . . . 1411.39 C-Programm Parameterübergabe an C-Funktionen . . . . . . . . . . . . . . . . . . . . . . 1421.40 C-Programm Parameterübergabe anFORTRAN-Funktion . . . . . . . . . . . . . . . . 1431.41 C-Programm Parameterübergabe an PASCAL-Funktionen . . . . . . . . . . . . . . . . . . . . . . 1431.42 FORTRAN-Programm Parameterübergabe anC-Funktionen . . . . . . . . . . . . . . . . . . . . . 1441.43 FORTRAN-Programm Parameterübergabe anFORTRAN-Fkt. . . . . . . . . . . . . . . . . . . . 1451.44 FORTRAN-Programm Parameterübergabe anPASCAL-Fkt. . . . . . . . . . . . . . . . . . . . . . 1461.45 PASCAL-Programm Parameterübergabe an C-Funktionen . . . . . . . . . . . . . . . . . . . . . . 1471.46 PASCAL-Programm Parameterübergabe anFORTRAN-Funktion . . . . . . . . . . . . . . . . 1471.47 PASCAL-Programm Parameterübergabe anPASCAL-Funktionen . . . . . . . . . . . . . . . . 1481.48 PASCAL-Funktion Parameterübergabe by value 1491.49 PASCAL-Funktion Parameterübergabe by reference. . . . . . . . . . . . . . . . . . . . . . . . . 1491.50 Shellscript Parameterübergabe . . . . . . . . . . 1501.51 C-Programm Parameterübernahme von Shellscript. . . . . . . . . . . . . . . . . . . . . . . . . 1501.52 C-Programm Kommandozeilenargumente . . . . 1511.53 C-Funktion Wechseln<strong>de</strong> Anzahl von Argumenten 1561.54 C-Programm Quadratwurzel . . . . . . . . . . . . 1581.55 C-Programm ggT . . . . . . . . . . . . . . . . . . . 1601.56 C-Programm Fakultät . . . . . . . . . . . . . . . . 1601.57 C-Programm Selbstaufruf ma<strong>in</strong>() . . . . . . . . . 1611.58 C-Programm, Fakultäten . . . . . . . . . . . . . . 1661.59 Assemblerfunktion Addition 1 . . . . . . . . . . . 1681.60 C-Programm Str<strong>in</strong>gverarbeitung . . . . . . . . . 1741.61 C-Programm Mathematische Funktionen . . . . 1751.62 <strong>C++</strong>-Programm Hallo, Welt . . . . . . . . . . . . . 181


xviProgramme und an<strong>de</strong>re Quellen1.63 <strong>C++</strong>-Programm Umrechnung UTC-MEZ . . . . . 1841.64 <strong>C++</strong>-Programm Geometrische Formen . . . . . . 1901.65 C-XSC-Funktion <strong>de</strong>fect() . . . . . . . . . . . . . . 2001.66 C-XSC-Programm e<strong>in</strong>facher Genauigkeit . . . . 2011.67 C-XSC-Programm mehrfacher Genauigkeit . . . 2011.68 C-XSC-Programm mit E<strong>in</strong>- und Ausgabe . . . . . 2021.69 C-XSC-Programm Intervall-Newton-Verfahren . 2041.70 Makefile zu qhello.cpp . . . . . . . . . . . . . . . . 2061.71 Inclu<strong>de</strong>-Datei zu qhello.cpp . . . . . . . . . . . . . 2071.72 <strong>C++</strong>-Programm qhello.cpp . . . . . . . . . . . . . 2091.73 <strong>C++</strong>-Programm Primzahlen . . . . . . . . . . . . 2121.74 Inclu<strong>de</strong>-Datei /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h . . . . . . . . . 2171.75 C-Programm Umrechnung Zahlenbasis . . . . . 2211.76 C-Programm, m<strong>in</strong>imal . . . . . . . . . . . . . . . 2261.77 C-Programm, e<strong>in</strong>fachst . . . . . . . . . . . . . . . 2271.78 C-Programm, e<strong>in</strong>fach . . . . . . . . . . . . . . . . 2271.79 C-Programm, fortgeschritten . . . . . . . . . . . . 2281.80 C-Programm, Variante . . . . . . . . . . . . . . . 2281.81 C-Programm, E<strong>in</strong>gabe . . . . . . . . . . . . . . . . 2291.82 C-Programm Dateiputzete . . . . . . . . . . . . . 2341.83 C-Programm, curses . . . . . . . . . . . . . . . . . 2361.84 C-Programm Zufallszahlen . . . . . . . . . . . . . 2381.85 C-Programm Zufallszahlen, mit Funktion . . . . 2401.86 C-Funktion Zufallszahlen . . . . . . . . . . . . . . 2411.87 PASCAL-Programm Zufallszahlen, mit Funktion 2411.88 C-Programm, void-Po<strong>in</strong>ter . . . . . . . . . . . . . 2461.89 C-Programm Primzahlen . . . . . . . . . . . . . . 2511.90 C-Programm Array von Funktionspo<strong>in</strong>tern . . . 2541.91 C-Funktion bil<strong>de</strong>r.c . . . . . . . . . . . . . . . . . 2551.92 Makefile zu schiff.c . . . . . . . . . . . . . . . . . 2571.93 C-Programm Dynamische Speicherverwaltung . 2591.94 C-Programm Sortieren nach Du<strong>de</strong>n . . . . . . . . 2641.95 C-Programm X W<strong>in</strong>dow System/Xlib . . . . . . . 2711.96 Webseite cgi_test . . . . . . . . . . . . . . . . . . . 2721.97 Inclu<strong>de</strong>-Datei cgi.h . . . . . . . . . . . . . . . . . . 2731.98 C-Programm cgi_test.c . . . . . . . . . . . . . . . 2741.99 C-Funktionen cgi.c . . . . . . . . . . . . . . . . . . 2771.100 ALGOL-Programm . . . . . . . . . . . . . . . . . 2831.101 C-Programm ggT nach Euklid . . . . . . . . . . . 2841.102 FORTRAN-Programm Quadratische Gleichung . 286


Programme und an<strong>de</strong>re Quellenxvii1.103 C-Programm Quadratische Gleichung . . . . . . 288


xviiiProgramme und an<strong>de</strong>re Quellen


Zum Gebrauch• Hervorhebungen im Text wer<strong>de</strong>n kursiv dargestellt.• Titel von Veröffentlichungen o<strong>de</strong>r Abschnitten, kurze Zitateo<strong>de</strong>r wörtliche Re<strong>de</strong> wer<strong>de</strong>n im Text kursiv markiert.• In Aussagen über Wörter wer<strong>de</strong>n diese kursiv abgesetzt.• Stichwörter für e<strong>in</strong>en Vortrag o<strong>de</strong>r e<strong>in</strong>e Vorlesung ersche<strong>in</strong>enfett.• Namen von Personen stehen <strong>in</strong> KAPITÄLCHEN.• E<strong>in</strong>gaben von <strong>de</strong>r Tastatur und Ausgaben auf <strong>de</strong>n Bildschirmwer<strong>de</strong>n <strong>in</strong> Schreibmasch<strong>in</strong>enschrift wie<strong>de</strong>rgegeben.• H<strong>in</strong>sichtlich <strong>de</strong>r <strong>de</strong>utschen Rechtschreibung bef<strong>in</strong><strong>de</strong>t sichdas Manuskript <strong>in</strong> e<strong>in</strong>em Übergangsstadium.• H<strong>in</strong>ter L<strong>in</strong>ux/UNIX-Kommandos folgt manchmal <strong>in</strong> Klammerndie Nummer <strong>de</strong>r betroffenen Sektion <strong>de</strong>s Referenz-Handbuchs, z. B. vi(1). Diese Nummer samt Klammernist beim Aufruf <strong>de</strong>s Kommandos nicht e<strong>in</strong>zugeben.• Suchen Sie die englische o<strong>de</strong>r französische Übersetzung e<strong>in</strong>es<strong>de</strong>utschen Fachwortes, so f<strong>in</strong><strong>de</strong>n Sie diese bei <strong>de</strong>r erstmaligenErläuterung <strong>de</strong>s <strong>de</strong>utschen Wortes.• Suchen Sie die <strong>de</strong>utsche Übersetzung e<strong>in</strong>es englischen o<strong>de</strong>rfranzösischen Fachwortes, so f<strong>in</strong><strong>de</strong>n Sie e<strong>in</strong>en Verweis imSach- und Namensverzeichnis.• UNIX wird hier immer als die Gattung <strong>de</strong>r aus <strong>de</strong>m beiAT&T um 1970 entwickelten Unix ähnlichen Betriebssystemeverstan<strong>de</strong>n, nicht als geschützter Name e<strong>in</strong>es bestimmtenProduktes.• Ich gebe möglichst genaue H<strong>in</strong>weise auf weiterführen<strong>de</strong>Dokumente im Netz. Der Leser sei sich aber bewußt, dasssich sowohl Inhalte wie Adressen (URLs) än<strong>de</strong>rn. Bei Verweisenauf Webseiten (URLs) ist die Angabe <strong>de</strong>s Protokollshttp:// weggelassen.xix


Zum Gebrauch 1• Unter Benutzer, Programmierer, Verwalter usw. wer<strong>de</strong>n sowohlmännliche wie weibliche Ersche<strong>in</strong>ungsformen verstan<strong>de</strong>n.• Ich re<strong>de</strong> <strong>de</strong>n Leser mit Sie an, obwohl unter Stu<strong>de</strong>nten undim Netz das Du üblich ist. Gegenwärtig ersche<strong>in</strong>t mir dieseWahl passen<strong>de</strong>r.


Brevity is the soul of wit.Shakespeare, Hamlet1 Programmieren <strong>in</strong> C/<strong>C++</strong>1.1 Grundbegriffe1.1.1 Wozu Programmierkenntnisse?Auch wer se<strong>in</strong>e Brötchen nicht mit Programmieren verdient,son<strong>de</strong>rn nur mit Computern arbeitet, braucht Grundkenntnisseim Programmieren, um die richtigen Vorstellungen von <strong>de</strong>mGeschehen h<strong>in</strong>ter <strong>de</strong>m Bildschirm zu haben. Nicht je<strong>de</strong>r Masch<strong>in</strong>enbauermuss e<strong>in</strong>en Kolbenmotor konstruieren können, aber ermuss wissen, wie e<strong>in</strong>e Kolbenmasch<strong>in</strong>e aufgebaut ist und funktioniert,und er sollte mit e<strong>in</strong>em Schraubenschlüssel umgehenkönnen. H<strong>in</strong>zu kommt, dass häufig kle<strong>in</strong>ere Anpassungen o<strong>de</strong>rErgänzungen <strong>de</strong>r Software erfor<strong>de</strong>rlich s<strong>in</strong>d, für die man nichtimmer e<strong>in</strong>en Spezialisten hat.Wenn es ernst wird, bezieht man se<strong>in</strong>e Kenntnisse aus dreiQuellen, nämlich aus:• e<strong>in</strong>em Lehrbuch wie diesem,• e<strong>in</strong>er Referenz zum Nachschlagen, siehe das Verzeichnisam En<strong>de</strong> <strong>de</strong>s Buches,• e<strong>in</strong>er Sammlung von Frequently Asked Questions aus <strong>de</strong>mInternet, hier zu <strong>de</strong>n Themen C und <strong>C++</strong>.Das Lehrbuch sorgt für <strong>de</strong>n Überblick, die Referenz vermitteltE<strong>in</strong>zelheiten, die FAQ beantwortet die offen gebliebenen Fragen.FAQs zu C und <strong>C++</strong> f<strong>in</strong><strong>de</strong>n sich unter:• www.eskimo.com/ scs/c-faq/top.html, die FAQ <strong>de</strong>rNewsgruppe comp.lang.c,• www-<strong>in</strong>fo2.<strong>in</strong>formatik.uni-wuerzburg.<strong>de</strong>/dclc-faq/,die FAQ <strong>de</strong>r Newsgruppe <strong>de</strong>.comp.lang.c,• www.faqs.org/faqs/C-faq/learn/,2


1.1. GRUNDBEGRIFFE 3• www.cerfnet.com/˜mpcl<strong>in</strong>e/c++-faq-lite/,• rtfm.mit.edu/pub/usenet-by-hierarchy/news/answers/<strong>C++</strong>-faq/ bzw. C-faq/.Langfristig s<strong>in</strong>d auch die genannen Newsgruppen e<strong>in</strong>e Quelle<strong>de</strong>r Erleuchtung, aber man sollte Grundkenntnisse erworben haben,ehe man dort mitmischt.1.1.2 Warum braucht man Programmiersprachen?Von e<strong>in</strong>er Anweisung <strong>in</strong> e<strong>in</strong>er höheren Programmiersprache biszu <strong>de</strong>n Nullen und E<strong>in</strong>sen im Befehlsregister <strong>de</strong>s Prozessors iste<strong>in</strong> weiter Weg. Wir wollen diesen Weg schrittweise an Han<strong>de</strong><strong>in</strong>es kle<strong>in</strong>en, aber weltweit bekannten Programmes verfolgen.Das Programm schreibt <strong>de</strong>n Gruß Hallo, Welt! auf <strong>de</strong>n Bildschirm.Weitere Exemplare dieses Programmes <strong>in</strong> über 200 Programmiersprachen1 f<strong>in</strong><strong>de</strong>n sich bei <strong>de</strong>r Louisiana Tech Universityunter:http://www.latech.edu/~acm/HelloWorld.shtmlAls erstes das Programm, so wie es e<strong>in</strong> C-Programmiererschreibt:/* hallo.c, C-Programm */#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){pr<strong>in</strong>tf("Hallo, Welt!\n");return 0;}Das Aussehen <strong>de</strong>s Textes wird durch <strong>de</strong>n ANSI-C-Standard bestimmt,letzten En<strong>de</strong>s durch die Leute, die die Sprache C entwickelthaben. Diese Form <strong>de</strong>s Programmes wird von geübten1 Unter www.ionet.net/˜timtroyr/funhouse/beer.htmlliegt e<strong>in</strong>e ähnliche Sammlung.


4 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Programmierern verstan<strong>de</strong>n und Programmquelle (source) genannt.Die Masch<strong>in</strong>e kann nichts damit anfangen.Damit das Programm von e<strong>in</strong>er Masch<strong>in</strong>e ausgeführt wer<strong>de</strong>nkann, muss es übersetzt wer<strong>de</strong>n. Hierzu wird e<strong>in</strong> weiteresProgramm, e<strong>in</strong> Compiler, herangezogen. Im Fall von Cläuft <strong>de</strong>r Übersetzungsvorgang <strong>in</strong> mehreren Schritten ab, ohnedass <strong>de</strong>r Benutzer etwas davon merkt. Wir verwen<strong>de</strong>n hier<strong>de</strong>n GNU-C-Compiler unter MS-DOS auf e<strong>in</strong>em PC. Im erstenSchritt (Präprozessor) wer<strong>de</strong>n <strong>de</strong>r für die Masch<strong>in</strong>e unbe<strong>de</strong>uten<strong>de</strong>Kommentar entfernt und die mit e<strong>in</strong>em Doppelkreuz beg<strong>in</strong>nen<strong>de</strong>nPräprozessor-Anweisungen ausgeführt. Das Ergebnissieht leicht gekürzt so aus:# 1 "hallo.c"# 1 "c:/djgpp/<strong>in</strong>clu<strong>de</strong>/stdio.h" 1 3# 1 "c:/djgpp/<strong>in</strong>clu<strong>de</strong>/sys/djtypes.h" 1 3# 12 "c:/djgpp/<strong>in</strong>clu<strong>de</strong>/stdio.h" 2 3type<strong>de</strong>f void *va list;type<strong>de</strong>f long unsigned <strong>in</strong>t size t;type<strong>de</strong>f struct {<strong>in</strong>t cnt;char * ptr;char * base;<strong>in</strong>t bufsiz;<strong>in</strong>t flag;<strong>in</strong>t file;char * name to remove;} FILE;extern FILE dj std<strong>in</strong>, dj stdout, dj st<strong>de</strong>rr;void clearerr(FILE * stream);<strong>in</strong>t fclose(FILE * stream);<strong>in</strong>t feof(FILE * stream);..<strong>in</strong>t.pr<strong>in</strong>tf(const char * format, ...);.<strong>in</strong>t vspr<strong>in</strong>tf(char * s, const char * format, va list ap);extern FILE dj stdprn, dj stdaux;# 3 "hallo.c" 2


1.1. GRUNDBEGRIFFE 5<strong>in</strong>t ma<strong>in</strong>(){pr<strong>in</strong>tf("Hallo, Welt!\n");return 0;}Wir erkennen, dass <strong>de</strong>r Präprozessor e<strong>in</strong>e Reihe von Zeilen h<strong>in</strong>zugefügthat. Im Pr<strong>in</strong>zip könnte das auch <strong>de</strong>r Programmierermachen, doch so erspart man sich viel rout<strong>in</strong>emäßige Arbeit.Im zweiten Schritt wird das C-Programm <strong>in</strong> e<strong>in</strong> Assembler-Programm übersetzt:.file "hallo.c"gcc2 compiled.:gnu compiled c:.textLC0:.ascii "Hallo, Welt!\12\0".align 2.globl ma<strong>in</strong>ma<strong>in</strong>:pushl %ebpmovl %esp,%ebpcall ma<strong>in</strong>pushl $LC0call pr<strong>in</strong>tfaddl $4,%espxorl %eax,%eaxjmp L1.align 2,0x90L1:leaveretSelbst diese, bereits schwerer verständliche Form könnte e<strong>in</strong> erfahrenerProgrammierer noch von Hand schreiben. Früher gabes nichts an<strong>de</strong>res. Im Großen und Ganzen entspricht e<strong>in</strong>e Anweisung<strong>in</strong> C o<strong>de</strong>r FORTRAN vier Assembler-Anweisungen. DieAssembler-Befehle wer<strong>de</strong>n zu e<strong>in</strong>em wesentlichen Teil durch<strong>de</strong>n Hersteller <strong>de</strong>r CPU bestimmt, hier also durch Intel. DasAssembler-Programm ist an die Hardware und das Betriebssystemgebun<strong>de</strong>n.Nun folgt als dritter Schritt die Übersetzung <strong>de</strong>s Assemblerprogramms<strong>in</strong> e<strong>in</strong> Masch<strong>in</strong>enprogramm, hier gekürzt und mit


6 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Hexa<strong>de</strong>zimalzahlen anstelle <strong>de</strong>r Nullen und E<strong>in</strong>sen wie<strong>de</strong>rgegeben:4c01 0300 66da 7d31 da00 0000 0d00 00000000 0401 2e74 6578 7400 0000 0000 00000000 0000 3000 0000 8c00 0000 bc00 00000000 0000 0300 0000 2000 0000 2e64 61746100 0000 3000 0000 3000 0000 0000 00000000 0000 0000 0000 0000 0000 0000 00004000 0000 2e62 7373 0000 0000 3000 0000Diese Form ist für e<strong>in</strong>en Menschen nicht mehr verständlich,statt<strong>de</strong>ssen für die Masch<strong>in</strong>e, weshalb sie als Masch<strong>in</strong>enco<strong>de</strong>bezeichnet wird, gelegentlich auch als Objektco<strong>de</strong>. E<strong>in</strong> Zurück-Übersetzen <strong>in</strong> Assemblerco<strong>de</strong> ist nur e<strong>in</strong>geschränkt möglich 2 .Obige Form ist jedoch immer noch nicht ausführbar. Wir verwen<strong>de</strong>ne<strong>in</strong>e Standard-Funktion pr<strong>in</strong>tf() zur Ausgabe auf <strong>de</strong>nBildschirm. Auch h<strong>in</strong>ter <strong>de</strong>m Wörtchen ma<strong>in</strong> verbirgt sich e<strong>in</strong>iges.Deren Co<strong>de</strong> muß noch h<strong>in</strong>zugefügt wer<strong>de</strong>n, dann kanndie Masch<strong>in</strong>e loslegen mit <strong>de</strong>r Begrüßung. Diesen letzten Schrittvollzieht <strong>de</strong>r L<strong>in</strong>ker. Der Anfang <strong>de</strong>s ausführbaren Programmeshallo.exe sieht nicht besser aus als vorher, <strong>de</strong>r Umfang <strong>de</strong>sProgrammfiles ist größer gewor<strong>de</strong>n:4d5a 0000 0400 0000 2000 2700 ffff 00006007 0000 5400 0000 0d0a 7374 7562 2e682067 656e 6572 6174 6564 2066 726f 6d207374 7562 2e61 736d 2062 7920 646a 61736d2c 206f 6e20 5475 6520 4a61 6e20 33302032 333a 3433 3a35 3820 3139 3936 0d0a5468 6520 5354 5542 2e45 5845 2073 7475Das müsste e<strong>in</strong> Programmierer schreiben, gäbe es ke<strong>in</strong>e höherenProgrammiersprachen. Als Kontrast dazu e<strong>in</strong> kurzes Beispiel e<strong>in</strong>erproblemangepassten, masch<strong>in</strong>enfernen Sprache (SQL). DieAufgabe sei die Abfrage e<strong>in</strong>er Datenbank, die ihre Daten <strong>in</strong> Formvon Tabellen mit Spalten und Zeilen hält:2 Genauer: Das Rück-Übersetzen ist möglich, das Ergebnis jedochpraktisch unbrauchbar, wenn es um mehr als triviale Programmegeht.


1.1. GRUNDBEGRIFFE 7select nachname, vorname, telefon from mitarbeiterwhere wohnort=’Karlsruhe’or<strong>de</strong>r by nachname, vorname;Die Datenbank soll bitteschön e<strong>in</strong> Liste mit Nachnamen, Vornamenund Telefonnummer aus <strong>de</strong>r Tabelle mitarbeiter herausziehenund dabei nur die Mitarbeiter berücksichtigen, <strong>de</strong>renWohnort Karlsruhe ist. Die Liste soll an erster Stelle nach <strong>de</strong>mNachnamen alphabetisch sortiert se<strong>in</strong>, bei gleichem Nachnamennach <strong>de</strong>m Vornamen. E<strong>in</strong>facher lässt sich e<strong>in</strong>e Aufgabe kaumformulieren.E<strong>in</strong>e Programmiersprache wird von zwei Seiten her entwickelt.Von oben, <strong>de</strong>n zu programmieren<strong>de</strong>n Aufgaben aus <strong>de</strong>rrealen Welt her, kommen die Anfor<strong>de</strong>rungen an die Sprache. Vonunten, <strong>de</strong>r Hardware (CPU) und <strong>de</strong>m Betriebssystem her kommendie Möglichkeiten zur Lösung <strong>de</strong>r Aufgaben. Wir haben folgen<strong>de</strong>Schichten:• Aufgabe, Problem• Lösungsweg, Algorithmus• Programm <strong>in</strong> e<strong>in</strong>er höheren (problemorientierten) Sprache• Assemblerprogramm• Masch<strong>in</strong>enprogramm• Mikroprogramme (Firmware) im Computer• ElektronikJe<strong>de</strong> Schicht stellt e<strong>in</strong> Mo<strong>de</strong>ll <strong>de</strong>r nächsthöheren Schicht dar,wobei das, was sich <strong>in</strong> <strong>de</strong>r Elektronik abspielt, hoffentlich nochetwas mit <strong>de</strong>r ursprünglichen Aufgabe zu tun hat. Der Compilerbauermuss sowohl das Problem wie die Hardware samtBetriebssystem im Auge haben, wenn er beispielsweise e<strong>in</strong>enC-Compiler für das Betriebssystem PC-DOS auf e<strong>in</strong>em Intel-Prozessor schreibt. Wer sich näher für Compiler <strong>in</strong>teressiert,kann mit <strong>de</strong>m Buch von ALFRED V. AHO – genannt das Dragon-Book – beg<strong>in</strong>nen. Die Thematik geht über <strong>de</strong>n Bau von Compilernh<strong>in</strong>aus und erstreckt sich ganz allgeme<strong>in</strong> auf die Analyseund Verarbeitung von Zeichenfolgen.


8 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.1.3 SprachenfamilienHat man e<strong>in</strong>e Aufgabe, e<strong>in</strong> Problem zu lösen, so kann man dreiAbschnitte auf <strong>de</strong>m Weg unterschei<strong>de</strong>n:• Aufgabenstellung,• Lösungsweg,• Ergebnis.Das Ergebnis ist nicht bekannt, sonst wäre die Aufgabe bereitsgelöst. Die Aufgabenstellung und erfor<strong>de</strong>rlichenfalls e<strong>in</strong>en Lösungswegsollten wir kennen.Mithilfe <strong>de</strong>r bekannten Programmiersprachen von BASIC bis<strong>C++</strong> beschreiben wir <strong>de</strong>n Lösungsweg <strong>in</strong> e<strong>in</strong>er für <strong>de</strong>n Computergeeigneten Form. Diese Programmiersprachen wer<strong>de</strong>n als algorithmischeo<strong>de</strong>r prozedurale Programmiersprachen im weiterenS<strong>in</strong>n bezeichnet, weil die Programme aus Prozeduren bestehen,die Anweisungen an <strong>de</strong>n Computer enthalten (late<strong>in</strong>ischproce<strong>de</strong>re = vorangehen). Diese Familie wird unterteilt <strong>in</strong> dieimperativen o<strong>de</strong>r prozeduralen Sprachen im engeren S<strong>in</strong>ne e<strong>in</strong>erseitsund die objektorientierten Sprachen an<strong>de</strong>rerseits (late<strong>in</strong>ischimperare = befehlen).Bequemer wäre es jedoch, wir könnten uns mit <strong>de</strong>r Beschreibung<strong>de</strong>r Aufgabe begnügen und das F<strong>in</strong><strong>de</strong>n e<strong>in</strong>es Lösungsweges<strong>de</strong>m Computer überlassen. Se<strong>in</strong> Nutzen wür<strong>de</strong> damit be<strong>de</strong>utendwachsen. Die noch nicht sehr verbreiteten <strong>de</strong>klarativenProgrammiersprachen gehen diesen Weg (late<strong>in</strong>isch <strong>de</strong>clarare= erklären, beschreiben). Die Datenbank-Abfragesprache SQL(Structured Query Language) gehört hierher: <strong>in</strong> <strong>de</strong>n Programmen(SQL-Script) steht, was man wissen will, nicht, wie mandazu kommt. Die <strong>de</strong>klarativen Sprachen unterteilt man <strong>in</strong> diefunktionalen und die logischen o<strong>de</strong>r prädikativen Sprachen.Wir haben also folgen<strong>de</strong> E<strong>in</strong>teilung (wobei die tatsächlich benutztenSprachen Mischl<strong>in</strong>ge s<strong>in</strong>d und die E<strong>in</strong>ordnung ihrem amstärksten ausgeprägten Charakterzug folgt):• Prozedurale Sprachen im weiteren S<strong>in</strong>n– imperative, algorithmische, operative o<strong>de</strong>r im engerenS<strong>in</strong>n prozedurale Sprachen (BASIC, FORTRAN, CO-BOL, C, PASCAL)– objektorientierte Sprachen (SMALLTALK, <strong>C++</strong>, Java)


1.1. GRUNDBEGRIFFE 9• Deklarative Sprachen– funktionale o<strong>de</strong>r applikative Sprachen (LISP, SCHE-ME, HASKELL)– logische o<strong>de</strong>r prädikative Sprachen (PROLOG)Diese Sprachentypen wer<strong>de</strong>n auch Paradigmen (Beispiel, Muster)genannt. Auf imperative und objektorientierte Sprachen gehenwir bald ausführlich e<strong>in</strong>. Zuerst e<strong>in</strong> kurzer Blick auf funktionaleund prädikative Sprachen.Programme <strong>in</strong> funktionalen Programmiersprachen wie LISPo<strong>de</strong>r SCHEME bestehen aus Def<strong>in</strong>itionen von Funktionen, äußerlichähnlich e<strong>in</strong>em Gleichungssystem, die auf Listen vonWerten angewen<strong>de</strong>t wer<strong>de</strong>n. Hier das Hello-World-Programm <strong>in</strong>LISP:; LISP(DEFUN HELLO-WORLD ()(PRINT (LIST ’HELLO ’WORLD)))Quelle 1.1 : LISP-Programm Hello, Worldund auch noch <strong>in</strong> SCHEME:(<strong>de</strong>f<strong>in</strong>e hello-world(lambda ()(beg<strong>in</strong>(write ’Hello-World)(newl<strong>in</strong>e)(hello-world))))Quelle 1.2 : SCHEME-Programm Hello, WorldDie großzügige Verwendung run<strong>de</strong>r Klammern fällt <strong>in</strong>s Auge,aber ansonsten s<strong>in</strong>d die Programme zu e<strong>in</strong>fach, um die Eigenheiten<strong>de</strong>r Sprachen zu erkennen. Die Sprache C ist trotz <strong>de</strong>rVerwendung <strong>de</strong>s Funktionsbegriffes ke<strong>in</strong>e funktionale Programmiersprache,da ihr Konzept nicht an<strong>de</strong>rs als <strong>in</strong> FORTRAN o<strong>de</strong>rPASCAL auf <strong>de</strong>r sequentiellen Ausführung von Anweisungen beruht.Programmen <strong>in</strong> logischen o<strong>de</strong>r prädikativen Sprachen wiePROLOG wer<strong>de</strong>n Fakten und Regeln zum Folgern mitgegeben,sie beantworten dann die Anfrage, ob e<strong>in</strong>e Behauptung mit <strong>de</strong>n


10 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Fakten und Regeln verträglich (wahr) ist o<strong>de</strong>r nicht. Viele Denksportaufgabenlegen e<strong>in</strong>e solche Sprache nahe. Hier das Hello-World-Programm <strong>in</strong> PROLOG:% HELLO WORLD. Works with Sbp (prolog)hello :-pr<strong>in</strong>tstr<strong>in</strong>g("HELLO WORLD!!!!").pr<strong>in</strong>tstr<strong>in</strong>g([]).pr<strong>in</strong>tstr<strong>in</strong>g([H|T]) :- put(H), pr<strong>in</strong>tstr<strong>in</strong>g(T).Quelle 1.3 : PROLOG-Programm Hello, WorldDie Umgewöhnung von e<strong>in</strong>em Paradigma auf e<strong>in</strong> an<strong>de</strong>resgeht über das Erlernen e<strong>in</strong>er neuen Sprache h<strong>in</strong>aus und bee<strong>in</strong>flusstdie Denkweise, die Sicht auf e<strong>in</strong> Problem.Es gibt e<strong>in</strong> zweite, von <strong>de</strong>r ersten unabhängige E<strong>in</strong>teilung,die zugleich die historische Entwicklung spiegelt:• masch<strong>in</strong>enorientierte Sprachen (Masch<strong>in</strong>ensprache, Assembler)• problemorientierte Sprachen (höhere Sprachen)In <strong>de</strong>r Frühzeit gab es nur die völlig auf die Hardware ausgerichteteund unbequeme Masch<strong>in</strong>ensprache, wir haben e<strong>in</strong>e Kostprobegesehen. Assembler s<strong>in</strong>d e<strong>in</strong> erster Schritt <strong>in</strong> Richtung aufdie Probleme und die Programmierer zu. Höhere Sprachen wieFORTRAN s<strong>in</strong>d von <strong>de</strong>r Hardware schon ziemlich losgelöst und<strong>in</strong> diesem Fall an mathematische Probleme angepasst. Es gibtaber für spezielle Aufgaben wie Str<strong>in</strong>gverarbeitung, Datenbankabfragen,Statistik o<strong>de</strong>r Grafik Sprachen, die <strong>in</strong> ihrer Anpassungnoch weiter gehen. Auch die zur Formatierung <strong>de</strong>s vorliegen<strong>de</strong>nTextes benutzte Sammlung von LaTeX-Makros stellt e<strong>in</strong>e problemangepassteSprache dar. Der Preis für die Erleichterungenist e<strong>in</strong> Verlust an Allgeme<strong>in</strong>heit. Denken Sie an die Notensprache<strong>de</strong>r Musik: an ihre Aufgabe gut angepasst, aber für an<strong>de</strong>reGebiete wie etwa die Chemie ungeeignet.1.1.4 Imperative ProgrammiersprachenDer Computer kennt nur Bits, das heißt Nullen und E<strong>in</strong>sen.Für <strong>de</strong>n Menschen ist diese Ausdrucksweise unangebracht. Zum


1.1. GRUNDBEGRIFFE 11Glück s<strong>in</strong>d die Zeiten, als man die Bits e<strong>in</strong>zeln von Hand <strong>in</strong> dieLochstreifen schlug, vorbei.Die nächste Stufe war die Zusammenfassung mehrerer Bitszu Gruppen, die man mit Buchstaben und Ziffern bezeichnenkonnte. E<strong>in</strong> Ausschnitt e<strong>in</strong>es Programmes für die ZUSE Z 22 imFreiburger Co<strong>de</strong> aus <strong>de</strong>n fünfziger Jahren:B15Br<strong>in</strong>ge <strong>de</strong>n Inhalt von Register 15 <strong>in</strong> <strong>de</strong>n AkkuU6 Kopiere <strong>de</strong>n Akku nach Register 6B18Br<strong>in</strong>ge <strong>de</strong>n Inhalt von Register 18 <strong>in</strong> <strong>de</strong>n Akku+ Addiere Akku und Reg. 6, Summe <strong>in</strong> Akku und 6B13Br<strong>in</strong>ge <strong>de</strong>n Inhalt von Register 13 <strong>in</strong> <strong>de</strong>n AkkuX Multipliziere Akku mit Register 6CGKU30+1 Kopiere <strong>de</strong>n Akku nach <strong>de</strong>r Adresse, die <strong>in</strong>Register 30 steht; <strong>in</strong>krementiere Register 300 leere OperationQuelle 1.4 : Ausschnitt aus e<strong>in</strong>em Programm für die ZUSE Z 22Man musste <strong>de</strong>m Computer <strong>in</strong> aller Ausführlichkeit sagen,was er zu tun hatte. Das war auch mühsam, aber diese Art <strong>de</strong>rProgrammierung gibt es heute noch unter <strong>de</strong>m Namen Assemblerprogrammierung.Man braucht sie, wenn man die Hardwarefest im Griff haben will, also an <strong>de</strong>n Grenzen Software - Hardware(Treiberprogramme). Darüber h<strong>in</strong>aus s<strong>in</strong>d gute Assemblerprogrammeschnell, weil sie nichts Unnötiges tun. Programmieren<strong>in</strong> Assembler setzt vertiefte Kenntnisse <strong>de</strong>r Hardware voraus.Für PCs gibt es von Microsoft e<strong>in</strong>e Komb<strong>in</strong>ation von QuickC mit Assembler, die es gestattet, das große Programm <strong>in</strong> <strong>de</strong>rhöheren Sprache C und e<strong>in</strong>zelne kritische Teile <strong>in</strong> Assembler zuprogrammieren. Wer unbed<strong>in</strong>gt <strong>de</strong>n herben Reiz <strong>de</strong>r Assemblerprogrammierungkennenlernen will, hat es mit dieser Komb<strong>in</strong>atione<strong>in</strong>fach.Die meisten Programmierer wollen jedoch nicht Speicher<strong>in</strong>halteverschieben, son<strong>de</strong>rn Gleichungen lösen o<strong>de</strong>r Wörter suchen3 . Schon Mitte <strong>de</strong>r fünfziger Jahre entstand daher bei <strong>de</strong>rFirma IBM die erste höhere Programmiersprache, und zwar zumBearbeiten mathematischer Aufgaben. Die Sprache war daher3 Recht betrachtet, will man auch ke<strong>in</strong>e Gleichungen, son<strong>de</strong>rnAufgaben wie die Dimensionierung e<strong>in</strong>es Masch<strong>in</strong>enteils o<strong>de</strong>rdas Zusammenstellen e<strong>in</strong>es Sachregisters lösen.


12 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>stark an die Ausdrucksweise <strong>de</strong>r Mathematik angelehnt und zum<strong>in</strong><strong>de</strong>stfür die mathematisch gebil<strong>de</strong>te Welt e<strong>in</strong>igermaßen bequem.Sie wur<strong>de</strong> als formula translator, abgekürzt FORTRANbezeichnet. FORTRAN wur<strong>de</strong> im Laufe <strong>de</strong>r Jahrzehnte weiterentwickelt – zur Zeit ist FORTRAN 90 bzw. 95 aktuell – undist auch heute noch die <strong>in</strong> <strong>de</strong>r Technik am weitesten verbreiteteProgrammiersprache. Ke<strong>in</strong> Ingenieur kommt an FORTRAN vorbei.E<strong>in</strong> Beispiel f<strong>in</strong><strong>de</strong>t sich <strong>in</strong> Abschnitt 1.4.3 Parameterübergabeauf Seite 137.Die Kaufleute hatten mit Mathematik weniger am Hut, dafüraber große Datenmengen. Sie erfan<strong>de</strong>n En<strong>de</strong> <strong>de</strong>r fünfziger Jahreihre eigene Programmiersprache COBOL, das heißt CommonBus<strong>in</strong>ess Oriented Language. Dass Leutnant GRACE M. HOP-PER (e<strong>in</strong>e Frau, zuletzt im Admiralsrang) sowohl <strong>de</strong>n ersten Bugerlegt wie auch COBOL erfun<strong>de</strong>n habe, ist e<strong>in</strong>e Legen<strong>de</strong> um e<strong>in</strong>Körnchen Wahrheit herum. COBOL ist ebenfalls unverwüstlichund gilt heute noch als die am weitesten verbreitete Programmiersprache.Ke<strong>in</strong> Wirtschaftswissenschaftler kommt an CO-BOL vorbei. E<strong>in</strong> COBOL-Programm liest sich wie gebrochenesEnglisch:000100 IDENTIFICATION DIVISION.000200 PROGRAM-ID. HELLOWORLD.000300 DATE-WRITTEN. 02/05/96 21:04.000400* AUTHOR BRIAN COLLINS000500 ENVIRONMENT DIVISION.000600 CONFIGURATION SECTION.000700 SOURCE-COMPUTER. RM-COBOL.000800 OBJECT-COMPUTER. RM-COBOL.000900001000 DATA DIVISION.001100 FILE SECTION.001200100000 PROCEDURE DIVISION.100100100200 MAIN-LOGIC SECTION.100300 BEGIN.100400 DISPLAY " " LINE 1 POSITION 1 ERASE EOS.100500 DISPLAY "HELLO, WORLD." LINE 15 POSITION 10.100600 STOP RUN.100700 MAIN-LOGIC-EXIT.100800 EXIT.


1.1. GRUNDBEGRIFFE 13Quelle 1.5 : COBOL-Programm Hello, WorldAls die Computer <strong>in</strong> die Reichweite gewöhnlicher Stu<strong>de</strong>ntenkamen, entstand das Bedürfnis nach e<strong>in</strong>er e<strong>in</strong>fachen Programmiersprachefür das Gröbste, kurzum nach e<strong>in</strong>em Beg<strong>in</strong>ners’All Purpose Symbolic Instruction Co<strong>de</strong>. JOHN KEMENY undTHOMAS KURTZ vom Dartmouth College <strong>in</strong> <strong>de</strong>n USA erfüllten1964 mit BASIC diesen Bedarf. Der Gebrauch von BASIC gilt<strong>in</strong> ernsthaften Programmiererkreisen als anrüchig 4 . Richtig ist,dass es unzählige, mite<strong>in</strong>an<strong>de</strong>r unverträgliche BASIC-Dialektegibt, dass BASIC die Unterschie<strong>de</strong> zwischen Betriebssystem undProgrammiersprache verwischt und dass die meisten BASIC-Dialekte ke<strong>in</strong>e or<strong>de</strong>ntliche Programmstruktur ermöglichen unddaher nur für kurze Programme brauchbar s<strong>in</strong>d. Richtig ist aberauch, dass mo<strong>de</strong>rne BASIC-Dialekte wie HP-BASIC o<strong>de</strong>r Quick-BASIC von Microsoft über alle Hilfsmittel zur Strukturierungverfügen und dass <strong>in</strong> ke<strong>in</strong>er an<strong>de</strong>ren gängigen Programmiersprachedie Bearbeitung von Str<strong>in</strong>gs so e<strong>in</strong>fach ist wie <strong>in</strong> BA-SIC 5 . In <strong>de</strong>r Messwerterfassung ist es beliebt. Fazit: die Kenntnisvon GW-BASIC auf <strong>de</strong>m PC reicht für e<strong>in</strong>en Programmierernicht aus, aber für viele Aufgaben ist e<strong>in</strong> mo<strong>de</strong>rnes BASIC e<strong>in</strong>brauchbares Werkzeug.Anfang <strong>de</strong>r sechziger Jahre wur<strong>de</strong> ALGOL 60 aufgrund theoretischerÜberlegungen entwickelt und nach e<strong>in</strong>er umfangreichenÜberarbeitung als ALGOL 68 veröffentlicht. Diese Programmierspracheist nie <strong>in</strong> großem Umfang angewen<strong>de</strong>t wor<strong>de</strong>n,spielte aber e<strong>in</strong>e be<strong>de</strong>uten<strong>de</strong> Rolle als Wegbereiter für die heutigenProgrammiersprachen beziehungsweise die heutigen Fassungenälterer Sprachen. Viele Konzepte gehen auf ALGOL zurück.En<strong>de</strong> <strong>de</strong>r sechziger Jahre hatte sich das Programmierenvom Kunsthandwerk zur Wissenschaft entwickelt, und NIKLAUSWIRTH von <strong>de</strong>r ETH Zürich brachte PASCAL heraus, um se<strong>in</strong>enStu<strong>de</strong>nten e<strong>in</strong>en anständigen Programmierstil anzugewöhnen.PASCAL ist e<strong>in</strong>e strenge und logisch aufgebaute Sprache,daher gut zum Lernen geeignet. Turbo-PASCAL von Borland istauf PCs weit verbreitet. E<strong>in</strong> PASCAL-Beispiel f<strong>in</strong><strong>de</strong>t sich <strong>in</strong> Ab-4 No programmers write <strong>in</strong> BASIC, after the age of 12.5 1964 bot ke<strong>in</strong>e an<strong>de</strong>re Programmiersprache nennenswerteMöglichkeiten zur Verarbeitung von Str<strong>in</strong>gs.


14 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>schnitt 1.4.3 Parameterübergabe auf Seite 137. E<strong>in</strong>e Weiterentwicklungvon PASCAL ist MODULA.Die Sprache C wur<strong>de</strong> von BRIAN KERNIGHAN, DENNIS RIT-CHIE und KEN THOMPSON <strong>in</strong> <strong>de</strong>n siebziger Jahren entwickelt,um das Betriebssystem UNIX damit portabel zu gestalten. LangeZeit h<strong>in</strong>durch gab das Buch <strong>de</strong>r bei<strong>de</strong>n Erstgenannten <strong>de</strong>nStandard vor 6 . In <strong>de</strong>n Achtzigern hat das American NationalStandards Institute (ANSI) an e<strong>in</strong>em Standard für C gearbeitet,<strong>de</strong>m alle neueren Compiler folgen (h<strong>in</strong>terherh<strong>in</strong>ken).Das ANSI-Dokument wur<strong>de</strong> als Internationaler Standard AN-SI/ISO/IEC 9899:1990 anerkannt. En<strong>de</strong> <strong>de</strong>r neunziger Jahrewur<strong>de</strong> e<strong>in</strong>e erneute Überarbeitung als Internationaler StandardANSI/ISO/IEC 9899:1999 7 veröffentlicht, <strong>de</strong>r auch als C9X bezeichnetwird. Den Stand <strong>de</strong>r D<strong>in</strong>ge erfährt man bei:http://anubis.dkuug.dk/JTC1/SC22/WG14/Erfahrungsgemäß dauert es e<strong>in</strong>ige Jahre, bis die Compiler e<strong>in</strong>enneuen Standard voll unterstützen.Das ANSI-C von 1990 ist im wesentlichen e<strong>in</strong>e Übermengevon K&R-C; die Nachführung <strong>de</strong>r Programme – wenn überhaupterfor<strong>de</strong>rlich – macht ke<strong>in</strong>e Schwierigkeiten. ANSI-C kennt e<strong>in</strong>Schlüsselwort von K&R nicht mehr (entry) und dafür mehrereneue.C ist allgeme<strong>in</strong> verwendbar, konzentriert, lässt <strong>de</strong>m Programmierergroße Freiheiten (hav<strong>in</strong>g the best parts of FORT-RAN and assembly language <strong>in</strong> one place) und führt <strong>in</strong> <strong>de</strong>rRegel zu schnellen Programmen, da vielen C-Anweisungen un-6 Das vergleichsweise schlanke Buch von K&R istdie erste Lektüre, sobald man e<strong>in</strong>fache C-Programmeschreiben kann. Über die Beschreibung von C h<strong>in</strong>ausbirgt es wertvolle allgeme<strong>in</strong>e H<strong>in</strong>weise zum Programmieren.Anmerkungen hat STEVE SUMMIT unterhttp://www.eskimo.com/˜scs/cclass/knotes/top.htmlveröffenlicht.7 Den Standard kann man sich bei www.ansi.org gegen 18US-Dollar im pdf-Format herunterla<strong>de</strong>n, rund 500 Seiten. Auf<strong>de</strong>r Titelseite steht Pr<strong>in</strong>ted <strong>in</strong> the United States of America, auf<strong>de</strong>m Rücktitel Pr<strong>in</strong>ted <strong>in</strong> Switzerland. Die Wahrheit <strong>in</strong> me<strong>in</strong>emFall: Pr<strong>in</strong>ted <strong>in</strong> Karlsruhe. Hoffentlich geht das nicht so weiter.


1.1. GRUNDBEGRIFFE 15mittelbar Assembler-Anweisungen entsprechen (Masch<strong>in</strong>ennähe).Die Sprache hat e<strong>in</strong>en kle<strong>in</strong>en Kern (wenige Schlüsselwörter),Erweiterungen und Hardwareabhängigkeiten stecken <strong>in</strong><strong>de</strong>n Bibliotheken. C-Programme gelten als unübersichtlich, aberdas ist e<strong>in</strong>e Frage <strong>de</strong>s Programmierstils, nicht <strong>de</strong>r Sprache 8 . AufUNIX-Systemen hat man mit C die wenigsten Schwierigkeiten.Für DOS-PCs gibt es von Microsoft das preiswerte Quick-C undaus <strong>de</strong>m GNU-Projekt e<strong>in</strong>en kostenlosen C-Compiler im Quellco<strong>de</strong>und betriebsklar kompiliert.Aus C hat BJARNE STROUSTRUP von 1979 bis 1989 e<strong>in</strong>eSprache <strong>C++</strong> entwickelt, die ebenfalls e<strong>in</strong>e Übermenge von C bil<strong>de</strong>t.Der Denkansatz (Paradigma) beim Programmieren <strong>in</strong> <strong>C++</strong>weicht jedoch erheblich von C ab, so dass man e<strong>in</strong>e längere Lernphasee<strong>in</strong>planen muss, mehr als bei e<strong>in</strong>em Übergang von PAS-CAL nach C. Da sich ANSI-C und <strong>C++</strong> gleichzeitig entwickelthaben, s<strong>in</strong>d e<strong>in</strong>ige Neuerungen von <strong>C++</strong> <strong>in</strong> ANSI-C e<strong>in</strong>geflossen,zum Beispiel das Prototyp<strong>in</strong>g. E<strong>in</strong> ANSI-C-Programm sollte vonje<strong>de</strong>m <strong>C++</strong>-Compiler verstan<strong>de</strong>n wer<strong>de</strong>n; das Umgekehrte giltnicht. Aktuell ist <strong>de</strong>r Standard ANSI/ISO/IEC 14882:1998.1.1.5 Objektorientierte ProgrammiersprachenIn <strong>de</strong>m Maß, wie die Hardware leistungsfähiger wur<strong>de</strong>, wagtensich die Programmierer an komplexere und umfangreichereAufgaben heran. Dass große Aufgaben <strong>in</strong> kle<strong>in</strong>ere Teilaufgabenunterglie<strong>de</strong>rt wer<strong>de</strong>n müssen, ist e<strong>in</strong>e alltägliche Erfahrungund nicht auf Programme beschränkt. Die Strukturierung e<strong>in</strong>erAufgabe samt ihrer Lösung gewann an Be<strong>de</strong>utung. Programmiersprachenwie C, die die Strukturierung e<strong>in</strong>es Programms <strong>in</strong>Module (Funktionen, Prozeduren, Subrout<strong>in</strong>en) erleichtern, verbreitetensich.Um 1980 herum war die Komplexität wie<strong>de</strong>r so angewachsen,dass nach neuen Wegen zu ihrer Bewältigung gesucht wur<strong>de</strong>.Außer<strong>de</strong>m hatte die Software als Kostenfaktor die Hardwareüberholt. Es galt, umfangreiche Programme schnell und preiswertherzustellen und dabei noch <strong>de</strong>ren Zuverlässigkeit sicher-8 Es gibt e<strong>in</strong>en International Obfuscated C Co<strong>de</strong> Contest,e<strong>in</strong>en Wettbewerb um das unübersichtlichste C-Programm, sieheAbschnitt 1.12 Obfuscated C auf Seite 278.


16 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>zustellen, ähnlich wie heutzutage Autos produziert wer<strong>de</strong>n. ZweiSchlagwörter kamen auf: Objektorientierung und SoftwareEng<strong>in</strong>eer<strong>in</strong>g. Entklei<strong>de</strong>t man sie <strong>de</strong>r merkantilen Übertreibungen,bleibt immer noch e<strong>in</strong> brauchbarer Kern von I<strong>de</strong>en übrig.Der Typbegriff wur<strong>de</strong> zur Klasse erweitert. E<strong>in</strong>e Klasse enthältVariable und zugehörige Funktionen, die nun Metho<strong>de</strong>n genanntwer<strong>de</strong>n. Klassen können im Gegensatz zum Typ vom Programmierer<strong>de</strong>f<strong>in</strong>iert wer<strong>de</strong>n. Sie bil<strong>de</strong>n e<strong>in</strong>e Hierarchie, wobeihöhere Klassen Eigenschaften an niedrigere vererben. Klassenhaben e<strong>in</strong>e genau <strong>de</strong>f<strong>in</strong>ierte Schnittstelle (Interface) zum Rest<strong>de</strong>s Programms, ihr Innenleben bleibt verborgen. Was sie tun, istbekannt, wie sie es tun, geht nieman<strong>de</strong>n etwas an. Diese scharfeTrennung von Innen und Außen ist wesentlich für <strong>de</strong>n Klassenbegriff.Was für C Funktionsbibliotheken s<strong>in</strong>d, das s<strong>in</strong>d für<strong>C++</strong> Klassenbibliotheken. Die Programmierarbeit besteht zu e<strong>in</strong>emgroßen Teil im Schreiben von Klassen. Wie e<strong>in</strong>e Variable dieVerwirklichung (Realisierung, Instantiierung) e<strong>in</strong>es Typs ist, soist e<strong>in</strong> Objekt e<strong>in</strong>e Instanz e<strong>in</strong>er Klasse. Von e<strong>in</strong>er Klasse könnenbeliebig viele Objekte abgeleitet wer<strong>de</strong>n. Klassen und <strong>de</strong>renObjekte s<strong>in</strong>d die Bauste<strong>in</strong>e e<strong>in</strong>es objektorientierten Programms.<strong>C++</strong> hieß anfangs C mit Klassen.Neben <strong>C++</strong> ist e<strong>in</strong>e zweite objektorientierte Erweiterung vonC entstan<strong>de</strong>n, die unter <strong>de</strong>m Namen Objective C <strong>in</strong> Verb<strong>in</strong>dungmit <strong>de</strong>m Betriebssystem NeXT e<strong>in</strong>e gewisse Verbreitunggefun<strong>de</strong>n hat. Der GNU-C-Compiler unterstützt sowohl <strong>C++</strong> wieObjective C, ansonsten ist es ziemlich still gewor<strong>de</strong>n um dieseSprache.Es kommen noch e<strong>in</strong> paar D<strong>in</strong>ge h<strong>in</strong>zu, um das Programmierenzu erleichtern, aber das Wesentliche am objektorientiertenProgrammieren ist, dass die Aufgabe nicht mehr <strong>in</strong> Module zerlegtwird, die aus Anweisungen bestehen, son<strong>de</strong>rn <strong>in</strong> vone<strong>in</strong>an<strong>de</strong>runabhängige Objekte, die sich Mitteilungen o<strong>de</strong>r Botschaftenschicken. Die Objektorientierung setzt bei <strong>de</strong>r Aufgabenanalysee<strong>in</strong>, nicht erst bei <strong>de</strong>r Umsetzung <strong>in</strong> e<strong>in</strong>e Programmiersprache(Codierung).Wie verhält sich <strong>C++</strong> zu C? Manche sagen, dass <strong>C++</strong> e<strong>in</strong>eneue, von C völlig unabhängige Sprache sei. An<strong>de</strong>re wie<strong>de</strong>rumbetrachten <strong>C++</strong> als e<strong>in</strong>e umfangreiche Erweiterung von C. Aufje<strong>de</strong>n Fall s<strong>in</strong>d die Kenntnisse, die man beim Lernen von C erworbenhat, auch <strong>in</strong> <strong>C++</strong> nützlich und ke<strong>in</strong>esfalls überholt. <strong>C++</strong>-


1.1. GRUNDBEGRIFFE 17Compiler übersetzen die meisten C-Programme anstandslos. Zufe<strong>in</strong>eren Unterschie<strong>de</strong>n und Unverträglichkeiten siehe DAVID.R. TRIBBLE:http://david.tribble.com/text/cdiffs.htmFür numerische Aufgaben ist <strong>C++</strong> <strong>in</strong> <strong>de</strong>r Universität Karlsruheum e<strong>in</strong>e Klassenbibliothek namens C-XSC (Exten<strong>de</strong>dScientific Calculation) mit Datentypen wie komplexen Zahlen,Vektoren, Matrizen und Intervallen samt <strong>de</strong>n zugehörigen Operationenergänzt wor<strong>de</strong>n, siehe das Buch von RUDI KLATTE etal.SMALLTALK ist e<strong>in</strong>e von Grund auf neu entwickelte, strengobjektorientierte Sprache 9 , im Gegensatz zu <strong>C++</strong>. JAVA wur<strong>de</strong>von <strong>de</strong>r Firma SUN entwickelt. Hier das Hello-World-Programm<strong>in</strong> JAVA (<strong>in</strong> <strong>C++</strong> lernen wir es <strong>in</strong> Abschnitt 1.62 auf Seite 181kennen):class HelloWorld {public static void ma<strong>in</strong> (Str<strong>in</strong>g args[]) {for (;;) {System.out.pr<strong>in</strong>t("Hello World ");}}}Quelle 1.6 : JAVA-Programm Hello, WorldÄhnlichkeiten zu C s<strong>in</strong>d erkennbar, die JAVA-Entwickler warenvermutlich C-Programmierer.Auf die übrigen 989 Programmiersprachen 10 soll aus Platzgrün<strong>de</strong>nnicht e<strong>in</strong>gegangen wer<strong>de</strong>n. Braucht man überhauptmehrere Sprachen? E<strong>in</strong>ige Sprachen wie FORTRAN und CO-BOL s<strong>in</strong>d historisch bed<strong>in</strong>gt und wer<strong>de</strong>n wegen ihrer weitenVerbreitung noch lange leben. An<strong>de</strong>re Sprachen wie BASIC und9 SMALLTALK ist ungewohnt und sehr <strong>in</strong>teressant,auch für LINUX verfügbar. Näheres siehewww.software.ibm.com/ad/smalltalk/, www.exept.<strong>de</strong>/,www.cetus-l<strong>in</strong>ks.org/oo_smalltalk.htmlo<strong>de</strong>rwww.gsug.org/.10 Real programmers can write FORTRAN programs <strong>in</strong> anylanguage.


18 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>C wen<strong>de</strong>n sich an unterschiedliche Benutzerkreise. Wie<strong>de</strong>ruman<strong>de</strong>re eignen sich für spezielle Aufgaben besser als allgeme<strong>in</strong>eSprachen. Mit e<strong>in</strong>er e<strong>in</strong>zigen Sprache wird man auch <strong>in</strong> <strong>de</strong>rZukunft nicht auskommen. Die Schwierigkeiten beim Programmierenliegen im übrigen weniger <strong>in</strong> <strong>de</strong>r Umsetzung <strong>in</strong> e<strong>in</strong>e Programmiersprache– <strong>de</strong>r Codierung – son<strong>de</strong>rn <strong>in</strong> <strong>de</strong>r Formulierungund Strukturierung <strong>de</strong>r Aufgabe.Was heißt, e<strong>in</strong>e Sprache sei für e<strong>in</strong> System verfügbar? Esgibt e<strong>in</strong>en Interpreter o<strong>de</strong>r Compiler für diese Sprache auf diesemSystem (Hardware plus Betriebssystem). Die BezeichnungFORTRAN-Compiler für UNIX reicht nicht, da es UNIX fürverschie<strong>de</strong>ne Hardware und zu<strong>de</strong>m <strong>in</strong> verschie<strong>de</strong>nen Versionengibt. Drei D<strong>in</strong>ge müssen zusammenpassen: Interpreter o<strong>de</strong>rCompiler, Betriebssystem und Hardware.1.1.6 Interpreter – Compiler – L<strong>in</strong>kerIn höheren Programmiersprachen wie C o<strong>de</strong>r FORTRAN geschriebeneProgramme wer<strong>de</strong>n als Quellco<strong>de</strong> (source co<strong>de</strong>),Quellprogramm o<strong>de</strong>r Quelltext bezeichnet. Mit diesem Quellco<strong>de</strong>kann <strong>de</strong>r Computer unmittelbar nichts anfangen, er ist nichtausführbar. Der Quellco<strong>de</strong> muss mithilfe <strong>de</strong>s Computers un<strong>de</strong><strong>in</strong>es Übersetzungsprogrammes <strong>in</strong> Masch<strong>in</strong>enco<strong>de</strong> übersetztwer<strong>de</strong>n. Mit <strong>de</strong>m Masch<strong>in</strong>enco<strong>de</strong> kann dann <strong>de</strong>r Programmierernichts mehr anfangen.Es gibt zwei Arten von Übersetzern. Interpreter übersetzendas Programm je<strong>de</strong>smal, wenn es aufgerufen wird. Die Übersetzungwird nicht auf Dauer gespeichert. Da <strong>de</strong>r Quellco<strong>de</strong> zeilenweisebearbeitet wird, lassen sich Än<strong>de</strong>rungen schnell und e<strong>in</strong>fachausprobieren. An<strong>de</strong>rerseits kostet die Übersetzung Zeit. Interpreterf<strong>in</strong><strong>de</strong>t man vorwiegend auf Home-Computern für BA-SIC, aber auch LISP-Programme, Shellscripts und awk-Scriptswer<strong>de</strong>n <strong>in</strong>terpretiert.Compiler übersetzen <strong>de</strong>n Quellco<strong>de</strong> e<strong>in</strong>es Programms alsGanzes und speichern die Übersetzung auf e<strong>in</strong>em permanentenMedium. Zur Ausführung <strong>de</strong>s Programms wird die Übersetzungaufgerufen. Bei <strong>de</strong>r kle<strong>in</strong>sten Än<strong>de</strong>rung muss das gesamte Programmerneut kompiliert wer<strong>de</strong>n, dafür entfällt die je<strong>de</strong>smaligeÜbersetzung während <strong>de</strong>r Ausführung. Compilierte Programmelaufen also schneller ab als <strong>in</strong>terpretierte. Es gibt auch Misch-


1.1. GRUNDBEGRIFFE 19formen von Interpretern und Compilern, zum Beispiel für JAVA.Wie wir e<strong>in</strong>gangs <strong>de</strong>s Kapitels gesehen haben, arbeiten C- und<strong>C++</strong>-Compiler wie cc(1) und CC(1) <strong>in</strong> vier Durchgängen:• Präprozessor• eigentlicher Compiler (Übersetzung <strong>in</strong> Assembler-Co<strong>de</strong>)• Assembler (Übersetzung <strong>in</strong> Masch<strong>in</strong>en-Co<strong>de</strong>)• L<strong>in</strong>kerDer Präprozessor entfernt Kommentar und führt diePräprozessor-Anweisungen (siehe Abschnitt 1.9 Präprozessorauf Seite 213) aus. Ruft man <strong>de</strong>n Compiler mit <strong>de</strong>r Option-P auf, so erhält man die Ausgabe <strong>de</strong>s Präprozessors <strong>in</strong> e<strong>in</strong>erlesbaren Datei mit <strong>de</strong>r Kennung .i.Der eigentliche Compiler ccom(1) übersetzt <strong>de</strong>n Quellco<strong>de</strong><strong>in</strong> masch<strong>in</strong>enspezifischen, lesbaren Assemblerco<strong>de</strong>. Die Compileroption-S liefert diesen Co<strong>de</strong> <strong>in</strong> e<strong>in</strong>er Datei mit <strong>de</strong>r Kennung.s. Bei e<strong>in</strong>em e<strong>in</strong>fachen Programm sollte man sich e<strong>in</strong>maldas Vergnügen gönnen und <strong>de</strong>n Assemblerco<strong>de</strong> anschauen.Der Assembler ist e<strong>in</strong> zweiter Übersetzer, <strong>de</strong>r Assemblerco<strong>de</strong><strong>in</strong> Masch<strong>in</strong>ensprache übersetzt. Mit <strong>de</strong>r Compileroption -cerhält man <strong>de</strong>n Masch<strong>in</strong>enco<strong>de</strong> (Objektco<strong>de</strong>, relocatable co<strong>de</strong>) <strong>in</strong>e<strong>in</strong>er nicht lesbaren Datei mit <strong>de</strong>r Kennung .o.Große Programme wer<strong>de</strong>n <strong>in</strong> mehrere Dateien aufgeteilt, diee<strong>in</strong>zeln kompiliert wer<strong>de</strong>n, aber nicht e<strong>in</strong>zeln ausführbar s<strong>in</strong>d,weil erst das Programm als Ganzes e<strong>in</strong>en S<strong>in</strong>n ergibt. Das Verb<strong>in</strong><strong>de</strong>n<strong>de</strong>r e<strong>in</strong>zeln kompilierten Dateien zu e<strong>in</strong>em ausführbarenProgramm besorgt <strong>de</strong>r B<strong>in</strong><strong>de</strong>r o<strong>de</strong>r L<strong>in</strong>ker. Die Compileroption-c unterdrückt das L<strong>in</strong>ken und erzeugt e<strong>in</strong>e nicht lesbare Dateimit <strong>de</strong>r Kennung .o.Unter UNIX wer<strong>de</strong>n üblicherweise Präprozessor, Compiler,Assembler und L<strong>in</strong>ker von e<strong>in</strong>em Compilertreiber aufgerufen,so dass <strong>de</strong>r Benutzer nichts von <strong>de</strong>n vier Schritten bemerkt. Manarbeitet mit <strong>de</strong>m Treiber cc(1), gcc(1) o<strong>de</strong>r CC(1) und erhälte<strong>in</strong> ausführbares Programm. Im Alltag me<strong>in</strong>t man <strong>de</strong>n Treiber,wenn man vom Compiler spricht.Üblicherweise erzeugt e<strong>in</strong> Compiler Masch<strong>in</strong>enco<strong>de</strong> für dieMasch<strong>in</strong>e, auf <strong>de</strong>r er selbst läuft. Cross-Compiler h<strong>in</strong>gegen erzeugenMasch<strong>in</strong>enco<strong>de</strong> für an<strong>de</strong>re Systeme. Das ist gelegentlichnützlich.


20 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Der Name <strong>de</strong>s Programms im C-Quellco<strong>de</strong> hat die Kennung.c, <strong>in</strong> FORTRAN und PASCAL entsprechend .f und .p. Daskompilierte, aber noch nicht gel<strong>in</strong>kte Programm wird als Objektco<strong>de</strong>o<strong>de</strong>r relozierbar (relocatable) bezeichnet, <strong>de</strong>r Date<strong>in</strong>amehat die Kennung .o o<strong>de</strong>r .obj. Das lauffähige Programmheißt ausführbar (executable), se<strong>in</strong> Name hat ke<strong>in</strong>eKennung. Unter PC-DOS s<strong>in</strong>d die Namen ausführbarer Programmedurch .com o<strong>de</strong>r .exe gekennzeichnet. E<strong>in</strong> kompiliertesProgramm wird auch B<strong>in</strong>ary genannt, im Gegensatz zumQuelltext. E<strong>in</strong> Programm ist b<strong>in</strong>är-kompatibel zu e<strong>in</strong>em an<strong>de</strong>renSystem, wenn es <strong>in</strong> se<strong>in</strong>er ausführbaren Form unter bei<strong>de</strong>nläuft.Hat sich e<strong>in</strong> Programm anstandslos kompilieren lassen un<strong>de</strong>rzeugt beim Aufruf die Fehlermeldung File not found, dannliegt das fast immer daran, dass das Arbeitsverzeichnis nicht imBefehlspfad enthalten ist. Man ruft dann das neue Programmmit e<strong>in</strong>em Punkt als Pfadangabe auf:./myprogramund veranlasst so die Shell, das Programm im Arbeitsverzeichniszu suchen. Alternativ könnte man auch <strong>de</strong>n Punkt <strong>in</strong> <strong>de</strong>nPfad aufnehmen.Bei <strong>de</strong>n Operan<strong>de</strong>n spielt es e<strong>in</strong>e Rolle, ob ihre Eigenschaftenvom Übersetzer bestimmt wer<strong>de</strong>n o<strong>de</strong>r von Programm undÜbersetzer geme<strong>in</strong>sam – zur Übersetzungszeit – o<strong>de</strong>r während<strong>de</strong>r Ausführung <strong>de</strong>s Programmes – zur Laufzeit. Der zweite Wegwird als statische B<strong>in</strong>dung bezeichnet, <strong>de</strong>r dritte als dynamischeB<strong>in</strong>dung. Die Größe e<strong>in</strong>er Ganzzahl (2 Bytes, 4 Bytes) istdurch <strong>de</strong>n Compiler gegeben. Die Größe e<strong>in</strong>es Arrays könnte imProgramm festgelegt se<strong>in</strong> o<strong>de</strong>r während <strong>de</strong>r Ausführung berechnetwer<strong>de</strong>n. Es ist auch <strong>de</strong>nkbar, aber <strong>in</strong> C nicht zugelassen, <strong>de</strong>nTyp e<strong>in</strong>er Variablen erst bei <strong>de</strong>r Ausführung je nach Bedarf zubestimmen.E<strong>in</strong>en Weg zurück vom ausführbaren Programm zum Quellco<strong>de</strong>gibt es nicht. Das Äußerste ist, mit e<strong>in</strong>em Disassembleraus <strong>de</strong>m ausführbaren Co<strong>de</strong> Assemblerco<strong>de</strong> zu erzeugen, ohneKommentar und typografische Struktur. Nur bei kurzen, e<strong>in</strong>fachenProgrammen ist dieser Assemblerco<strong>de</strong> verständlich.


1.1. GRUNDBEGRIFFE 211.1.7 Qualität und StilUnser Ziel ist e<strong>in</strong> gutes Programm. Was heißt das im e<strong>in</strong>zelnen?E<strong>in</strong> Programm soll selbstverständlich fehlerfrei se<strong>in</strong> <strong>in</strong><strong>de</strong>m S<strong>in</strong>n, dass es aus zulässigen E<strong>in</strong>gaben richtige Ergebnisseerzeugt. Außer <strong>in</strong> seltenen Fällen lässt sich die so <strong>de</strong>f<strong>in</strong>ierteFehlerfreiheit e<strong>in</strong>es Programms nicht beweisen. Man kann nur– nach e<strong>in</strong>er Vielzahl von Tests und längerem Gebrauch – davonre<strong>de</strong>n, dass e<strong>in</strong> Programm zuverlässig ist, e<strong>in</strong> falsches Ergebnisalso nur mit ger<strong>in</strong>ger Wahrsche<strong>in</strong>lichkeit auftritt.E<strong>in</strong> Programm soll robust se<strong>in</strong>, das heißt auf Fehler <strong>de</strong>r E<strong>in</strong>gabeo<strong>de</strong>r <strong>de</strong>r Peripherie vernünftig reagieren, nicht mit e<strong>in</strong>emAbsturz. Das Schlimmste ist, wenn e<strong>in</strong> Programm trotz e<strong>in</strong>esFehlers e<strong>in</strong> sche<strong>in</strong>bar richtiges Ergebnis ausgibt. Die Fehlerbehandlungmacht oft <strong>de</strong>n größeren Teil e<strong>in</strong>es Programmes ausund wird häufig vernachlässigt. Die Sprache C erleichtert dieseAufgabe.E<strong>in</strong> Programm ist niemals fertig und soll daher leicht zuän<strong>de</strong>rn se<strong>in</strong>. Die Ent<strong>de</strong>ckung von Fehlern, die Berücksichtigungneuer Wünsche, die Entwicklung <strong>de</strong>r Hardware, Bestrebungenzur Standardisierung und Lernvorgänge <strong>de</strong>r Programmiererführen dazu, dass Programme immer wie<strong>de</strong>r überarbeitetwer<strong>de</strong>n. Kle<strong>in</strong>ere Korrekturen wer<strong>de</strong>n durch Patches behoben,wörtlich Flicken. Das s<strong>in</strong>d Ergänzungen zum Co<strong>de</strong>, dienicht gleich e<strong>in</strong>e neue Version rechtfertigen. Für manche Fehlerlassen sich auch ohne Än<strong>de</strong>rung <strong>de</strong>s Co<strong>de</strong>s Umgehungen f<strong>in</strong><strong>de</strong>n,sogenannte Workarounds. Nach umfangreichen Än<strong>de</strong>rungen– möglichst Verbesserungen – ersche<strong>in</strong>t e<strong>in</strong>e neue Version<strong>de</strong>s Programmes. E<strong>in</strong> Programm, von <strong>de</strong>m nicht e<strong>in</strong>mal jährliche<strong>in</strong>e Überarbeitung ersche<strong>in</strong>t, ist tot. Je<strong>de</strong> Woche e<strong>in</strong>e neueVersion ist natürlich auch ke<strong>in</strong>e Empfehlung. Leichte Än<strong>de</strong>rbarkeitberuht auf Übersichtlichkeit, ausführlicher Dokumentationund Vermeidung von Hardwareabhängigkeiten. Die Übersichtlichkeitwie<strong>de</strong>rum erreicht man durch e<strong>in</strong>e zweckmäßige Strukturierung,verständliche Namenswahl und Verzicht auf beson<strong>de</strong>reTricks e<strong>in</strong>er Programmiersprache, die zwar erlaubt, abernicht allgeme<strong>in</strong> bekannt s<strong>in</strong>d. Gera<strong>de</strong> C erlaubt viel, was nichtzur Übersichtlichkeit beiträgt.Än<strong>de</strong>rungen zu erleichtern kann auch heißen, Än<strong>de</strong>rungen


22 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>von vornhere<strong>in</strong> zu vermei<strong>de</strong>n, <strong>in</strong><strong>de</strong>m man die Programmteile soallgeme<strong>in</strong> wie mit <strong>de</strong>m Aufwand vere<strong>in</strong>bar gestaltet.Effizienz ist immer gefragt. Früher be<strong>de</strong>utete das vor allemsparsamer Umgang mit <strong>de</strong>m Arbeitsspeicher. Das ist heute immernoch e<strong>in</strong>e Tugend, tritt aber h<strong>in</strong>ter <strong>de</strong>n vorgenannten Kriterienzurück. Die mo<strong>de</strong>rne Software sche<strong>in</strong>t zur Unterstützung<strong>de</strong>r Chiphersteller geschrieben zu wer<strong>de</strong>n. An zweiter Stelle kamAusführungsgeschw<strong>in</strong>digkeit, trotz aller Geschw<strong>in</strong>digkeitssteigerungen<strong>de</strong>r Hardware ebenfalls noch e<strong>in</strong>e Tugend, wenn siemit E<strong>in</strong>fachheit und Übersichtlichkeit e<strong>in</strong>hergeht. Mit an<strong>de</strong>renWorten: erst e<strong>in</strong> übersichtliches Programm schreiben und dannnach<strong>de</strong>nken, ob man Speicher und Zeit e<strong>in</strong>sparen kann.E<strong>in</strong> Programm soll benutzerfreundlich se<strong>in</strong>. Der Benutzeram Term<strong>in</strong>al will bei alltäglichen Aufgaben ohne das Studiumpfundschwerer Handbücher auskommen und bei <strong>de</strong>n häufigstenFehlern Hilfe vom Bildschirm erhalten. Er will an<strong>de</strong>rerseitsauch nicht mit überflüssigen Informationen und nutzlosen Spielereienbelästigt wer<strong>de</strong>n. Der Schwerpunkt <strong>de</strong>r Programmentwicklungliegt heute weniger bei <strong>de</strong>n Algorithmen, son<strong>de</strong>rn bei<strong>de</strong>r Interaktion mit <strong>de</strong>m Benutzer. Für e<strong>in</strong>en Programmierer istes nicht immer e<strong>in</strong>fach, sich <strong>in</strong> die Rolle e<strong>in</strong>es EDV-Laien zu versetzen.Schließlich ist daran zu <strong>de</strong>nken, dass man e<strong>in</strong> Programmnicht nur für <strong>de</strong>n Computer schreibt, son<strong>de</strong>rn auch für an<strong>de</strong>reProgrammierer. Erstens kommt es oft vor, dass e<strong>in</strong> Programmvon an<strong>de</strong>ren weiterentwickelt o<strong>de</strong>r ergänzt wird; zweitens ist e<strong>in</strong>Programm e<strong>in</strong>e von mehreren Möglichkeiten, e<strong>in</strong>en Algorithmuso<strong>de</strong>r e<strong>in</strong>en komplexen Zusammenhang darzustellen. Der Quellco<strong>de</strong>sollte daher leicht zu lesen, programmiererfreundlichse<strong>in</strong>. For<strong>de</strong>rn wir also menschenfreundliche Programme.C lässt <strong>de</strong>m Programmierer viel Freiheit, mehr als PASCAL.Damit nun nicht je<strong>de</strong>r schreibt, wie ihm <strong>de</strong>r Schnabel gewachsenist, hat die Programmierergeme<strong>in</strong>schaft Regeln und Gebräucheentwickelt. E<strong>in</strong> Verstoß dagegen bee<strong>in</strong>druckt <strong>de</strong>n Compilernicht, aber das Programm ist mühsam zu lesen. Der Beautifiercb(1) automatisiert die E<strong>in</strong>haltung e<strong>in</strong>iger dieser Regeln, weitergehen<strong>de</strong>f<strong>in</strong><strong>de</strong>n sich <strong>in</strong>:• NELSON FORD, Programmer’s Gui<strong>de</strong>, siehe Anhang,


1.1. GRUNDBEGRIFFE 23• B. W. KERNIGHAN, P. J. PLAUGER, Software Tools, sieheAnhang,• ROB PIKE, Notes on Programm<strong>in</strong>g<strong>in</strong> C, /pub/../pikestyle.ps aufftp.ciw.uni-karlsruhe.<strong>de</strong>• Firmen-Richtl<strong>in</strong>ien wie Nixdorf Computer C-Programmierrichtl<strong>in</strong>ien (Hausstandard), 1985• K. HENNING, Portables Programmieren <strong>in</strong> C – Programmierrichtl<strong>in</strong>ien,verfasst 1993 vom HochschuldidaktischenZentrum und vom Fachgebiet Kybernetische Verfahren undDidaktik <strong>de</strong>r Ingenieurwissenschaften <strong>de</strong>r RWTH Aachenim Auftrag von sechs Chemiefirmen. Der Verbreitung dieserRichtl<strong>in</strong>ien stehen lei<strong>de</strong>r e<strong>in</strong> H<strong>in</strong>weis auf das Urheberrechtsowie e<strong>in</strong> ausdrückliches Kopierverbot entgegen.E<strong>in</strong>- und dieselbe Aufgabe kann – von e<strong>in</strong>fachen Fällen abgesehen– auf verschie<strong>de</strong>ne Weisen gelöst wer<strong>de</strong>n. Der e<strong>in</strong>e bevorzugtviele kle<strong>in</strong>e Programmblöcke, <strong>de</strong>r an<strong>de</strong>re wenige große.E<strong>in</strong>er arbeitet gern mit Menüs, e<strong>in</strong> an<strong>de</strong>rer lieber mit Kommandozeilen.E<strong>in</strong>er schreibt e<strong>in</strong>en langen Kommentar an <strong>de</strong>n Programmanfang,e<strong>in</strong> an<strong>de</strong>rer zieht kurze, <strong>in</strong> <strong>de</strong>n Programmco<strong>de</strong>e<strong>in</strong>gestreute Kommentare vor. Solange die genannten objektivenZiele erreicht wer<strong>de</strong>n, ist gegen e<strong>in</strong>en persönlichen Stil nichtse<strong>in</strong>zuwen<strong>de</strong>n. Le style c’est l’homme.1.1.8 ProgrammiertechnikBei kurzen Programmen, wie sie <strong>in</strong> diesem Buch überwiegen,setzt man sich oft gleich an das Term<strong>in</strong>al und legt los. Beson<strong>de</strong>rsjugendliche BASIC-Programmierer neigen zu dieser Programmiertechnik.Wenn man sich das nicht schnellstens abgewöhnt,kommt man nicht weit. Um wirkliche Programme zuschreiben, muss man systematisch vorgehen und viel Konzeptpapierverbrauchen, ehe es ans Hacken geht. Es gibt mehrereVorgehensweisen. E<strong>in</strong>e verbreitete sieht fünf Stufen vor (waterfallapproach):• Aufgabenstellung (Vorstudien, Analyse, Formulierung),• Entwurf (Struktur, Anpassen an Werkzeuge wie make(1),RCS, CVS),


24 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>• Umsetzung <strong>in</strong> e<strong>in</strong>e Programmiersprache (Codierung, Implementation),• Test (Fehlersuche, Prüfungen, Messungen, Vergleich mitPunkt 1),• Betrieb und Pflege (Wartung, Updat<strong>in</strong>g, Fehler-Management).Die Programmiersprache, die für <strong>de</strong>n Anfänger im Vor<strong>de</strong>rgrund<strong>de</strong>s Programmierens steht, kommt erst an dritter Stelle. Wenndie bei<strong>de</strong>n vorangehen<strong>de</strong>n Punkte schlecht erledigt wor<strong>de</strong>n s<strong>in</strong>d,kann auch e<strong>in</strong> Meister <strong>in</strong> C/<strong>C++</strong> nichts mehr retten.Der Zeitbedarf <strong>de</strong>r e<strong>in</strong>zelnen Stufen ist schwierig abzuschätzen,da Kle<strong>in</strong>igkeiten manchmal fürchterlich aufhalten. Lassenwir Betrieb und Pflege als zeitlich unbegrenzt heraus, und nehmenwir an, dass das Schreiben <strong>de</strong>r Dokumentation parallel erfolgt,so lassen sich ungefähr folgen<strong>de</strong> Anteile als Ausgangswertefür e<strong>in</strong>e Zeitplanung nehmen:• Aufgabenanalyse 20 %,• Entwurf 30 %,• Codierung 20 %,• Test 30 %.Wer Softwareprojekte zu se<strong>in</strong>em Broterwerb macht, sollte e<strong>in</strong>Tagebuch o<strong>de</strong>r Protokoll führen, um Erfahrungen auf <strong>de</strong>m Papierfestzuhalten und sie beim nächsten Projekt zu verwerten.Bei <strong>de</strong>r Codierung rechnet man mit 60 Zeilen Programmco<strong>de</strong>(ohne Kommentar und Leerzeilen) pro Tag und Programmierer.Das s<strong>in</strong>d zwei bis drei Seiten DIN A4 mit Kommentar und Leerzeilen.Gleichzeitig ist das die Obergrenze für e<strong>in</strong> Programmmodul(<strong>in</strong> C e<strong>in</strong>e Funktion). Haben Sie für ihr Projekt 100 ArbeitstageZeit und e<strong>in</strong>en Programmierer, so ergeben sich 20 Arbeitstageür die Codierung gleich 20 Modulen zu je 60 Zeilen Co<strong>de</strong>. Dass<strong>in</strong>d grobe Werte, aber sie reichen für e<strong>in</strong>e erste Abschätzungaus.Bei Texten kann man von e<strong>in</strong>er Seite pro Tag ausgehen. Liegtdas Rohmaterial samt allen Abbildungen fertig vor, kommt manauch auf zehn Seiten pro Tag. Umgekehrt können schwierigeRechnungen o<strong>de</strong>r das Beschaffen exotischer Literatur e<strong>in</strong> Manuskriptbeliebig verzögern. Korrekturlesen, das Zusammenstellen


1.1. GRUNDBEGRIFFE 25e<strong>in</strong>es In<strong>de</strong>x und ähnliche ungeliebte Arbeiten kosten auch Zeit,unter Umstän<strong>de</strong>n Wochen.Die Programmentwicklung vollzieht sich <strong>in</strong> <strong>de</strong>r Praxis nichtso geradl<strong>in</strong>ig, wie es <strong>de</strong>r obige Plan vermuten lässt. Aus je<strong>de</strong>rStufe kommen Rücksprünge <strong>in</strong> vorangegangene Stufen vor,man könnte auch von Rückkoppelungen sprechen. Dagegen istnichts e<strong>in</strong>zuwen<strong>de</strong>n, es besteht jedoch e<strong>in</strong>e Gefahr. Wenn mannicht Zwangsmaßnahmen ergreift – Schlussstriche zieht – erreichtdas Programmierprojekt nie e<strong>in</strong>en <strong>de</strong>f<strong>in</strong>ierten Zustand.Programmierer verstehen das, Kaufleute und Kun<strong>de</strong>n nicht. Giltauch für Buchmanuskripte.Der steigen<strong>de</strong> Bedarf an Software und ihre wachsen<strong>de</strong> Komplexitätverlangen die Entwicklung von Programmierverfahren,mit <strong>de</strong>nen durchschnittliche Programmierer zuverlässige Programmeentwickeln. Auf geniale Real Programmers alle<strong>in</strong> kannsich ke<strong>in</strong>e Firma verlassen. Die Entwicklung dieser Programmiertechnik(Software Eng<strong>in</strong>eer<strong>in</strong>g) ist noch nicht abgeschlossen.1.1.9 Aufgabenanalyse und Entwurf1.1.9.1 AufgabenstellungDie meisten Programmieraufgaben wer<strong>de</strong>n verbal gestellt, nicht<strong>in</strong> Form e<strong>in</strong>er mathematischen Gleichung. Zu<strong>de</strong>m s<strong>in</strong>d sie anfangsoft pauschal abgefasst, da <strong>de</strong>m Aufgabensteller 11 E<strong>in</strong>zelheitennoch nicht klar s<strong>in</strong>d.Auf <strong>de</strong>r an<strong>de</strong>ren Seite benötigt <strong>de</strong>r Computer e<strong>in</strong>e e<strong>in</strong><strong>de</strong>utige,<strong>in</strong>s e<strong>in</strong>zelne gehen<strong>de</strong> Anweisung, da er – an<strong>de</strong>rs als e<strong>in</strong> Mensch– fehlen<strong>de</strong> Informationen nicht aufgrund se<strong>in</strong>er Erfahrung und<strong>de</strong>s gesun<strong>de</strong>n Menschenverstan<strong>de</strong>s ergänzt.Der erste Schritt bei <strong>de</strong>r Programmentwicklung ist daher dieFormulierung <strong>de</strong>r Aufgabe. Zu diesem Schritt kehrt man imVerlauf <strong>de</strong>s Programmierens immer wie<strong>de</strong>r zurück, um zu ergänzeno<strong>de</strong>r zu berichtigen. Es ist realistisch, für die Aufgabenanalyserund e<strong>in</strong> Drittel <strong>de</strong>s gesamten Zeitaufwan<strong>de</strong>s anzusetzen.Die Aufgabe wird <strong>in</strong> e<strong>in</strong>em Pflichtenheft schriftlich festgehalten,das zur Verständigung zwischen Entwickler und Anwen<strong>de</strong>r11 Real programmers know better than the users what theyneed.


26 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>sowie <strong>de</strong>r Entwickler untere<strong>in</strong>an<strong>de</strong>r dient. Fragen <strong>in</strong> diesem Zusammenhangs<strong>in</strong>d:• Welche Ergebnisse soll das Programm liefern?• Welche E<strong>in</strong>gaben s<strong>in</strong>d erfor<strong>de</strong>rlich?• Welche Ausnahmefälle (Fehler) s<strong>in</strong>d zu berücksichtigen?• In welcher Form sollen die Ergebnisse ausgegeben wer<strong>de</strong>n?• Wer soll mit <strong>de</strong>m Programm umgehen?• Auf welchen Computern soll das Programm laufen?Anfänger sehen die Schwierigkeiten <strong>de</strong>s Programmierens <strong>in</strong> <strong>de</strong>rUmsetzung <strong>de</strong>s Lösungsweges <strong>in</strong> e<strong>in</strong>e Programmiersprache, <strong>in</strong><strong>de</strong>r Codierung. Nach e<strong>in</strong>igem Üben stellt sich dann heraus, dassdie dauerhaften Schwierigkeiten <strong>in</strong> <strong>de</strong>r Formulierung und Analyse<strong>de</strong>r Aufgabe, allenfalls noch im Suchen nach Lösungen liegen,während die Codierung größtenteils Rout<strong>in</strong>e wird.Nach unserer Erfahrung sollte man e<strong>in</strong>e Aufgabe zunächste<strong>in</strong>mal so formulieren, wie sie <strong>de</strong>n augenblicklichen Bedürfnissenentspricht. Dann sollte man sich mit viel Phantasie ausmalen,was alles noch dazu kommen könnte, wenn Geld, Zeit undVerstand ke<strong>in</strong>e Schranken setzen wür<strong>de</strong>n (I have a dream ... ).Drittens streiche man von diesem Traum gna<strong>de</strong>nlos alles weg,was nicht unbed<strong>in</strong>gt erfor<strong>de</strong>rlich und absolut m<strong>in</strong>imal notwendigist – ohne das vielleicht nur asymptotisch erreichbare Zielaus <strong>de</strong>n Augen zu verlieren. So kommt man mit beschränktenMitteln zu Software, die sich entwickeln kann, wenn die Zeit dafürreif ist. Anpassungsfähigkeit ist für Software und Lebewesenwichtiger als Höchstleistungen.1.1.9.2 Zerlegen <strong>in</strong> TeilaufgabenControll<strong>in</strong>g complexity is the essence of computer programm<strong>in</strong>g(B. W. KERNIGHAN, P. J. PLAUGER, Software Tools). KomplexeAufgaben wer<strong>de</strong>n <strong>in</strong> mehreren Stufen <strong>in</strong> Teilaufgaben zerlegt,die überschaubar s<strong>in</strong>d und sich durch e<strong>in</strong>e Funktion o<strong>de</strong>rProzedur im Programm lösen lassen. Insofern spiegelt die Zerlegungbereits die spätere Programmstruktur 12 wi<strong>de</strong>r. DasHauptprogramm soll möglichst wenig selbst erledigen, son<strong>de</strong>rn12 Real programmers disda<strong>in</strong> structured programm<strong>in</strong>g.


1.1. GRUNDBEGRIFFE 27nur Aufrufe von Unterprogrammen enthalten und somit diegroße Struktur wi<strong>de</strong>rspiegeln. Oft ist folgen<strong>de</strong> Glie<strong>de</strong>rung e<strong>in</strong>zweckmäßiger Ausgangspunkt:• Programmstart (Initialisierungen)• E<strong>in</strong>gabe, Dialog• Rechnung• Ausgabe• Hilfen• Fehlerbehandlung• Programmen<strong>de</strong>, AufräumenBei <strong>de</strong>n Teilaufgaben ist zu fragen, ob sie sich – ohne die Komplexitätwesentlich zu erhöhen – allgeme<strong>in</strong>er formulieren lassen.Damit lässt sich die Verwendbarkeit von Programmteilen verbessern.Diese Strategie wird als Top-down-Entwurf bezeichnet.Man geht vom Allgeme<strong>in</strong>en <strong>in</strong>s E<strong>in</strong>zelne.1.1.9.3 Zusammensetzen aus TeilaufgabenDer umgekehrte Weg – Bottom-up-Entwurf – liegt nicht sonahe. Es gibt wie<strong>de</strong>rkehren<strong>de</strong> Grund-Operationen wie Suchen,Sortieren, Fragen, Ausgeben, Interpolieren, Zeichnen e<strong>in</strong>esKreisbogens. Aus diesen lässt sich e<strong>in</strong>e gegebene Aufgabe zue<strong>in</strong>em großen Teil zusammensetzen, so dass nur wenige spezielleTeilaufgaben übrig bleiben. Hat man die Grundoperationene<strong>in</strong>mal programmiert, so vere<strong>in</strong>facht sich <strong>de</strong>r Rest erheblich.In praxi wen<strong>de</strong>t man e<strong>in</strong>e gemischte Strategie an. Man zerlegtdie übergeordnete Aufgabe <strong>in</strong> Teilaufgaben, versucht diese<strong>in</strong> Grundoperationen auszudrücken und kommt dann wie<strong>de</strong>raufsteigend zu e<strong>in</strong>er genaueren und allgeme<strong>in</strong>er gültigen Formulierung.Dieser Ab- und Aufstieg kann sich mehrmals wie<strong>de</strong>rholen.Die Aufgabenstellung ist nicht unverän<strong>de</strong>rlich. Genau sogeht man bei <strong>de</strong>r Planung von Industrieanlagen vor.Man darf nicht <strong>de</strong>n Fehler machen, die Aufgabe aus Bequemlichkeit<strong>de</strong>n Eigenheiten e<strong>in</strong>es Computers o<strong>de</strong>r e<strong>in</strong>er Programmierspracheanzupassen. Der Benutzer hat Anspruch auf e<strong>in</strong>gut und verständlich funktionieren<strong>de</strong>s Programm. Die Zeiten,als <strong>de</strong>r Computer als Entschuldigung für alle möglichen Unzulänglichkeitenherhalten musste, s<strong>in</strong>d vorbei.


28 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.1.10 Prototyp<strong>in</strong>gIn <strong>de</strong>m häufig vorkommen<strong>de</strong>n Fall, dass die Anfor<strong>de</strong>rungen andas Programm zu Beg<strong>in</strong>n noch verschwommen s<strong>in</strong>d, ist es zweckmäßig,möglichst rasch e<strong>in</strong> lauffähiges Grundgerüst, e<strong>in</strong> Skelettzu haben. Mit diesem kann man dann spielen und Erfahrungensammeln <strong>in</strong> e<strong>in</strong>em Stadium, <strong>in</strong> <strong>de</strong>m <strong>de</strong>r Programmco<strong>de</strong> nochüberschaubar und leicht zu än<strong>de</strong>rn ist.Bei e<strong>in</strong>em solchen Prototyp s<strong>in</strong>d nur die benutzernahenFunktionen halbwegs ausgebaut, die datennahen Funktionenschreiben vorläufig nur ihren Namen auf <strong>de</strong>n Bildschirm. Vone<strong>in</strong>em menugesteuerten Vokabeltra<strong>in</strong>er beispielsweise schreibtman zunächst das Menusystem und lässt die Funktionen, diedie eigentliche Arbeit erledigen, leer o<strong>de</strong>r beschränkt sie auf dieAusgabe ihres Namens. Damit liegt die Programmstruktur –das Knochengerüst – fest. Gleichzeitig macht man sich Gedankenüber die Datenstruktur. Steht <strong>de</strong>r Prototyp, nimmt man<strong>de</strong>n Datenaustausch zwischen <strong>de</strong>n Funktionen h<strong>in</strong>zu (Parameterübergabeund -rückgabe), immer noch mit Bildschirmmeldungenanstelle <strong>de</strong>r eigentlichen Arbeit. Funktioniert auch das wiegewünscht, füllt man e<strong>in</strong>e Funktion nach <strong>de</strong>r an<strong>de</strong>ren mit Co<strong>de</strong>.Diese Vorgehensweise lenkt die Entwicklung zu e<strong>in</strong>em möglichstfrühen Zeitpunkt <strong>in</strong> die gewünschte Richtung. Bei e<strong>in</strong>emkommerziellen Auftrag bezieht sie <strong>de</strong>n Auftraggeber <strong>in</strong> die Entwicklunge<strong>in</strong> und för<strong>de</strong>rt das gegenseitige Verständnis, aberauch bei privaten Projekten verh<strong>in</strong><strong>de</strong>rt sie, dass man viel Co<strong>de</strong>für /<strong>de</strong>v/null schreibt.Das Prototyp<strong>in</strong>g ist sicher nicht für alle Programmieraufgabendas beste Mo<strong>de</strong>ll – es gibt auch noch an<strong>de</strong>re Mo<strong>de</strong>lle– aber für dialog<strong>in</strong>tensive kle<strong>in</strong>e und mittlerer Anwendungenrecht brauchbar und <strong>in</strong> C leicht zu verwirklichen.1.1.11 FlussdiagrammeProgramme wer<strong>de</strong>n schnell unübersichtlich. Man hat daherschon früh versucht, mit Hilfe grafischer Darstellungen 13 <strong>de</strong>nÜberblick zu behalten, aber auch diese neigen zum Wuchern. E<strong>in</strong>grundsätzlicher Mangel ist die Beschränkung e<strong>in</strong>es Blattes Papierauf zwei Dimensionen. Es ist unmöglich, e<strong>in</strong> umfangreiches13 Real programmers don’t draw flowcharts.


1.1. GRUNDBEGRIFFE 29true✑◗✑ ◗◗◗◗✑✑✑◗ Bed<strong>in</strong>gung ✑◗◗◗◗ ✑✑✑✑falseAnweisung 1Anweisung 2 Anweisung 4Anweisung 3Abb. 1.1: Flussdiagramm e<strong>in</strong>er if-else-VerzweigungProgramm durch e<strong>in</strong>e e<strong>in</strong>zige halbwegs überschaubare Grafik zubeschreiben.Flussdiagramme (flow chart), auch Blockdiagramme genannt,sollen die Abläufe <strong>in</strong>nerhalb e<strong>in</strong>es Programmes durchS<strong>in</strong>nbil<strong>de</strong>r nach DIN 66 001 und Text darstellen, unabhängigvon e<strong>in</strong>er Programmiersprache. Obwohl das Flussdiagramm vor<strong>de</strong>m Programmco<strong>de</strong> erstellt wer<strong>de</strong>n sollte, halten sich viele Programmierernicht an diese Reihenfolge. Zum Teil ersetzt e<strong>in</strong>e gutetypografische Gestaltung <strong>de</strong>r Programmquelle auch e<strong>in</strong> Flussdiagramm,während das Umgekehrte nicht gilt. E<strong>in</strong> Flussdiagrammist nicht mit e<strong>in</strong>em Syntaxdiagramm zu verwechseln, lesenSie die bei<strong>de</strong>n entsprechen<strong>de</strong>n Abbildungen, die die if-else-Verzweigung darstellen, e<strong>in</strong>mal laut vor.Nassi-Shnei<strong>de</strong>rman-Diagramme o<strong>de</strong>r Struktogrammenach ISAAC NASSI und BEN SHNEIDERMAN s<strong>in</strong>d e<strong>in</strong> weitererVersuch, <strong>de</strong>n Programmablauf grafisch darzustellen. Sie s<strong>in</strong>dnäher an e<strong>in</strong>e Programmiersprache angelehnt, so dass es leichtfällt, nach <strong>de</strong>m Diagramm e<strong>in</strong>e Quelle zu schreiben. Das lässtsich teilweise sogar mit CASE-Werkzeugen <strong>in</strong> bei<strong>de</strong> Richtungenautomatisieren.


30 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>❛ ❛❛❛❛❛❛❛❛❛❛❛❛❛❛❛❛thenif Bed<strong>in</strong>gungelse✦✦ ✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦Anweisung 1Anweisung 2Anweisung 4Anweisung 3Abb. 1.2: Nassi-Shnei<strong>de</strong>rman-Diagramm e<strong>in</strong>er if-else-Verzweigung1.1.12 Memo Grundbegriffe• Masch<strong>in</strong>en verstehen nur Masch<strong>in</strong>ensprache, die hardwareabhängigund für Menschen unverständlich ist.• Programmierer verwen<strong>de</strong>n höhere, an die Aufgaben angepassteProgrammiersprachen, die für Masch<strong>in</strong>en unverständlichs<strong>in</strong>d. Was sie schreiben, wird Quelle (source) genannt.• Übersetzer (Compiler, Interpreter) übersetzen Quelltextehöherer Programmiersprachen <strong>in</strong> Masch<strong>in</strong>ensprache. Derumgekehrte Weg ist praktisch nicht gangbar.• Deklarative Sprachen beschreiben die Aufgabe, prozedurale<strong>de</strong>n Lösungsweg.• Innerhalb <strong>de</strong>r prozeduralen Sprachen gehören BASIC,FORTRAN, PASCAl, COBOL und C zum imperativenZweig, JAVA, SMALLTALK und <strong>C++</strong> zum objektorientierten.• Die Objektorientierung ist e<strong>in</strong> Versuch, mit <strong>de</strong>r wachsen<strong>de</strong>nKomplexität <strong>de</strong>r Programme fertig zu wer<strong>de</strong>n.• Die Herstellung e<strong>in</strong>es Programms beg<strong>in</strong>nt mit e<strong>in</strong>er gründlichenAnalyse <strong>de</strong>r Aufgabe. Die Umsetzung <strong>in</strong> e<strong>in</strong>e Pro-


1.2. PROGRAMMER’S WORKBENCH 31grammiersprache (Codierung) ist dann vergleichsweiseharmlos.• E<strong>in</strong> Programm soll nicht nur die zugrun<strong>de</strong>liegen<strong>de</strong> Aufgaberichtig lösen, son<strong>de</strong>rn auch gegen Fehler und Ausnahmenunempf<strong>in</strong>dlich (robust) se<strong>in</strong>. Die Fehlerbehandlung erfor<strong>de</strong>rtmehr Programmzeilen als die eigentliche Aufgabe.• E<strong>in</strong> Programm soll e<strong>in</strong>fach zu än<strong>de</strong>rn se<strong>in</strong>. Dies wirddurch e<strong>in</strong>e gute Struktur und reichlich Kommentar erleichtert(wenn man schon ke<strong>in</strong>e ausführliche Dokumentationschreibt).• E<strong>in</strong> Programm soll menschenfreundlich se<strong>in</strong>.1.1.13 Übung GrundbegriffeNehmen wir an, <strong>de</strong>r Weg zu Ihrem Arbeitsplatz bestehe aus mehrerenTeilstrecken mit unterschiedlichen Gegebenheiten. Siewollen wissen, was es br<strong>in</strong>gt und kostet, wenn Sie e<strong>in</strong>zelne Teilstreckenschneller o<strong>de</strong>r langsamer zurücklegen.Sie brauchen also e<strong>in</strong> Programm zur Analyse Ihres Arbeitsweges.Formulieren Sie die Aufgabe genauer, zerlegen Sie sie <strong>in</strong>Teilaufgaben, beschreiben Sie die E<strong>in</strong>- und Ausgabe, berücksichtigenSie Fehler <strong>de</strong>s Benutzers. Aus welchen Größen besteht dieAusgabe, welche E<strong>in</strong>gaben s<strong>in</strong>d für die Rechnungen erfor<strong>de</strong>rlich?Kann e<strong>in</strong>e Division durch Null vorkommen? Das Ergebnis solltene<strong>in</strong>ige Blätter Papier mit Worten, Formeln und Skizzen se<strong>in</strong>,nach <strong>de</strong>nen e<strong>in</strong> Programmierer arbeiten könnte. Sie selbst sollenan dieser Stelle noch nicht an e<strong>in</strong>e Programmiersprache <strong>de</strong>nken.Falls Ihnen die Übung zu e<strong>in</strong>fach ersche<strong>in</strong>t, machen Sie dasselbefür e<strong>in</strong>en Vokabeltra<strong>in</strong>er, <strong>de</strong>r außer Deutsch zwei Fremdsprachenbeherrscht. Wortschatz anfangs je 1000 Vokabeln, erweiterbar.Erste Frage: Was gehört alles zu e<strong>in</strong>er Vokabel?1.2 Programmer’s WorkbenchUnter <strong>de</strong>r Werkbank <strong>de</strong>s Programmierers wer<strong>de</strong>n UNIX-Werkzeuge zusammengefaßt, die zum Programmieren benötigtwer<strong>de</strong>n. Auf Masch<strong>in</strong>en, die nicht zur Programmentwicklunge<strong>in</strong>gesetzt wer<strong>de</strong>n, können sie fehlen. Das Werkzeug make(1)


32 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>und die Revisionskontrolle s<strong>in</strong>d auch bei Projekten außerhalb<strong>de</strong>r Programmierung nützlich, vor allem beim Bearbeiten umfangreicherManuskripte.1.2.1 Nochmals die EditorenEditoren wur<strong>de</strong>n bereits im UNIX-Kapitel, Abschnitt ?? Writer’sWorkbench auf Seite ?? erläutert. Hier geht es nur um e<strong>in</strong>ige weitereEigenschaften <strong>de</strong>s Editors vi(1), die beim Schreiben vonProgrammquellen von Belang s<strong>in</strong>d.Im Quellco<strong>de</strong> wer<strong>de</strong>n üblicherweise Schleifenrümpfe und <strong>de</strong>rgleichenum e<strong>in</strong>e Tabulatorbreite e<strong>in</strong>gerückt, die als Default 8Leerzeichen entspricht. Bei geschachtelten Schleifen stößt <strong>de</strong>rText schnell an <strong>de</strong>n rechten Seitenrand. Es empfiehlt sich, <strong>in</strong><strong>de</strong>m entsprechen<strong>de</strong>n Verzeichnis e<strong>in</strong>e Datei .exrc mit <strong>de</strong>n Zeilen:set tabstop=4set showmatchset numberanzulegen. Die Option showmatch veranlaßt <strong>de</strong>n vi(1), bei je<strong>de</strong>rE<strong>in</strong>gabe e<strong>in</strong>er rechten Klammer kurz zur zugehörigen l<strong>in</strong>kenKlammer zu spr<strong>in</strong>gen. Die Option number führt zur Anzeige<strong>de</strong>r Zeilennummern, die jedoch nicht Bestandteil <strong>de</strong>s Texteswer<strong>de</strong>n. E<strong>in</strong>e Zeile set lisp ist e<strong>in</strong>e Hilfe beim E<strong>in</strong>geben vonLISP-Quellen.Steht <strong>de</strong>r Cursor auf e<strong>in</strong>er Klammer, so läßt das Kommando% <strong>de</strong>n Cursor zur Gegenklammer spr<strong>in</strong>gen und dort verbleiben.Auch beim emacs(1) gibt es e<strong>in</strong>ige Wege, das Schreiben vonQuellen zu erleichtern, <strong>in</strong>sbeson<strong>de</strong>re natürlich, falls es um LISPgeht. Der Editor nedit(1) lässt sich auf <strong>de</strong>n Stil aller gängigenProgrammiersprachen e<strong>in</strong>schließlich LaTeX e<strong>in</strong>stellen und ist <strong>in</strong>vielen L<strong>in</strong>ux-Distributionen enthalten.1.2.2 Compiler und L<strong>in</strong>ker (cc, ccom, ld)Auf das Schreiben <strong>de</strong>r Quelltexte mit e<strong>in</strong>em Editor folgt ihreÜbersetzung <strong>in</strong> die Sprache <strong>de</strong>r jeweiligen Masch<strong>in</strong>e mittels e<strong>in</strong>esÜbersetzungsprogrammes, meist e<strong>in</strong>es Compilers. Je<strong>de</strong>s


1.2. PROGRAMMER’S WORKBENCH 33vollständige UNIX-System enthält e<strong>in</strong>en C-Compiler; Compilerfür weitere Programmiersprachen s<strong>in</strong>d optional. Auf unserer Anlages<strong>in</strong>d zusätzlich e<strong>in</strong> FORTRAN- und e<strong>in</strong> PASCAL-Compilervorhan<strong>de</strong>n, wobei von FORTRAN gegenwärtig die Versionen 77und 90 nebene<strong>in</strong>an<strong>de</strong>r laufen.Kompilieren be<strong>de</strong>utete vor <strong>de</strong>r EDV-Zeit zusammentragen.Im alten Rom hatte es auch noch die Be<strong>de</strong>utung von plün<strong>de</strong>rn. Inunseren Herzensergießungen haben wir viel aus Büchern, Zeitschriften,WWW-Seiten und Netnews kompiliert.E<strong>in</strong> Compiler übersetzt <strong>de</strong>n Quellco<strong>de</strong> e<strong>in</strong>es Programmes <strong>in</strong>Masch<strong>in</strong>ensprache. Die meisten Programme enthalten Aufrufevon externen Programmodulen, die bereits vorübersetzt und <strong>in</strong>Bibliotheken zusammengefaßt s<strong>in</strong>d. Beispiele s<strong>in</strong>d Ausgaberout<strong>in</strong>eno<strong>de</strong>r mathematische Funktionen. Der ausführbare Co<strong>de</strong>dieser externen Module wird erst vom L<strong>in</strong>ker 14 mit <strong>de</strong>m Programmco<strong>de</strong>vere<strong>in</strong>igt, so daß e<strong>in</strong> vollständiges ausführbares Programmentsteht. Es gibt die Möglichkeit, die externen Moduleerst zur Laufzeit h<strong>in</strong>zuzunehmen; das heißt dynamisches L<strong>in</strong>kenund spart Speicherplatz. Dabei wer<strong>de</strong>n die Module entwe<strong>de</strong>rbeim La<strong>de</strong>n <strong>de</strong>s Programms <strong>in</strong> <strong>de</strong>n Arbeitsspeicher o<strong>de</strong>r erstbei ihrem Aufruf h<strong>in</strong>zugela<strong>de</strong>n (load on <strong>de</strong>mand). Benutzen mehrereProgramme e<strong>in</strong> <strong>in</strong> <strong>de</strong>n Arbeitsspeicher kopiertes Modul geme<strong>in</strong>samanstatt jeweils e<strong>in</strong>e eigene Kopie anzulegen, so kommtman zu <strong>de</strong>n Shared Libraries und spart nochmals Speicherplatz.Die Aufrufe lauten cc(1), f77(1), f90(1) und pc(1).Diese Kommandos rufen Compilertreiber auf, die ihrerseitsdie eigentlichen Compiler /lib/ccom, f77comp, f90comp undpascomp starten und noch weitere D<strong>in</strong>ge erledigen. OhneOptionen rufen die Compilertreiber auch noch <strong>de</strong>n L<strong>in</strong>ker/b<strong>in</strong>/ld(1) auf, so dass das Ergebnis e<strong>in</strong> lauffähiges Programmist, das als Default <strong>de</strong>n Namen a.out(4) trägt. Mit <strong>de</strong>mNamen a.out(4) sollte man nur vorübergehend arbeiten (mitmv(1) än<strong>de</strong>rn). Der Aufruf <strong>de</strong>s C-Compilers sieht beispielsweiseso aus:cc source.c14 L<strong>in</strong>ker wer<strong>de</strong>n auch B<strong>in</strong><strong>de</strong>r, Mapper o<strong>de</strong>r Loa<strong>de</strong>r genannt.Manchmal wird auch zwischen B<strong>in</strong><strong>de</strong>r und Loa<strong>de</strong>r unterschie<strong>de</strong>n,soll uns hier nicht beschäftigen.


34 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>cc -g source.c -lm -L./lib -I. -DMAX=100Die erste Zeile stellt <strong>de</strong>n m<strong>in</strong>imalen Aufruf dar, die zweite e<strong>in</strong>enum gängige Optionen erweiterten. Die Option -g veranlaßt <strong>de</strong>nCompiler, zusätzliche Informationen für <strong>de</strong>n symbolischen Debuggerzu erzeugen. Weitere Optionen s<strong>in</strong>d:• -v (verbose) führt zu etwas mehr Bemerkungen beim Übersetzen,• -o (output) benennt die ausführbare Datei mit <strong>de</strong>m auf dieOption folgen<strong>de</strong>n Namen, meist <strong>de</strong>rselbe wie die Quelle,nur ohne Kennung: cc -o myprogram myprogram.c,• -c hört vor <strong>de</strong>m L<strong>in</strong>ken auf, erzeugt Objektfile mit <strong>de</strong>r Kennung.o,• -p (profile) erzeugt beim Ablauf <strong>de</strong>s Programmes e<strong>in</strong>e Dateimon.out, das mit <strong>de</strong>m Profiler prof(1) ausgewertetwer<strong>de</strong>n kann, um Zeit<strong>in</strong>formationen zum Programm zu erhalten,• -O optimiert das ausführbare Programm o<strong>de</strong>r auch nicht.Der Quelltext <strong>de</strong>s C-Programmes steht <strong>in</strong> <strong>de</strong>r Datei source.c,die e<strong>in</strong>en beliebigen Namen tragen kann, nur sollte <strong>de</strong>r Namemit <strong>de</strong>r Kennung .c en<strong>de</strong>n. Die anschließen<strong>de</strong> Option -lmfor<strong>de</strong>rt <strong>de</strong>n L<strong>in</strong>ker auf, die mathematische Standard-Bibliotheke<strong>in</strong>zub<strong>in</strong><strong>de</strong>n. Die Option -L./lib wen<strong>de</strong>t sich ebenfalls an <strong>de</strong>nL<strong>in</strong>ker und teilt ihm mit, dass sich im Verzeichnis ./lib weitereBibliotheken bef<strong>in</strong><strong>de</strong>n. Die Reihenfolge, <strong>in</strong> <strong>de</strong>r Bibliothekene<strong>in</strong>gebun<strong>de</strong>n wer<strong>de</strong>n, ist wichtig. Die Option -I. veranlasst <strong>de</strong>nPräprozessor, Inclu<strong>de</strong>-Dateien auch im aktuellen Verzeichnis zusuchen, was er nicht immer automatisch tut. Es könnte auch e<strong>in</strong>an<strong>de</strong>res Verzeichnis angegeben wer<strong>de</strong>n. Die Option -DMAX=100<strong>de</strong>f<strong>in</strong>iert e<strong>in</strong>e symbolische Konstante namens MAX und weist ihr<strong>de</strong>n Wert 100 zu, genau wie e<strong>in</strong>e Zeile:#<strong>de</strong>f<strong>in</strong>e MAX 100im Quelltext, nur eben hier mit <strong>de</strong>r Möglichkeit, <strong>de</strong>n Wert bei<strong>de</strong>r Übersetzung zu bestimmen. Speichermo<strong>de</strong>lle wie unter PC-DOS gibt es <strong>in</strong> UNIX nicht. Hat man Speicher, kann man ihnune<strong>in</strong>geschränkt nutzen.Für C-Programme gibt es e<strong>in</strong>en Syntax-Prüfer namensl<strong>in</strong>t(1), <strong>de</strong>n man unbed<strong>in</strong>gt verwen<strong>de</strong>n sollte. Er reklamiert


1.2. PROGRAMMER’S WORKBENCH 35nicht nur Fehler, son<strong>de</strong>rn auch Stilmängel. Manchmal beanstan<strong>de</strong>ter auch D<strong>in</strong>ge, die man bewußt gegen die Regeln geschriebenhat. Man muß se<strong>in</strong>en Kommentar s<strong>in</strong>nvoll <strong>in</strong>terpretieren. Aufruf:l<strong>in</strong>t mysource.cE<strong>in</strong> verbesserter l<strong>in</strong>t, e<strong>in</strong> Secure Programm<strong>in</strong>g L<strong>in</strong>t f<strong>in</strong><strong>de</strong>t sichbei <strong>de</strong>r University of Virg<strong>in</strong>ia unter:http://www.spl<strong>in</strong>t.org/Unter L<strong>in</strong>ux ist l<strong>in</strong>t(1) nicht überall vorhan<strong>de</strong>n, dann kannman <strong>de</strong>n Compiler gcc(1) mit e<strong>in</strong>er Option aufrufen, die ihnnur zu e<strong>in</strong>er Prüfung <strong>de</strong>r Syntax veranlasst:gcc -fsyntax-only -pedantic -Wall mysource.cFerner gibt es unter e<strong>in</strong>igen UNIXen für C-Quelltexte e<strong>in</strong>enBeautifier namens cb(1), <strong>de</strong>r <strong>de</strong>n Text <strong>in</strong> e<strong>in</strong>e standardisierteForm mit E<strong>in</strong>rückungen usw. br<strong>in</strong>gt und die Lesbarkeit erleichtert:cb source.c > source.bWenn man mit <strong>de</strong>m Ergebnis source.b zufrie<strong>de</strong>n ist, löschtman die ursprüngliche Datei source.c und benennt source.b<strong>in</strong> source.c um.1.2.3 Unentbehrlich (make)Größere Programme s<strong>in</strong>d stark geglie<strong>de</strong>rt und auf mehrere bisviele Dateien und Verzeichnisse verteilt. Der Compileraufrufwird dadurch länglich, und die Wahrsche<strong>in</strong>lichkeit, etwas zu vergessen,steigt. Hier hilft make(1). Man schreibt e<strong>in</strong>mal alle Angabenfür <strong>de</strong>n Compiler <strong>in</strong> e<strong>in</strong> makefile (auch Makefile) undruft dann zum Kompilieren nur noch make(1) auf. Für Manuskripteist make(1) ebenfalls zu gebrauchen. Statt Makefiles ließensich auch Shellskripte e<strong>in</strong>setzen, die Stärke von make(1)liegt jedoch im Umgang mit Dateien unter Beachtung <strong>de</strong>s Zeitstempelsmtime (jüngster schreiben<strong>de</strong>r Zugriff). Werkzeuge wiemake(1) wer<strong>de</strong>n als Buil<strong>de</strong>r bezeichnet.


36 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Man lege für das Projekt e<strong>in</strong> eigenes Unterverzeichnis an,<strong>de</strong>nn make(1) sucht zunächst im Arbeits-Verzeichnis. Dasmakefile beschreibt die Abhängigkeiten (<strong>de</strong>pen<strong>de</strong>ncies) <strong>de</strong>rProgrammteile vone<strong>in</strong>an<strong>de</strong>r und enthält die Kommandozeilenzu ihrer Erzeugung. E<strong>in</strong> e<strong>in</strong>faches makefile sieht so aus (Zeilenmit Kommandos müssen durch e<strong>in</strong>en Tabulatorstop – nichtdurch Spaces – e<strong>in</strong>gerückt se<strong>in</strong>):pgm: a.o b.occ a.o b.o -o pgma.o: <strong>in</strong>cl.h a.ccc -c a.cb.o: <strong>in</strong>cl.h b.ccc -c b.cQuelle 1.7 : E<strong>in</strong>faches Makefileund ist folgen<strong>de</strong>rmaßen zu verstehen:• Das ausführbare Programm (Ziel, Target) namens pgmhängt ab von <strong>de</strong>n Modulen im Objektco<strong>de</strong> a.o und b.o. Esentsteht durch <strong>de</strong>n Compileraufruf cc a.o b.o -o pgm.• Das Programmodul a.o hängt ab von <strong>de</strong>r <strong>in</strong>clu<strong>de</strong>-Datei<strong>in</strong>cl.h und <strong>de</strong>m Modul im Quellco<strong>de</strong> a.c. Es entstehtdurch <strong>de</strong>n Aufruf <strong>de</strong>s Compilers mit cc -c a.c. Die Option- c unterb<strong>in</strong><strong>de</strong>t das L<strong>in</strong>ken.• Das Programmodul b.o hängt ab von <strong>de</strong>rselben <strong>in</strong>clu<strong>de</strong>-Datei und <strong>de</strong>m Modul im Quellco<strong>de</strong> b.c. Es entsteht durch<strong>de</strong>n Compileraufruf cc -c b.c.E<strong>in</strong> makefile ist ähnlich aufgebaut wie e<strong>in</strong> Backrezept: erstwer<strong>de</strong>n die Zutaten aufgelistet, dann folgen die Anweisungen.Zu beachten ist, daß man am Ziel startet und rückwärts bis zu<strong>de</strong>n Quellen geht. Kommentar beg<strong>in</strong>nt mit e<strong>in</strong>em Doppelkreuzund reicht bis zum Zeilenen<strong>de</strong>. Leerzeilen wer<strong>de</strong>n ignoriert.make(1) verwaltet auch verschie<strong>de</strong>ne Versionen <strong>de</strong>r Programmoduleund paßt auf, daß e<strong>in</strong>e neue Version <strong>in</strong> alle betroffenenProgrammteile e<strong>in</strong>gebun<strong>de</strong>n wird. Umgekehrt wird e<strong>in</strong>eaktuelle Version e<strong>in</strong>es Moduls nicht unnötigerweise kompiliert.Warum wird im obigen Beispiel die <strong>in</strong>clu<strong>de</strong>-Datei <strong>in</strong>cl.hausdrücklich genannt? Der Compiler weiß doch auf Grund e<strong>in</strong>erentsprechen<strong>de</strong>n Zeile im Quelltext, daß diese Datei e<strong>in</strong>zub<strong>in</strong><strong>de</strong>nist? Richtig, aber make(1) muß das auch wissen, <strong>de</strong>nn


1.2. PROGRAMMER’S WORKBENCH 37die <strong>in</strong>clu<strong>de</strong>-Datei könnte sich än<strong>de</strong>rn, und dann müssen alle vonihm abhängigen Programmteile neu übersetzt wer<strong>de</strong>n. make(1)schaut nicht <strong>in</strong> die Quellen h<strong>in</strong>e<strong>in</strong>, son<strong>de</strong>rn nur auf die Zeitstempel(mtime) <strong>de</strong>r Zutaten. Unverän<strong>de</strong>rliche <strong>in</strong>clu<strong>de</strong>-Dateien wiestdio.h brauchen nicht im makefile aufgeführt zu wer<strong>de</strong>n.Nun e<strong>in</strong> etwas umfangreicheres Beispiel, das aber längstnoch nicht alle Fähigkeiten von make(1) ausreizt:# Kommentar, wie ueblichCC = /b<strong>in</strong>/ccCFLAGS =FC = /usr/b<strong>in</strong>/f77LDFLAGS = -lclall: csumme fsumme cleancsumme: csumme.c csv.o csr.o$(CC) -o csumme csumme.c csv.o csr.ocsv.o: csv.c$(CC) -c csv.ccsr.o: csr.c$(CC) -c csr.cfsumme: fsumme.c fsr.o$(CC) -o fsumme fsumme.c fsr.o $(LDFLAGS)fsr.o: fsr.f$(FC) -c fsr.fclean:rm *.oQuelle 1.8 : Makefile mit Makros und Dummy-ZielenZunächst wer<strong>de</strong>n e<strong>in</strong>ige Makros <strong>de</strong>f<strong>in</strong>iert, z. B. <strong>de</strong>r CompileraufrufCC. Überall, wo im Makefile das Makro mittels $(CC) aufgerufenwird, wird es vor <strong>de</strong>r Ausführung wörtlich ersetzt. Aufdiese Weise kann man e<strong>in</strong>fach e<strong>in</strong>en an<strong>de</strong>ren Compiler wählen,ohne im ganzen Makefile per Editor ersetzen zu müssen. Dannhaben wir e<strong>in</strong> Dummy-Ziel all, das aus e<strong>in</strong>er Aufzählung weitererZiele besteht. Mittels make all wird dieses Dummy-Ziel


38 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>erzeugt, d. h. die aufgezählten Ziele. Unter diesen bef<strong>in</strong><strong>de</strong>t sichauch e<strong>in</strong>es namens clean, das ohne Zutaten daherkommt undoffenbar nur bestimmte Tätigkeiten wie das Löschen temporärerDateien bezweckt. E<strong>in</strong> Dummy-Ziel ist immer out-of-date, diezugehörigen Kommandos wer<strong>de</strong>n immer ausgeführt.make(1) darf rekursiv aufgerufen wer<strong>de</strong>n, e<strong>in</strong> Makefile darfmake-Aufrufe enthalten, die sich auf an<strong>de</strong>re Makefiles beziehen.Das kann so aussehen:............cd subdirectory ; make all ; make cleanGelangt make an diese Zeile, spr<strong>in</strong>gt es <strong>in</strong> das Unterverzeichnis,sucht dort e<strong>in</strong> Makefile und erzeugt die Ziele all und clean.Anschließend macht es im Makefile <strong>de</strong>s aktuellen Verzeichnissesweiter. E<strong>in</strong>e Anwendung ist e<strong>in</strong> aus mehreren Kapiteln bestehen<strong>de</strong>sSkriptum, das komplett als Report formatiert wer<strong>de</strong>nsoll, dazu noch die Kapitel <strong>in</strong> jeweils e<strong>in</strong>em eigenen Unterverzeichnisals Artikel samt Folien. Natürlich s<strong>in</strong>d die Makefiles <strong>in</strong><strong>de</strong>n Unterverzeichnissen weiche L<strong>in</strong>ks auf e<strong>in</strong> e<strong>in</strong>ziges Makefile.Ohne make(1) und e<strong>in</strong>e entsprechen<strong>de</strong> Verzeichnisstrukturwür<strong>de</strong> man sich dumm und dämlich tippen.Im GNU-Projekt wird Software im Quellco<strong>de</strong> für verschie<strong>de</strong>neSysteme veröffentlicht. In <strong>de</strong>r Regel muß man die Quellenauf <strong>de</strong>r eigenen Anlage kompilieren. Infolge<strong>de</strong>ssen gehören zu<strong>de</strong>n GNU-Programmen fast immer umfangreiche Makefiles o<strong>de</strong>rsogar Hierarchien davon. Übung im Gebrauch von make(1) erleichtertdie E<strong>in</strong>richtung von GNU-Software daher erheblich. Oftwird e<strong>in</strong> an das eigene System angepaßtes Makefile erst durche<strong>in</strong> Kommando ./configure erzeugt. Die Reihenfolge bei solchenProgramme<strong>in</strong>richtungen lautet dann:./configure(vi Makefile)makemake <strong>in</strong>stallmake cleanwobei make <strong>in</strong>stall Schreibrechte <strong>in</strong> <strong>de</strong>n betroffenen Verzeichnissenerfor<strong>de</strong>rt, also meist Superuserrechte. Gelegentlichwird make(1) aus e<strong>in</strong>em Shellskript heraus aufgerufen, das


1.2. PROGRAMMER’S WORKBENCH 39e<strong>in</strong>ige D<strong>in</strong>ge vorbereitet. So wird zum Beispiel sendmail(1)durch <strong>de</strong>n Aufruf <strong>de</strong>s mitgelieferten Shellskripts Build erzeugt.Das Skript configure erlaubt oft die Option -prefix=DIR,wobei DIR das Verzeichnis ist, <strong>in</strong> <strong>de</strong>m das ganze Gerö<strong>de</strong>l e<strong>in</strong>gerichtetwer<strong>de</strong>n soll, <strong>de</strong>faultmäßig meist /usr/local, abermanchmal besser /usr o<strong>de</strong>r /opt. Da von configure allesWeitere abhängt, sollte man sich die zugehörige Protokoll-Dateiconfig.log ansehen, auch wenn ansche<strong>in</strong>end ke<strong>in</strong>e Problemeaufgetreten s<strong>in</strong>d.Statt make clean kann man auch make distclean versuchen,das räumt noch gründlicher auf, so daß h<strong>in</strong>terher wie<strong>de</strong>rmit ./configure e<strong>in</strong> Neubeg<strong>in</strong>n möglich ist.1.2.4 Debugger (xdb, gdb)Programme s<strong>in</strong>d Menschenwerk und daher fehlerhaft 15 . Es gibtke<strong>in</strong>e Möglichkeit, die Fehlerfreiheit e<strong>in</strong>es Programmes festzustelleno<strong>de</strong>r zu beweisen außer <strong>in</strong> trivialen o<strong>de</strong>r i<strong>de</strong>alen Fällen.Die Fehler lassen sich <strong>in</strong> drei Klassen e<strong>in</strong>teilen. Verstößegegen die Regeln <strong>de</strong>r jeweiligen Programmiersprache heißenGrammatikfehler o<strong>de</strong>r Syntaxfehler. Sie führen bereits zue<strong>in</strong>em Abbruch <strong>de</strong>s Kompiliervorgangs und lassen sich schnelllokalisieren und beheben. Der C-Syntax-Prüfer l<strong>in</strong>t ist das besteWerkzeug zu ihrer Ent<strong>de</strong>ckung. wihle statt while wäre e<strong>in</strong>e<strong>in</strong>facher Syntaxfehler. Fehlen<strong>de</strong> o<strong>de</strong>r unpaarige Klammern s<strong>in</strong>dauch beliebt, <strong>de</strong>shalb enthält <strong>de</strong>r vi(1) e<strong>in</strong>e Funktion zur Klammerprüfung.Unzulässige Operationen mit Po<strong>in</strong>tern s<strong>in</strong>d ebenfallsan <strong>de</strong>r Tagesordnung. Geht es um Texte, so fallen Tippfehlerund Grammatikfehler <strong>in</strong> diese Klasse.Falls das Programm die Kompilation ohne Fehlermeldungh<strong>in</strong>ter sich gebracht hat, startet man es. Dann mel<strong>de</strong>n sich die15 Es irrt <strong>de</strong>r Mensch, so lang er strebt. GOETHE, Faust. O<strong>de</strong>rerrare humanum est, wie wir Late<strong>in</strong>er sagen. Noch etwas älter:αµαρτωλαι εν ανϑρωπoισιν επoνται ϑνητoις. Die entsprechen<strong>de</strong>Aussage <strong>in</strong> babylonischer Keilschrift aus <strong>de</strong>m Co<strong>de</strong>x Kombysiskönnen wir lei<strong>de</strong>r aus Mangel an e<strong>in</strong>em TeX-Font vorläufig nichtwie<strong>de</strong>rgeben. In <strong>de</strong>r nächsten Auflage wer<strong>de</strong>n wir jedoch e<strong>in</strong>ee<strong>in</strong>gescannte Zeichnung aus <strong>de</strong>r Höhle von Rienne-Vaplus zeigen,die als älteste Dokumentation obiger Weisheit gilt.


40 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Laufzeitfehler, die unter Umstän<strong>de</strong>n nur bei bestimmten undwomöglich seltenen Parameterkonstellationen auftreten. E<strong>in</strong> typischerLaufzeitfehler ist die Division durch e<strong>in</strong>e Variable, diemanchmal <strong>de</strong>n Wert Null annimmt. Die Fehlermeldung lautetFloat<strong>in</strong>g po<strong>in</strong>t exception. E<strong>in</strong> an<strong>de</strong>rer häufig vorkommen<strong>de</strong>rLaufzeitfehler ist die Überschreitung von Arraygrenzen o<strong>de</strong>r dieVerwechslung von Variablen und Po<strong>in</strong>tern, was zu e<strong>in</strong>em Memoryfault, e<strong>in</strong>em Speicherfehler führt.Die dritte Klasse bil<strong>de</strong>n die logischen Fehler o<strong>de</strong>r Denkfehler.Sie wer<strong>de</strong>n auch semantische Fehler genannt. DasProgramm arbeitet e<strong>in</strong>wandfrei, nur tut es nicht das, was sich<strong>de</strong>r Programmierer vorgestellt hat. E<strong>in</strong> typischer Denkfehler istdas Verzählen bei <strong>de</strong>n Elementen e<strong>in</strong>es Arrays o<strong>de</strong>r bei Schleifendurchgängenum genau e<strong>in</strong>s. Hier hilft <strong>de</strong>r Computer nur wenig,da <strong>de</strong>r Ärmste ja gar nicht weiß, was sich <strong>de</strong>r Programmierervorstellt. Diese Fehler kosten viel Mühe, doch solcherlei Verdrüssepflegen die Denkungskräfte anzuregen, me<strong>in</strong>t WILHELMBUSCH und hat recht.E<strong>in</strong>e vierte Fehlerklasse liegt fast schon außerhalb <strong>de</strong>r Verantwortung<strong>de</strong>s Programmierers. Wenn das mathematische Mo<strong>de</strong>llzur Beschreibung e<strong>in</strong>es realen Problems ungeeignet ist,mag das Programm so fehlerarm se<strong>in</strong> wie es will, se<strong>in</strong>e Ergebnissegehen an <strong>de</strong>r Wirklichkeit vorbei. Für bestimmte Zweckeist e<strong>in</strong>e Speisekarte e<strong>in</strong> brauchbares Mo<strong>de</strong>ll e<strong>in</strong>er Mahlzeit, füran<strong>de</strong>re nicht.In diese Klasse fallen auch Fehler, die dadurch entstehen,dass wir im Computer stets mit Zahlen endlicher Länge rechnen,während <strong>in</strong> Wirklichkeit die Zahl π unendlich viele Dezimalstellenhat und gemessene Größen statistischen Schwankungen unterliegen,also unscharf begrenzte Intervalle darstellen. Grundkenntnisse<strong>in</strong> mo<strong>de</strong>rner numerischer Mathematik bewahren vorbl<strong>in</strong><strong>de</strong>m Glauben an <strong>de</strong>n Computer.Ob und wie <strong>in</strong>haltliche Fehler <strong>in</strong> Texten – falsche o<strong>de</strong>r fehlen<strong>de</strong>Angaben – e<strong>in</strong>er <strong>de</strong>r vorstehen<strong>de</strong>n Klassen s<strong>in</strong>nvoll zugeordnetwer<strong>de</strong>n können, ist noch zu überlegen. Dann gibt es noch <strong>de</strong>nFehler Thema verfehlt, <strong>de</strong>r vielleicht zum Mo<strong>de</strong>ll-Fehler passt.H<strong>in</strong>tergrund dieser Gedanken ist die Anwendung von Software-Werkzeugen <strong>in</strong> Text-Projekten, was erwiesenermaßen die Arbeiterleichtert.E<strong>in</strong> Fehler wird im Englischen auch als bug bezeichnet, was


1.2. PROGRAMMER’S WORKBENCH 41soviel wie Wanze o<strong>de</strong>r Laus be<strong>de</strong>utet. E<strong>in</strong> Programm zu entlausenheißt Debugg<strong>in</strong>g. Dazu braucht man e<strong>in</strong>en Debugger (déverm<strong>in</strong>ateur,déboguer). Das s<strong>in</strong>d Programme, unter <strong>de</strong>ren Kontrolledas verlauste Programm abläuft. Man hat dabei vielfältigeMöglichkeiten, <strong>in</strong> <strong>de</strong>n Ablauf e<strong>in</strong>zugreifen. E<strong>in</strong> absoluter Debuggerwie <strong>de</strong>r adb(1) bezieht sich dabei auf das lauffähigeProgramm im Arbeitsspeicher – nicht auf <strong>de</strong>n Quellco<strong>de</strong> – undist somit für die meisten Aufgaben wenig geeignet. E<strong>in</strong> symbolischerDebugger wie <strong>de</strong>r sdb(1), <strong>de</strong>r GNU gdb(1) o<strong>de</strong>r<strong>de</strong>r xdb(1) bezieht sich auf die jeweilige Stelle im Quelltext 16 .Debugger s<strong>in</strong>d mächtige und hilfreiche Werkzeuge. Manche Programmierergehen so weit, daß sie das Schreiben e<strong>in</strong>es Programmsals Debuggen e<strong>in</strong>er leeren Datei bzw. e<strong>in</strong>es weißen BlattesPapier ansehen. In <strong>de</strong>r Übung wird e<strong>in</strong>e e<strong>in</strong>fache Anwendung<strong>de</strong>s Debuggers vorgeführt.Falls Sie auch mit <strong>de</strong>m UNIX-Debugger nicht alle Würmer<strong>in</strong> Ihrem Programm f<strong>in</strong><strong>de</strong>n und vertreiben können, möchten wirIhnen noch e<strong>in</strong> altes Hausrezept verraten, das aus e<strong>in</strong>er Handschrift<strong>de</strong>s 9. Jahrhun<strong>de</strong>rts stammt. Das Rezept ist im Raum Wien– München entstan<strong>de</strong>n und unter <strong>de</strong>n Namen Contra vermeso<strong>de</strong>r Pro nescia bekannt. Lei<strong>de</strong>r ist die README-Datei, welche dieHandhabung erklärt, verlorengegangen. Wir schlagen vor, dieZeilen als Kommentar <strong>in</strong> das Programm e<strong>in</strong>zufügen. Hier <strong>de</strong>rText:Gang út, nesso, mid nigun nessikl<strong>in</strong>on,ût fana themo marge an that bên,fan thêmo bêne an that flêsg,ût fan themo flêsgke an thia hûd,ût fan thera hûd an thesa strâla.Droht<strong>in</strong>. Uuerthe sô!1.2.5 Profiler (time, gprof)Profiler s<strong>in</strong>d ebenfalls Programme, unter <strong>de</strong>ren Kontrolle e<strong>in</strong>zu untersuchen<strong>de</strong>s Programm abläuft. Ziel ist die Ermittlung<strong>de</strong>s Zeitverhaltens <strong>in</strong> <strong>de</strong>r Absicht, das Programm schneller zumachen. E<strong>in</strong> e<strong>in</strong>faches UNIX-Werkzeug ist time(1):time prim 100000016 Real programmers don’t use source language <strong>de</strong>buggers.


42 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Die Ausgabe sieht so aus:real 0m 30.65suser 0m 22.53ssys 0m 1.07sund be<strong>de</strong>utet, daß die gesamte Laufzeit <strong>de</strong>s Programms prim30.65 s betrug, davon entfielen 22.53 s auf die Ausführung vonBenutzeranweisungen und 1.07 s auf Systemtätigkeiten. DieAusgabe wur<strong>de</strong> durch e<strong>in</strong>en Aufruf <strong>de</strong>s Primzahlenprogrammsaus <strong>de</strong>m Skriptum Programmieren <strong>in</strong> C/<strong>C++</strong> erzeugt, das selbstZeiten mittels <strong>de</strong>s Systemaufrufs time(2) misst und rund 22 sfür die Rechnung und 4 s für die Bildschirmausgabe mel<strong>de</strong>t.E<strong>in</strong> weiterer Profiler ist gprof(1). Se<strong>in</strong>e Verwendung setztvoraus, daß das Programm mit <strong>de</strong>r Option -G kompiliert wor<strong>de</strong>nist. Es wird gestartet und erzeugt neben se<strong>in</strong>er normalen Ausgabee<strong>in</strong>e Datei gmon.out, das mit gprof(1) betrachtet wird.Besser noch lenkt man die Ausgabe von gprof(1) <strong>in</strong> e<strong>in</strong>e Dateium, die sich lesen und editieren läßt:gprof prim > prim.gprofileE<strong>in</strong>e stark gekürzte Analyse mittels gprof(1) sieht so aus:%timethe percentage of the total runn<strong>in</strong>g time of theprogram used by this function.cumsecs a runn<strong>in</strong>g sum of the number of seconds accountedfor by this function and those listed above it.seconds the number of seconds accounted for by thisfunction alone. This is the major sort for thislist<strong>in</strong>g.callsthe number of times this function was <strong>in</strong>voked, ifthis function is profiled, else blank.name the name of the function. This is the m<strong>in</strong>or sortfor this list<strong>in</strong>g.%time cumsecs seconds calls msec/call name52.1 12.18 12.18 $$remU


1.2. PROGRAMMER’S WORKBENCH 4322.2 17.38 5.20 $$mulU20.8 22.25 4.87 333332 0.01 ttest2.1 22.74 0.49 9890 0.05 _doprnt0.8 22.93 0.19 _mcount0.6 23.08 0.15 $$divi<strong>de</strong>_by_const0.6 23.22 0.14 1 140.00 ma<strong>in</strong>0.3 23.29 0.07 9890 0.01 _memchr0.2 23.34 0.05 _write_sys0.1 23.36 0.02 9890 0.00 _pr<strong>in</strong>tf0.0 23.37 0.01 9887 0.00 _write0.0 23.38 0.01 9887 0.00 _xflsbuf0.0 23.39 0.00 9890 0.00 _wrtchk0.0 23.39 0.00 1 0.00 _sscanf0.0 23.39 0.00 1 0.00 _start0.0 23.39 0.00 1 0.00 _strlen0.0 23.39 0.00 1 0.00 atexit0.0 23.39 0.00 1 0.00 exit0.0 23.39 0.00 1 0.00 ioctlWir sehen, daß die Funktion ttest() sehr oft aufgerufenwird und 4,87 s verbrät. Die bei<strong>de</strong>n ersten Funktionenwer<strong>de</strong>n vom Compiler zur Verfügung gestellt (Millico<strong>de</strong> aus/usr/lib/milli.a) und liegen außerhalb unserer Reichweite.Für genauere Auskünfte zieht man <strong>de</strong>n Systemaufruftimes(2), <strong>de</strong>n Debugger o<strong>de</strong>r das UNIX-Kommando prof(1)<strong>in</strong> Verb<strong>in</strong>dung mit <strong>de</strong>r Subrout<strong>in</strong>e monitor(3) heran.1.2.6 Archive, Bibliotheken (ar)Viele Teilaufgaben <strong>in</strong> <strong>de</strong>n Programmen wie<strong>de</strong>rholen sich immerwie<strong>de</strong>r. Das s<strong>in</strong>d Aufgaben, die mit <strong>de</strong>m System zu tun haben,Befehle zur Bildschirmsteuerung, mathematische Berechnungenwie Logarithmus o<strong>de</strong>r trigonometrische Funktionen, Datenbankfunktioneno<strong>de</strong>r Funktionen zur Abfrage von Meßgerätenam Bus.Damit man diese Funktionen nicht je<strong>de</strong>smal neu zu erf<strong>in</strong><strong>de</strong>nbraucht, wer<strong>de</strong>n sie <strong>in</strong> Bibliotheken gepackt, die <strong>de</strong>m Programmiererzur Verfügung stehen. Teils stammen sie vom Hersteller<strong>de</strong>s Betriebssystems (also ursprünglich AT&T), teils vom Hersteller<strong>de</strong>r Compiler (bei uns Hewlett-Packard und GNU) o<strong>de</strong>r


44 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong><strong>de</strong>r Anwendungssoftware, teils von Benutzern. Bibliotheken enthaltenProgrammbauste<strong>in</strong>e, es lassen sich aber auch an<strong>de</strong>reDateien (Texte, Grafiken) <strong>in</strong> gleicher Weise zusammenfassen.Dann spricht man allgeme<strong>in</strong>er von Archiven. Außer <strong>de</strong>n Dateienenthalten Archive Verwaltungs<strong>in</strong>formationen (In<strong>de</strong>x) zumschnellen F<strong>in</strong><strong>de</strong>n <strong>de</strong>r Inhalte. Diese Informationen wur<strong>de</strong>n frühermit <strong>de</strong>m Kommando ranlib(1) eigens erzeugt, heute erledigtar(1) das mit. Die Verwendung von Bibliotheken beimProgrammieren wird im Skriptum Programmieren <strong>in</strong> C/<strong>C++</strong> erläutert.Außer <strong>de</strong>n mit <strong>de</strong>m Compiler gelieferten Bibliotheken kannman zusätzlich erworbene o<strong>de</strong>r selbst erstellte Bibliothekenverwen<strong>de</strong>n. Im Han<strong>de</strong>l s<strong>in</strong>d beispielsweise Bibliotheken mitFunktionen für Bildschirmmasken, zur Verwaltung <strong>in</strong><strong>de</strong>xsequentiellerDateien, für Grafik, zur Meßwerterfassung und -aufbereitung und für beson<strong>de</strong>re mathematische Aufgaben. Auchaus <strong>de</strong>m Netz laufen Bibliotheken zu. Eigene Bibliotheken erzeugtman mit <strong>de</strong>m UNIX-Kommando ar(1); das Datei-Formatist unter ar(4) beschrieben. E<strong>in</strong> Beispiel zeige <strong>de</strong>n Gebrauch.Wir haben e<strong>in</strong> Programm statistik.c zur Berechnung vonMittelwert und Varianz <strong>de</strong>r <strong>in</strong> <strong>de</strong>r Kommandozeile mitgegebenenganzen Zahlen geschrieben:/* Statistische Auswertung von e<strong>in</strong>gegebenen WertenPrivat-Bibliothek ./libstat.a erfor<strong>de</strong>rlichCompileraufruf cc statistik.c -L . -lstat*/#<strong>de</strong>f<strong>in</strong>e MAX 100 /* max. Anzahl <strong>de</strong>r Werte */#<strong>in</strong>clu<strong>de</strong> void exit(); double mwert(), varianz();ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[]){<strong>in</strong>t i, a[MAX];if (argc < 3) {puts("Zuwenig Werte"); exit(-1);}if (argc > MAX + 1) {


1.2. PROGRAMMER’S WORKBENCH 45}puts("Zuviel Werte"); exit(-1);/* Uebernahme <strong>de</strong>r Werte <strong>in</strong> e<strong>in</strong> Array */a[0] = argc - 1;for (i = 1; i < argc; i++) {sscanf(argv[i], "%d", a + i);}/* Ausgabe <strong>de</strong>s Arrays */for (i = 1; i < argc; i++) {pr<strong>in</strong>tf("%d\n", a[i]);}/* Rechnungen */pr<strong>in</strong>tf("Mittelwert: %f\n", mwert(a));pr<strong>in</strong>tf("Varianz: %f\n", varianz(a));return 0;}Quelle 1.9 : C-Programm Statistik mit Benutzung e<strong>in</strong>er eigenenFunktionsbibliothekDas Programm verwen<strong>de</strong>t die Funktionen mwert() undvarianz(), die wir aus e<strong>in</strong>er hausgemachten Funktionsbibliotheknamens libstat.a entnehmen. Der im Kommentar genannteCompileraufruf mit <strong>de</strong>r Option -L . veranlaßt <strong>de</strong>n L<strong>in</strong>ker,diese Bibliothek im Arbeits-Verzeichnis zu suchen. DieFunktionen sehen so aus:double mwert(x)<strong>in</strong>t *x;{<strong>in</strong>t j, k;double m;for (j = 1, k = 0; j


46 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>return m;}Quelle 1.10 : C-Funktion Mittelwert ganzer Zahlenextern double mwert();double varianz(x)<strong>in</strong>t *x;{<strong>in</strong>t j;double m, s, v;m = mwert(x);for (j = 1, s = 0; j


1.2. PROGRAMMER’S WORKBENCH 47cflow statistik.cliefert auf stdout1 ma<strong>in</strong>: <strong>in</strong>t(), 2 puts: 3 exit: 4 sscanf: 5 pr<strong>in</strong>tf: 6 mwert: 7 varianz: was besagt, daß die Funktion ma<strong>in</strong>() vom Typ <strong>in</strong>t ist und <strong>in</strong>Zeile 15 <strong>de</strong>s Quelltextes statistik.c <strong>de</strong>f<strong>in</strong>iert wird. ma<strong>in</strong>()ruft se<strong>in</strong>erseits die Funktionen puts, exit, sscanf und pr<strong>in</strong>tfauf, die <strong>in</strong> statistik.c nicht <strong>de</strong>f<strong>in</strong>iert wer<strong>de</strong>n, da sie Teil <strong>de</strong>rStandardbibliothek s<strong>in</strong>d. Die Funktionen mwert und varianzwer<strong>de</strong>n ebenfalls aufgerufen und nicht <strong>de</strong>f<strong>in</strong>iert, da sie aus e<strong>in</strong>erPrivatbibliothek stammen.Das Werkzeug cxref(1) erzeugt zu e<strong>in</strong>er Gruppe von C-Quellfiles e<strong>in</strong>e Kreuzreferenzliste aller Symbole, die nicht re<strong>in</strong>lokal s<strong>in</strong>d. Der Aufrufcxref fehler.cgibt nach stdout e<strong>in</strong>e Liste aus, <strong>de</strong>ren erste Zeilen so aussehen:fehler.c:SYMBOL FILE FUNCTION LINEBUFSIZ /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- *10EOF /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- 70 *71FILE /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- *18 78 123127 128 201223FILENAME_MAX /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- *67FOPEN_MAX /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- *68L_ctermid /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- *193L_cuserid /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- *194L_tmpnam /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- *61NULL /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- 35 *36


48 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>PI fehler.c -- *27P_tmpdir /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- *209SEEK_CUR /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- *55SEEK_END /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- *56SEEK_SET /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- 53 *54TMP_MAX /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- 63 *64_CLASSIC_ANSI_TYPES /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h -- 162Durch die <strong>in</strong>clu<strong>de</strong>-Datei stdio.h und gegebenenfalls durchBibliotheksfunktionen geraten viele Namen <strong>in</strong> das Programm,von <strong>de</strong>nen man nichts ahnt. Ferner gibt es e<strong>in</strong>ige Werkzeuge zurErmittlung und Bearbeitung von Str<strong>in</strong>gs <strong>in</strong> Quellfiles und ausführbarenProgrammen, teilweise beschränkt auf C-Programme(tt str<strong>in</strong>gs(1), xstr(1)).Weitere wichtige Werkzeuge s<strong>in</strong>d e<strong>in</strong> L<strong>in</strong>eal und Buntstifte,mit <strong>de</strong>nen man zusammengehören<strong>de</strong> Namen o<strong>de</strong>r Teile im Quelltextmarkiert.1.2.8 Versionsverwaltung mit RCS, SCCS undCVSGrößere Projekte wer<strong>de</strong>n von zahlreichen, unter Umstän<strong>de</strong>nwechseln<strong>de</strong>n Programmierern o<strong>de</strong>r Autoren geme<strong>in</strong>sam bearbeitet.In <strong>de</strong>r Regel wer<strong>de</strong>n die so entstan<strong>de</strong>nen Programmpaketeüber Jahre h<strong>in</strong>weg weiterentwickelt und vielleicht auf mehrereSysteme portiert. Die Arbeit vollzieht sich <strong>in</strong> mehreren Stufenparallel zur Zeitachse:• Aufgabenstellung• Aufgabenanalyse• Umsetzung <strong>in</strong> e<strong>in</strong>e Programmiersprache• Testen• Dokumentieren• vorläufige Freigabe• endgültige Freigabe• Weiterentwicklung, PflegeDes weiteren wird e<strong>in</strong> Programmpaket <strong>in</strong> viele überschaubareModule aufgeteilt. Von je<strong>de</strong>m Modul entstehen im Verlauf <strong>de</strong>r


1.2. PROGRAMMER’S WORKBENCH 49Arbeit mehrere Fassungen o<strong>de</strong>r Versionen. Der Zustand <strong>de</strong>sganzen Projektes läßt sich <strong>in</strong> e<strong>in</strong>em dreidimensionalen Koord<strong>in</strong>atensystemmit <strong>de</strong>n Achsen Modul, Stufe (Zeit) und Versiondarstellen. Das von WALTER F. TICHY entwickelte RevisionControl System RCS ist e<strong>in</strong> Werkzeug, um bei dieser EntwicklungOrdnung zu halten. Es ist e<strong>in</strong>fach handzuhaben und verträgtsich gut mit make(1). Das RCS erledigt drei Aufgaben:• Es führt Buch über die Än<strong>de</strong>rungen an <strong>de</strong>n Texten.• Es ermöglicht, ältere Versionen wie<strong>de</strong>rherzustellen, ohnedaß diese vollständig gespeichert zu wer<strong>de</strong>n brauchen(Speichern von Differenzen).• Es verh<strong>in</strong><strong>de</strong>rt gleichzeitige schreiben<strong>de</strong> Zugriffe mehrererBenutzer auf <strong>de</strong>nselben Text.Sowie es um mehr als Wegwerfprogramme geht, sollte manmake(1) und RCS e<strong>in</strong>setzen. Der ger<strong>in</strong>ge Aufwand zum E<strong>in</strong>arbeitenwird bei <strong>de</strong>r weiteren Arbeit mehr als wett gemacht.Arbeiten mehrere Programmierer an e<strong>in</strong>em Projekt, kommt manum RCS o<strong>de</strong>r ähnliches nicht herum. Bei<strong>de</strong> Werkzeuge s<strong>in</strong>d auchfür Manuskripte o<strong>de</strong>r WWW-Dateien zu verwen<strong>de</strong>n. RCS ist <strong>in</strong><strong>de</strong>n meisten L<strong>in</strong>ux-Distributionen enthalten. Man beg<strong>in</strong>nt folgen<strong>de</strong>rmaßen:• Unterverzeichnis anlegen, h<strong>in</strong>e<strong>in</strong>wechseln.• Mit e<strong>in</strong>em Editor die erste Fassung <strong>de</strong>s Quelltextes schreiben.Irgendwo im Quelltext - z. B. im Kommentar - sollte$Hea<strong>de</strong>r: /home/<strong>de</strong>bian/unix/unix8.tex,v 1.1.1.1 2005/02o<strong>de</strong>r $Id: unix8.tex,v 1.1.1.1 2005/02/06 20:01:11 wulfvorkommen, siehe unten. Dann übergibt man mit <strong>de</strong>mKommando ci filename (check <strong>in</strong>) die Datei <strong>de</strong>m RCS.Dieses ergänzt die Datei durch Versions<strong>in</strong>formationen undmacht e<strong>in</strong>e nur lesbare RCS-Datei (444) mit <strong>de</strong>r Kennung,v daraus. Die ursprüngliche Datei löschen.• Mit <strong>de</strong>m Kommando co filename (check out, ohne ,v)bekommt man e<strong>in</strong>e Kopie se<strong>in</strong>er Datei zurück, und zwarnur zum Lesen. Diese Kopie kann man mit allen UNIX-Werkzeugen bearbeiten, nur das Zurückschreiben mittelsci verweigert das RCS.• Mit <strong>de</strong>m Kommando co -l filename wird e<strong>in</strong>e les- undschreibbare Kopie erzeugt. Dabei wird die RCS-Datei für


50 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>weitere, gleichzeitige Schreibzugriffe gesperrt (l = lock). DieKopie kann man mit allen UNIX-Werkzeugen bearbeiten,Umbenennen wäre jedoch e<strong>in</strong> schlechter E<strong>in</strong>fall.• Beim Zurückstellen mittels ci filename hat man Gelegenheit,e<strong>in</strong>en kurzen Kommentar <strong>in</strong> die Versions<strong>in</strong>formationenzu schreiben wie Grund und Umfang <strong>de</strong>r Än<strong>de</strong>rung.Mittels rlog filename wer<strong>de</strong>n die Versions<strong>in</strong>formationenauf <strong>de</strong>n Schirm geholt. Enthält <strong>de</strong>r Quelltext die Zeichenfolge$Log: unix8.tex,v $ – zweckmäßig im Kommentaram Anfang – so wer<strong>de</strong>n die Versions<strong>in</strong>formationenauch dorth<strong>in</strong> übernommen. Dann hat man alles im Quellfilebeisammen.• Falls Sie sich mit co -l filename e<strong>in</strong>e Kopie zum Editierengeholt und damit gleichzeitig das Orig<strong>in</strong>al für weitereSchreibzugriffe gesperrt haben, anschließend die Kopiemit rm(1) löschen, so haben Sie nichts mehr zumZurückstellen. In diesem Fall läßt sich die Sperre mitrcs -u filename aufheben. Besser ist es jedoch, auf dieUNIX-Kommandos zu verzichten und nur mit <strong>de</strong>n RCS-Kommandos zu arbeiten.Das ist für <strong>de</strong>n Anfang alles. Die RCS-Kommandos lassen sich <strong>in</strong>Makefiles verwen<strong>de</strong>n. Die vom RCS vergebenen Zugriffsrechtekönnen von UNIX-Kommandos (chmod(1)) überrannt wer<strong>de</strong>n,aber das ist nicht S<strong>in</strong>n <strong>de</strong>r Sache; <strong>de</strong>r E<strong>in</strong>satz von RCS setztvoraus, daß sich die Beteiligten diszipl<strong>in</strong>iert verhalten.Hier e<strong>in</strong> Makefile mit RCS-Kommandos für das nachstehen<strong>de</strong>Sortierprogramm:# makefile zu mysort.c, im RCS-System# $Hea<strong>de</strong>r: /home/<strong>de</strong>bian/prog/quellen/sortmakef.tex,v 1.1.1.1CC = /b<strong>in</strong>/ccCFLAGS = -Aa -DDEBUGall: mysort cleanmysort: mysort.o bubble.o$(CC) $(CFLAGS) -o mysort mysort.o bubble.omysort.o: mysort.c myhea<strong>de</strong>r.h$(CC) $(CFLAGS) -c mysort.c


1.2. PROGRAMMER’S WORKBENCH 51bubble.o: bubble.c myhea<strong>de</strong>r.h$(CC) $(CFLAGS) -c bubble.cmysort.c: mysort.c,vco mysort.cbubble.c: bubble.c,vco bubble.cmyhea<strong>de</strong>r.h: myhea<strong>de</strong>r.h,vco myhea<strong>de</strong>r.hclean:/b<strong>in</strong>/rm-f *.c *.o *.h makefileQuelle 1.12 : Makefile zum Sortierprogramm mysort.cDa dieses Beispiel sich voraussichtlich zu e<strong>in</strong>er kle<strong>in</strong>en Familievon Quelltexten ausweiten wird, legen wir e<strong>in</strong>e privates <strong>in</strong>clu<strong>de</strong>-Datei mit unseren eigenen, für alle Teile gültigen Werten an:/* myhea<strong>de</strong>r.h zum Sortierprogramm, RCS-BeispielW. <strong>Alex</strong>, Universitaet Karlsruhe, 04. Juli 1995*//*$Hea<strong>de</strong>r: /home/<strong>de</strong>bian/prog/quellen/sort<strong>in</strong>clu<strong>de</strong>,v 1.1.1.1 2*/<strong>in</strong>t bubble(char *text);<strong>in</strong>t <strong>in</strong>sert(char *text);#<strong>de</strong>f<strong>in</strong>e USAGE "Aufruf: mysort filename"#<strong>de</strong>f<strong>in</strong>e NOTEXIST "File existiert nicht"#<strong>de</strong>f<strong>in</strong>e NOTREAD "File ist nicht lesbar"#<strong>de</strong>f<strong>in</strong>e NOTSORT "Problem beim Sortieren"#<strong>de</strong>f<strong>in</strong>e LINSIZ 64 /* Zeilenlaenge */#<strong>de</strong>f<strong>in</strong>e MAXLIN 256 /* Anzahl Zeilen */Quelle 1.13 : Inclu<strong>de</strong>-Datei zum Sortierprogramm mysort.cNun das Hauptprogramm, das die Verantwortung trägt,aber sonst nicht viel tut. Hier ist <strong>de</strong>r Platzhalter$Hea<strong>de</strong>r: /home/<strong>de</strong>bian/unix/unix8.tex,v 1.1.1.1 2005/02/06


52 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Bestandteil <strong>de</strong>s Co<strong>de</strong>s, die Versions<strong>in</strong>formationen stehen alsoauch im ausführbaren Programm. Man könnte sogar mit ihnenetwas machen, ausgeben beispielsweise:/* Sortierprogramm mysort, als Beispiel fuer RCS *//*$Log: mysort.tex,v $Revision 1.1.1.1 2005/02/06 19:44:00 wulfAnlegen <strong>de</strong>s prog-Reps*/static char rcsid[] ="$Hea<strong>de</strong>r: /home/<strong>de</strong>bian/prog/quellen/mysort.tex,v 1.1.1.1 2005#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> "myhea<strong>de</strong>r.h"<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[]){long time1, time2;/* Pruefung <strong>de</strong>r Kommandozeile */if (argc != 2) {puts(USAGE); return(-1);}/* Pruefung <strong>de</strong>s Textfiles */if (access(argv[1], 0)) {puts(NOTEXIST); return(-2);}if (access(argv[1], 4)) {puts(NOTREAD); return(-3);}/* Sortierfunktion und Zeitmessung */time1 = time((long *)0);if (bubble(argv[1])) {puts(NOTSORT); return(-4);}


1.2. PROGRAMMER’S WORKBENCH 53time2 = time((long *)0);/* En<strong>de</strong> */pr<strong>in</strong>tf("Das Sortieren dauerte %ld sec.\n", time2 - time1);return 0;}Quelle 1.14 : C-Programm Sortieren, für RCSHier die Funktion zum Sortieren (Bubblesort, nicht optimiert).Der e<strong>in</strong>zige Witz <strong>in</strong> dieser Funktion ist, daß wir nicht dieStr<strong>in</strong>gs durch Umkopieren sortieren, son<strong>de</strong>rn nur die Indizes <strong>de</strong>rStr<strong>in</strong>gs. Ansonsten kann man hier noch e<strong>in</strong>iges verbessern undvor allem auch an<strong>de</strong>re Sortieralgorithmen nehmen. Man sollteauch das E<strong>in</strong>lesen und die Ausgabe vom Sortieren trennen:/* Funktion bubble() (Bubblesort), als Beispiel fuer RCSW. <strong>Alex</strong>, Universitaet Karlsruhe, 04. Juli 1995 *//*$Hea<strong>de</strong>r: /home/<strong>de</strong>bian/prog/quellen/bubble.tex,v 1.1.1.1*/#<strong>in</strong>clu<strong>de</strong> &#60;stdio.h&#62;#<strong>in</strong>clu<strong>de</strong> &#60;str<strong>in</strong>g.h&#62;#<strong>in</strong>clu<strong>de</strong> "myhea<strong>de</strong>r.h"<strong>in</strong>t bubble(char *text){<strong>in</strong>t i = 0, j = 0, flag = 0, z, l<strong>in</strong>e[MAXLIN];char array[MAXLIN][LINSIZ];FILE *fp;#if DEBUGpr<strong>in</strong>tf("Bubblesort %s\n", text);#endif/* E<strong>in</strong>lesen */if ((fp = fopen(text, "r")) == NULL) return(-1);while ((!feof(fp)) && (i < MAXLIN)) {fgets(array[i++], LINSIZ, fp);}


54 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>fclose(fp);#if DEBUGputs("Array:");j = 0;while (j < i) {pr<strong>in</strong>tf("%s", array[j++]);}puts("En<strong>de</strong> Array");#endif/* Sortieren (Bubblesort) */for (j = 0; j < MAXLIN; j++)l<strong>in</strong>e[j] = j;while (flag == 0) {flag = 1;for (j = 0; j < i; j++) {if (strcmp(array[l<strong>in</strong>e[j]], array[l<strong>in</strong>e[j + 1]]) > 0) {z = l<strong>in</strong>e[j + 1];l<strong>in</strong>e[j + 1] = l<strong>in</strong>e[j];l<strong>in</strong>e[j] = z;flag = 0;}}}/* Ausgeben nach stdout */#if DEBUGputs("Array:");j = 0;while (j < i) {pr<strong>in</strong>tf("%d\n", l<strong>in</strong>e[j++]);}puts("En<strong>de</strong> Array");#endifj = 0;while (j < i) {pr<strong>in</strong>tf("%s", array[l<strong>in</strong>e[j++]]);}/* En<strong>de</strong> */


1.2. PROGRAMMER’S WORKBENCH 55return 0;}Quelle 1.15 : C-Funktion BubblesortBubblesort eignet sich für kle<strong>in</strong>e Sortieraufgaben mit bis zu etwahun<strong>de</strong>rt Elementen. Kopieren Sie sich die Bauste<strong>in</strong>e <strong>in</strong> e<strong>in</strong> eigenesVerzeichnis und entwickeln Sie das Programm unter Verwendung<strong>de</strong>s RCS weiter. Näheres siehe rcs<strong>in</strong>tro(5).Anfangs ersche<strong>in</strong>t das Arbeiten mit RCS bei kle<strong>in</strong>en Projektenals lästig, ähnlich wie das Anlegen e<strong>in</strong>es Makefiles. Man gewöhntsich aber schnell daran und spart sofort das E<strong>in</strong>tragen<strong>de</strong>s Än<strong>de</strong>rungsdatums von Hand. Nach kurzer Zeit ist man fürdie selbst auferlegte Ordnung dankbar.Das Source Co<strong>de</strong> Control System SCCS verwaltet die Versionen<strong>de</strong>r Module, <strong>in</strong><strong>de</strong>m es die erste Fassung vollständig speichertund dann jeweils die Differenzen zur nächsten Version,während RCS die jüngste Version speichert und die älteren aus<strong>de</strong>n Differenzen rekonstruiert.Alle Versionen e<strong>in</strong>es Programmes samt <strong>de</strong>n Verwaltungsdatenwer<strong>de</strong>n <strong>in</strong> e<strong>in</strong>er e<strong>in</strong>zigen SCCS-Datei namens s.filenameabgelegt, auf das schreibend nur über beson<strong>de</strong>re SCCS-Kommandos zugegriffen wer<strong>de</strong>n kann. Das erste dieser Kommandosist adm<strong>in</strong>(1) und erzeugt aus e<strong>in</strong>em C-Quellfileprogram.c das zugehörige SCCS-Dokument:adm<strong>in</strong> -iprogram.c s.program.cMit adm<strong>in</strong>(1) lassen sich noch weitere Aufgaben erledigen, sieheReferenz-Handbuch. Mittels get(1) holt man das Quellfilewie<strong>de</strong>r aus <strong>de</strong>m SCCS-Dokument heraus, mitttels <strong>de</strong>lta(1)gibt man e<strong>in</strong>e geän<strong>de</strong>rte Fassung <strong>de</strong>s Quellfiles an das SCCS-Dokument zurück.RCS und SCCS arbeiten auf Datei-Ebene. Bei größeren Projektenist es wünschenswert, mehrere Dateien geme<strong>in</strong>sam o<strong>de</strong>rganze Verzeichnisse <strong>in</strong> die Versionsverwaltung e<strong>in</strong>zubeziehen.Dies leistet das Concurrent Versions System (CVS). Es bautauf RCS auf und erweitert <strong>de</strong>ssen Funktionalität außer<strong>de</strong>m ume<strong>in</strong>e Client-Server-Architektur. Die beteiligten Dateien und Verzeichnissekönnen auf verschie<strong>de</strong>nen Computern im Netz liegen.


56 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Im Gegensatz zu RCS, das zu e<strong>in</strong>em Zeitpunkt immer nur e<strong>in</strong>emBenutzer das Schreiben gestattet, verfolgt CVS e<strong>in</strong>e sogenannteoptimistische Kooperationsstrategie. Mehrere Programmiererkönnen gleichzeitig auf Kopien <strong>de</strong>rselben Version (Revision)arbeiten. Beim Zurückschreiben wird e<strong>in</strong> Abgleich mit <strong>de</strong>r<strong>in</strong> <strong>de</strong>r zentralen Versionsbibliothek (Repository) abgelegten Fassungerzwungen, um zu verh<strong>in</strong><strong>de</strong>rn, daß parallel durchgeführteund bereits zurückgeschriebene Versionen überschrieben wer<strong>de</strong>n.Diese Strategie kann zu Konflikten führen, die per Handaufgelöst wer<strong>de</strong>n müssen. Während das E<strong>in</strong>richten e<strong>in</strong>es CVS-Projektes Überblick erfor<strong>de</strong>rt, ist das Arbeiten unter CVS nichtschwieriger als unter RCS. E<strong>in</strong>zelheiten wie so oft am e<strong>in</strong>fachstenaus <strong>de</strong>m Netz, wo außer <strong>de</strong>m Programmpaket selbst auchkurze o<strong>de</strong>r ausführliche, <strong>de</strong>utsche o<strong>de</strong>r englische Anleitungen zuf<strong>in</strong><strong>de</strong>n s<strong>in</strong>d. Unter <strong>de</strong>n Namen W<strong>in</strong>CVS und MacCVS liegen Fassungenfür weitere Betriebssysteme im Netz.Der Oberbegriff <strong>de</strong>s ganzen Gebietes lautet Software ConfigurationManagement (SCM) o<strong>de</strong>r allgeme<strong>in</strong>er ConfigurationManagement (CM). Lassen Sie e<strong>in</strong>mal e<strong>in</strong>e Suchmasch<strong>in</strong>e darauflos, es gibt mehrere freie o<strong>de</strong>r kommerzielle Produkte sowieÜbersichten, E<strong>in</strong>führungen und Tutorials dazu.Ist die Entwicklung e<strong>in</strong>er Software o<strong>de</strong>r e<strong>in</strong>es Manuskriptesvorläufig abgeschlossen, geht es an die Pflege. Dazu gehört unteran<strong>de</strong>rem das Management <strong>de</strong>r im Betrieb <strong>de</strong>r Software auftauchen<strong>de</strong>nProbleme. Auch hierfür gibt es Werkzeuge, beispielsweisegnats aus <strong>de</strong>m GNU-Projekt. Aber das sprengt <strong>de</strong>n Rahmendieses Buches.CASE be<strong>de</strong>utet Computer Ai<strong>de</strong>d Software Eng<strong>in</strong>eer<strong>in</strong>g. Ansich ist das nichts Neues, beim Programmieren hat man schonimmer Computer e<strong>in</strong>gesetzt. Das Neue bei CASE Tools wie Soft-Bench von Hewlett-Packard besteht dar<strong>in</strong>, daß die e<strong>in</strong>zelnenProgrammierwerkzeuge wie syntaxgesteuerte Editoren, Compiler,L<strong>in</strong>ker, Buil<strong>de</strong>r (make(1)), Analysewerkzeuge, Debugger,Versionskontrollsysteme sowie die Dokumentation unter e<strong>in</strong>ere<strong>in</strong>heitlichen, heutzutage grafischen Oberfläche – hier das XW<strong>in</strong>dow System und Motif - zusammengefaßt wer<strong>de</strong>n. Allgeme<strong>in</strong>heißt das Ganze Programmier- o<strong>de</strong>r Entwicklungsumgebung (Integrated<strong>de</strong>velopment environment, IDE). Damit zu arbeiten istdie mo<strong>de</strong>rne Form <strong>de</strong>s Programmierens und kann effektiv se<strong>in</strong>.


1.2. PROGRAMMER’S WORKBENCH 571.2.9 Systemaufrufe1.2.9.1 Was s<strong>in</strong>d Systemaufrufe?Dem Programmierer stehen zwei Hilfsmittel 17 zur Verfügung,um se<strong>in</strong>e Wünsche auszudrücken:• die Schlüsselwörter (Wortsymbole) <strong>de</strong>r Programmiersprache,• die Systemaufrufe <strong>de</strong>s Betriebssystems.Die Schlüsselwörter (keyword, mot-clé) <strong>de</strong>r Programmiersprache(C/<strong>C++</strong>, FORTRAN o<strong>de</strong>r PASCAL) s<strong>in</strong>d auch unter verschie<strong>de</strong>nenBetriebssystemen (PC-DOS, OS/2 o<strong>de</strong>r UNIX) dieselben.Sie gehören zur Programmiersprache, das heißt zum Compiler.Die Systemaufrufe (system call, system primitive, fonctionsystème) e<strong>in</strong>es Betriebssystems (UNIX) s<strong>in</strong>d für alle Programmiersprachen(C, FORTRAN, PASCAL, COBOL) dieselben. Siegehören zum Betriebssystem. Man f<strong>in</strong><strong>de</strong>t auch die BezeichnungKernschnittstellenfunktion, die besagt, dass e<strong>in</strong> solcher Aufrufsich unmittelbar an <strong>de</strong>n Kern <strong>de</strong>s Betriebssystems richtet. DerKreis <strong>de</strong>r Systemaufrufe liegt fest und kann nicht ohne E<strong>in</strong>griffe<strong>in</strong> <strong>de</strong>n Kern <strong>de</strong>s Betriebssystems verän<strong>de</strong>rt wer<strong>de</strong>n. Da UN-IX zum großen Teil <strong>in</strong> C geschrieben ist, s<strong>in</strong>d die Systemaufrufevon UNIX C-Funktionen, die sich <strong>in</strong> ihrer Syntax nicht von eigeneno<strong>de</strong>r frem<strong>de</strong>n C-Funktionen unterschei<strong>de</strong>n. Deshalb müssenauch FORTRAN- o<strong>de</strong>r PASCAL-Programmierer etwas von<strong>de</strong>r Programmiersprache C verstehen. Im Handbuch wer<strong>de</strong>n dieSystemaufrufe <strong>in</strong> Sektion (2) beschrieben.Bei POSIX-konformen Betriebssystemen spricht man stattvon Systemaufrufen besser von POSIX-Funktionen, da <strong>de</strong>rPOSIX-Standard offen lässt, ob diese vom Betriebssystem zurVerfügung gestellten Funktionen als Systemaufrufe o<strong>de</strong>r alsBibliothek verwirklicht s<strong>in</strong>d. Auf je<strong>de</strong>n Fall gehören sie zum Betriebssystem,nicht zum Compiler. Die Unterscheidung spielt e<strong>in</strong>eRolle, wenn man für verschie<strong>de</strong>ne Betriebssysteme und/o<strong>de</strong>rCompiler programmiert. Der Programmierer muss wissen, woherse<strong>in</strong>e Funktionen stammen.In Sektion (3) f<strong>in</strong><strong>de</strong>n sich vorgefertigte Unterprogramme,Subrout<strong>in</strong>en o<strong>de</strong>r Standardfunktionen (standard function,17 Standardfunktionen s<strong>in</strong>d erst verfügbar, nach<strong>de</strong>m an<strong>de</strong>reProgrammierer sie geschrieben haben.


58 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>fonction élémentaire) für häufig vorkommen<strong>de</strong> Aufgaben. Für<strong>de</strong>n Anwen<strong>de</strong>r besteht ke<strong>in</strong> Unterschied zu <strong>de</strong>n Systemaufrufen.Streng genommen gehören diese Standardfunktionen jedoch zu<strong>de</strong>n jeweiligen Programmiersprachen (zum Compiler) und nichtzum Betriebssystem. Der Kreis <strong>de</strong>r Standardfunktionen ist beliebigergänzbar. Um <strong>de</strong>n Benutzer zu verwirren, s<strong>in</strong>d die Systemaufrufeund die Standardfunktionen <strong>in</strong> e<strong>in</strong>er Funktionsbibliothek(/lib/libc.a und an<strong>de</strong>re) vere<strong>in</strong>igt.Die Aufgabenverteilung zwischen Schlüsselwörtern, Systemaufrufenund Standardfunktionen ist <strong>in</strong> gewissem Umfang willkürlich.Systemaufrufe erledigen Aufgaben, die aus <strong>de</strong>m Aufbauund <strong>de</strong>n kennzeichnen<strong>de</strong>n Eigenschaften <strong>de</strong>s Betriebssystemsherrühren, bei UNIX also <strong>in</strong> erster L<strong>in</strong>ie• E<strong>in</strong>- und Ausgabe auf unterster Stufe,• Umgang mit Prozessen,• Umgang mit <strong>de</strong>m Datei-System,• Sicherheitsvorkehrungen.Das Öffnen e<strong>in</strong>er Datei zum Lesen o<strong>de</strong>r Schreiben ist Sache e<strong>in</strong>esSystemaufrufs (open(2)), Sortieren h<strong>in</strong>gegen Sache e<strong>in</strong>er Standardfunktion(qsort(3)). Es gibt aber zusätzlich auch Standardfunktionenzum Umgang mit Dateien, die <strong>de</strong>n jeweiligenSystemaufruf komfortabel verpacken (fopen(3)). Nach außen<strong>de</strong>f<strong>in</strong>iert die Menge <strong>de</strong>r Systemaufrufe das Betriebssystem. ZweiSysteme, die <strong>in</strong> ihren Aufrufen übere<strong>in</strong>stimmen, s<strong>in</strong>d für <strong>de</strong>nBenutzer i<strong>de</strong>ntisch. Neue Funktionalitäten <strong>de</strong>s Betriebssystemsstellen sich <strong>de</strong>m Programmierer als neue Systemaufrufe dar, siehezum Beispiel unter stream(2).E<strong>in</strong>ige UNIX-Systemaufrufe haben gleiche o<strong>de</strong>r ähnliche Aufgabenwie Shell-Kommandos. Wenn man die Zeit wissen möchte,verwen<strong>de</strong>t man im Dialog das Shell-Kommando date(1). Willman diese Information aus e<strong>in</strong>em eigenen Programm heraus abfragen,greift man auf <strong>de</strong>n Systemaufruf time(2) 18 zurück. DasShell-Kommando ist e<strong>in</strong> <strong>in</strong> e<strong>in</strong> C-Programm verpackter Systemaufruf.In L<strong>in</strong>ux/UNIX s<strong>in</strong>d Systemaufrufe Funktionen <strong>de</strong>r ProgrammierspracheC. E<strong>in</strong>e Funktion übernimmt beim Aufruf Ar-18 In HP-UX. In ANSI-C ist e<strong>in</strong>e Standardfunktion time(3)enthalten.


1.2. PROGRAMMER’S WORKBENCH 59gumente o<strong>de</strong>r Parameter und gibt e<strong>in</strong> Ergebnis zurück. DieserMechanismus wird Parameterübergabe genannt. Man mussihn verstan<strong>de</strong>n haben, um Funktionen <strong>in</strong> eigenen Programmenverwen<strong>de</strong>n zu können. E<strong>in</strong>e Erklärung f<strong>in</strong><strong>de</strong>t sich im SkriptumProgrammieren <strong>in</strong> C/<strong>C++</strong>.1.2.9.2 Beispiel Systemzeit (time)Im folgen<strong>de</strong>n Beispiel wird <strong>de</strong>r Systemaufruf time(2) verwen<strong>de</strong>t.time(2) liefert die Zeit <strong>in</strong> Sekun<strong>de</strong>n seit 00:00:00 GreenwichMean Time, 1. Januar 1970. Computeruhren laufen übrigenserstaunlich ungenau, falls sie nicht durch e<strong>in</strong>e Funkuhro<strong>de</strong>r über das Netz synchronisiert wer<strong>de</strong>n. Ferner brauchenwir die Standardfunktion gmtime(3), Beschreibung unterctime(3), die aus <strong>de</strong>n obigen Sekun<strong>de</strong>n e<strong>in</strong>e Struktur erzeugt,die Datum und Uhrzeit enthält. Die Umrechnung von Greenwichauf Karlsruhe nehmen wir selbst vor. Eleganter wäre e<strong>in</strong> Rückgriffauf die Zeitzonen-Variable <strong>de</strong>r Umgebung. Laut Referenz-Handbuch hat time(2) die Syntaxlong time ((long *) 0)Die Funktion verlangt e<strong>in</strong> Argument vom Typ Po<strong>in</strong>ter auf long<strong>in</strong>teger, und zwar im e<strong>in</strong>fachsten Fall <strong>de</strong>n Nullpo<strong>in</strong>ter. Der Returnwertist vom Typ long <strong>in</strong>teger. Der größte Wert dieses Typsliegt etwas über 2 Milliar<strong>de</strong>n. Damit läuft diese Uhr etwa 70Jahre. Die Subrout<strong>in</strong>e gmtime(3) hat die Syntax#<strong>in</strong>clu<strong>de</strong> struct tm *gmtime(clock)long *clockDie Funktion gmtime(3) verlangt e<strong>in</strong> Argument clock vomTyp Po<strong>in</strong>ter auf long <strong>in</strong>teger. Wir müssen also <strong>de</strong>n Returnwertvon time(2) <strong>in</strong> e<strong>in</strong>en Po<strong>in</strong>ter umwan<strong>de</strong>ln (referenzieren). DerRückgabewert <strong>de</strong>r Funktion gmtime(3) ist e<strong>in</strong> Po<strong>in</strong>ter auf e<strong>in</strong>eStruktur namens tm. Diese Struktur ist <strong>in</strong> <strong>de</strong>r <strong>in</strong>clu<strong>de</strong>-Dateitime.h <strong>de</strong>f<strong>in</strong>iert. Die <strong>in</strong>clu<strong>de</strong>-Dateien s<strong>in</strong>d lesbarer Text; esist ratsam h<strong>in</strong>e<strong>in</strong>zuschauen. In <strong>de</strong>r weiteren Beschreibung zuctime(3) wird die Struktur tm erläutert:


60 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>struct tm {<strong>in</strong>t tm_sec; /* seconds (0 - 59) */<strong>in</strong>t tm_m<strong>in</strong>; /* m<strong>in</strong>utes (0 - 59) */<strong>in</strong>t tm_hour; /* hours (0 - 23) */<strong>in</strong>t tm_mday; /* day of month (1 - 31) */<strong>in</strong>t tm_mon; /* month of year (0 - 11) */<strong>in</strong>t tm_year; /* year - 1900 */<strong>in</strong>t tm_wday; /* day of week (sunday = 0) */<strong>in</strong>t tm_yday; /* day of year (0 - 365) */<strong>in</strong>t tm_isdst; /* daylight sav<strong>in</strong>g time */}Von <strong>de</strong>n bei<strong>de</strong>n letzten Komponenten <strong>de</strong>r Struktur machen wirke<strong>in</strong>en Gebrauch. Da die Komponenten alle vom selben Typ s<strong>in</strong>d,ist statt <strong>de</strong>r Struktur auch e<strong>in</strong> Array <strong>de</strong>nkbar. Vermutlich wolltesich <strong>de</strong>r Programmierer <strong>de</strong>n Weg offenhalten, künftig auchan<strong>de</strong>re Typen aufzunehmen (Zeitzone). Das Programm, das dieQuelle zu <strong>de</strong>m Kommando zeit aus <strong>de</strong>r ersten Übung ist, siehtfolgen<strong>de</strong>rmaßen aus:/* Ausgabe <strong>de</strong>r Zeit auf Bildschirm *//* Compileraufruf cc -o zeit zeit.c */#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> char *ptag[] = {"Sonntag, ", "Montag, ","Dienstag, ", "Mittwoch, ","Donnerstag,", "Freitag, ","Samstag, "};char *pmon[] = {"Januar", "Februar", "Maerz", "April","Mai", "Juni", "Juli", "August","September", "Oktober", "November","Dezember"};ma<strong>in</strong>(){long sec, time();struct tm *gmtime(), *p;sec = time((long *) 0) + 3600; /* MEZ = GMT + 3600 */p = gmtime(&sec);pr<strong>in</strong>tf("%s %d. ", ptag[p->tm wday], p->tm mday);pr<strong>in</strong>tf("%s %d ", pmon[p->tm mon], p->tm year +1900);


1.2. PROGRAMMER’S WORKBENCH 61pr<strong>in</strong>tf("%d:%02d MEZ\n", p->tm hour, p->tm m<strong>in</strong>);}Quelle 1.16 : C-Programm zur Anzeige <strong>de</strong>r SystemzeitNun wollen wir dieselbe Aufgabe mit e<strong>in</strong>em FORTRAN-Programm bewältigen. Der UNIX-Systemaufruf time(2) bleibt,für die C-Standardfunktion gmtime(3) suchen wir die entsprechen<strong>de</strong>FORTRAN-Rout<strong>in</strong>e. Da wir ke<strong>in</strong>e f<strong>in</strong><strong>de</strong>n, müssenwir sie entwe<strong>de</strong>r selbst schreiben (was <strong>de</strong>r erfahrene Programmiererscheut) o<strong>de</strong>r nach e<strong>in</strong>em Weg suchen, e<strong>in</strong>e beliebige C-Standardfunktion <strong>in</strong> e<strong>in</strong> FORTRAN-Programm h<strong>in</strong>e<strong>in</strong>zuquetschen.Der Systemaufruf time(2) macht ke<strong>in</strong>en Kummer. Er benötigte<strong>in</strong> Argument vom Typ Po<strong>in</strong>ter auf long <strong>in</strong>teger, was es<strong>in</strong> FORTRAN gibt. Der Rückgabewert ist vom Typ long <strong>in</strong>teger,auch ke<strong>in</strong> Problem. Die C-Standardfunktion gmtime(3) erwartete<strong>in</strong> Argument vom Typ Po<strong>in</strong>ter auf long <strong>in</strong>teger, was machbarwäre, aber ihr Ergebnis ist e<strong>in</strong> Po<strong>in</strong>ter auf e<strong>in</strong>e Struktur. Dashat FORTRAN noch nie gesehen 19 . Deshalb weichen wir auf dieC-Standardfunktion ctime(3) aus, <strong>de</strong>ren Rückgabewert vomTyp Po<strong>in</strong>ter auf character ist, was es <strong>in</strong> FORTRAN näherungsweisegibt. In FORTRAN ist e<strong>in</strong> Zeichen e<strong>in</strong> Str<strong>in</strong>g <strong>de</strong>r Längee<strong>in</strong>s. Str<strong>in</strong>gs wer<strong>de</strong>n per Deskriptor übergeben. E<strong>in</strong> Str<strong>in</strong>g-Deskriptor ist <strong>de</strong>r Po<strong>in</strong>ter auf das erste Zeichen und die Anzahl<strong>de</strong>r Zeichen im Str<strong>in</strong>g als Integerwert. Das Programm sieht dannso aus:program zeit$ALIAS foratime = ’spr<strong>in</strong>tf’ c<strong>in</strong>teger*4 time, tloc, sec, ctimecharacter atime*26sec = time(tloc)call foratime(atime, ’%s’//char(0), ctime(sec))write(6, ’(a)’) atimeend19 FORTRAN 90 kennt Strukturen.


62 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Quelle 1.17 : FORTRAN-Programm zur Anzeige <strong>de</strong>r SystemzeitDie ALIAS-Anweisung ist als Erweiterung zu FORTRAN77 <strong>in</strong> vielen Compilern enthalten und dient dazu, <strong>de</strong>n Aufrufvon Unterprogrammen an<strong>de</strong>rer Sprachen zu ermöglichen. DerCompiler weiß damit, dass das Unterprogramm außerhalb <strong>de</strong>sProgramms – zum Beispiel <strong>in</strong> e<strong>in</strong>er Bibliothek – e<strong>in</strong>en an<strong>de</strong>renNamen hat als <strong>in</strong>nerhalb <strong>de</strong>s Programms. Wird e<strong>in</strong>e Sprache angegeben(hier C), so erfolgt die Parameterübergabe gemäß <strong>de</strong>rSyntax dieser Sprache. E<strong>in</strong>zelheiten siehe im Falle unserer Anlageim HP FORTRAN 77/HP-UX Reference Manual im AbschnittCompiler Directives.Die Anweisung teilt <strong>de</strong>m Compiler mit, dass h<strong>in</strong>ter<strong>de</strong>r FORTRAN-Subrout<strong>in</strong>e foratime die C-Standard-Funktionspr<strong>in</strong>tf(3) steckt und dass diese nach <strong>de</strong>n Regeln von C behan<strong>de</strong>ltwer<strong>de</strong>n soll. Der Rückgabewert von spr<strong>in</strong>tf(3) (dieAnzahl <strong>de</strong>r ausgegebenen Zeichen) wird nicht verwertet, <strong>de</strong>shalbist foratime e<strong>in</strong>e FORTRAN-Subrout<strong>in</strong>e (ke<strong>in</strong>e Funktion), dieim Programm mit call aufgerufen wer<strong>de</strong>n muss.Der Systemaufruf time(2) verlangt als Argument e<strong>in</strong>enPo<strong>in</strong>ter auf long <strong>in</strong>teger, daher ist tloc als vier Bytes langeIntegerzahl <strong>de</strong>klariert. tloc spielt weiter ke<strong>in</strong>e Rolle. Die Übergabeals Po<strong>in</strong>ter (by reference) ist <strong>in</strong> FORTRAN Standard fürZahlenvariable und braucht nicht eigens vere<strong>in</strong>bart zu wer<strong>de</strong>n.Der Rückgabewert von time geht <strong>in</strong> die Variable sec vom Typlong <strong>in</strong>teger = <strong>in</strong>teger*4.Die call-Zeile ruft die Subrout<strong>in</strong>e foratime alias C-Funktion spr<strong>in</strong>tf(3) auf. Diese C-Funktion erwartet drei Argumente:<strong>de</strong>n Ausgabestr<strong>in</strong>g als Po<strong>in</strong>ter auf char, e<strong>in</strong>en Formatstr<strong>in</strong>gals Po<strong>in</strong>ter auf char und die auszugeben<strong>de</strong> Variable vone<strong>in</strong>em Typ, wie er durch <strong>de</strong>n Formatstr<strong>in</strong>g bezeichnet wird. DerRückgabewert <strong>de</strong>r Funktion ctime(3) ist e<strong>in</strong> Po<strong>in</strong>ter auf char.Da dies ke<strong>in</strong> <strong>in</strong> FORTRAN zulässiger Typ ist, <strong>de</strong>klarieren wirdie Funktion ersatzweise als vom Typ 4-Byte-<strong>in</strong>teger. Der Po<strong>in</strong>terlässt sich auf je<strong>de</strong>n Fall <strong>in</strong> <strong>de</strong>n vier Bytes unterbr<strong>in</strong>gen. Nachunserer Erfahrung reichen auch zwei Bytes, ebenso funktioniert<strong>de</strong>r Typ logical, nicht jedoch real.Der Formatstr<strong>in</strong>g besteht aus <strong>de</strong>r Str<strong>in</strong>gkonstanten %s, gefolgtvon <strong>de</strong>m ASCII-Zeichen Nr. 0, wie es bei Str<strong>in</strong>gs <strong>in</strong> CBrauch ist. Für spr<strong>in</strong>tf(3) besagt dieser Formatstr<strong>in</strong>g, das


1.2. PROGRAMMER’S WORKBENCH 63dritte Argument – <strong>de</strong>n Rückgabewert von ctime(3) – als e<strong>in</strong>enStr<strong>in</strong>g aufzufassen, das heißt als Po<strong>in</strong>ter auf das erste Elemente<strong>in</strong>es Arrays of characters.atime ist e<strong>in</strong> FORTRAN-Str<strong>in</strong>g-Deskriptor, <strong>de</strong>ssen ersteKomponente e<strong>in</strong> Po<strong>in</strong>ter auf character ist. Damit weißspr<strong>in</strong>tf(3), woh<strong>in</strong> mit <strong>de</strong>r Ausgabe. Die write-Zeile ist wie<strong>de</strong>rpures FORTRAN.An diesem Beispiel erkennen Sie, dass Sie auch alsFORTRAN- o<strong>de</strong>r PASCAL-Programmierer etwas von C verstehenmüssen, um die Systemaufrufe und C-Standardfunktionensyntaktisch richtig zu gebrauchen.Bei manchen FORTRAN-Compilern (Hewlett-Packard, Microsoft)lassen sich durch e<strong>in</strong>en e<strong>in</strong>fachen Interface-AufrufRout<strong>in</strong>en frem<strong>de</strong>r Sprachen so verpacken, dass man sie übernehmenkann, ohne sich um E<strong>in</strong>zelheiten kümmern zu müssen.1.2.9.3 Beispiel Datei-Informationen (access, stat, open,close)In e<strong>in</strong>em weiteren Beispiel wollen wir mithilfe von SystemaufrufenInformationen über e<strong>in</strong>e Fatei gew<strong>in</strong>nen, dazu noch e<strong>in</strong>eAngabe aus <strong>de</strong>r Sitzungsumgebung. Die Teile <strong>de</strong>s Programmslassen sich e<strong>in</strong>fach <strong>in</strong> an<strong>de</strong>re C-Programme übernehmen.Dieses Programm soll beim Aufruf (zur Laufzeit, <strong>in</strong> <strong>de</strong>r Kommandozeile)<strong>de</strong>n Namen <strong>de</strong>r Datei als Argument übernehmen,wie wir es von UNIX-Kommandos her kennen. Dazu ist e<strong>in</strong> bestimmterFormalismus vorgesehen:<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[], char *envp[])Die Funktion ma<strong>in</strong>() übernimmt die Argumente argc, argvund gegebenenfalls envp. Das Argument argc ist <strong>de</strong>r ArgumentCounter, e<strong>in</strong>e Ganzzahl. Sie ist gleich <strong>de</strong>r Anzahl <strong>de</strong>rArgumente <strong>in</strong> <strong>de</strong>r Kommandozeile beim Aufruf <strong>de</strong>s Programms.Das Kommando selbst ist das erste Argument, also hat argcm<strong>in</strong><strong>de</strong>stens <strong>de</strong>n Wert 1. Das Argument argv ist <strong>de</strong>r ArgumentVector, e<strong>in</strong> Array of Str<strong>in</strong>gs, also e<strong>in</strong> Array of Arrays of Characters.Der erste Str<strong>in</strong>g, In<strong>de</strong>x 0, ist das Kommando; die weiterenStr<strong>in</strong>gs s<strong>in</strong>d die mit <strong>de</strong>m Kommando übergebenen Argumente,hier <strong>de</strong>r Name <strong>de</strong>r gefragten Datei. Der Environment Po<strong>in</strong>ter


64 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>envp wird nur benötigt, falls man Werte aus <strong>de</strong>r Umgebung abfragt.Es ist wie argv e<strong>in</strong> Array of Str<strong>in</strong>gs. Die Namen argc,argv und envp s<strong>in</strong>d willkürlich, aber üblich. Typ und Reihenfolges<strong>in</strong>d vorgegeben.Die Umgebung besteht aus Str<strong>in</strong>gs (mit Kommandoset (Shell) anschauen). In <strong>de</strong>r for-Schleife wer<strong>de</strong>n dieStr<strong>in</strong>gs nache<strong>in</strong>an<strong>de</strong>r mittels <strong>de</strong>r Funktion strncmp(3) (siehestr<strong>in</strong>g(3)) mit <strong>de</strong>m Str<strong>in</strong>g LOGNAME verglichen. Das Ergebnisist <strong>de</strong>r In<strong>de</strong>x i <strong>de</strong>s gesuchten Str<strong>in</strong>gs im Array envp[].Den Systemaufruf access(2) f<strong>in</strong><strong>de</strong>n wir <strong>in</strong> <strong>de</strong>r Sektion (2)<strong>de</strong>s Referenz-Handbuches. Er untersucht die Zugriffsmöglichkeitenauf e<strong>in</strong>e Datei und hat die Syntax:<strong>in</strong>t access(char *path, <strong>in</strong>t mo<strong>de</strong>)Der Systemaufruf erwartet als erstes Argument e<strong>in</strong>en Str<strong>in</strong>g,nämlich <strong>de</strong>n Namen <strong>de</strong>r Datei. Wir wer<strong>de</strong>n hierfür argv[1] e<strong>in</strong>setzen.Als zweites steht e<strong>in</strong>e Ganzzahl, die die Art <strong>de</strong>s gefragtenZugriffs kennzeichnet. Falls <strong>de</strong>r gefragte Zugriff möglich ist, liefertaccess(2) <strong>de</strong>n Wert null zurück, <strong>de</strong>r <strong>in</strong> e<strong>in</strong>em C-Programmzugleich die Be<strong>de</strong>utung von logisch falsch (FALSE) hat und <strong>de</strong>shalb<strong>in</strong> <strong>de</strong>n if-Zeilen negiert wird.Den Systemaufruf stat(2) f<strong>in</strong><strong>de</strong>n wir ebenfalls <strong>in</strong> Sektion2. Er ermittelt Datei<strong>in</strong>formationen aus <strong>de</strong>r Ino<strong>de</strong> und hat dieSyntax#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t stat(path, buf)char *path;struct stat *buf;Se<strong>in</strong> erstes Argument ist wie<strong>de</strong>r <strong>de</strong>r Date<strong>in</strong>ame, das zweite<strong>de</strong>r Name e<strong>in</strong>es Puffers zur Aufnahme e<strong>in</strong>er Struktur,die die Informationen enthält. Diese Struktur vom Typstat ist <strong>in</strong> <strong>de</strong>r <strong>in</strong>clu<strong>de</strong>-Datei /usr/<strong>in</strong>clu<strong>de</strong>/sys/stat.h<strong>de</strong>klariert, das se<strong>in</strong>erseits Bezug nimmt auf Deklarationen<strong>in</strong> /usr/<strong>in</strong>clu<strong>de</strong>/types.h. Auch e<strong>in</strong>ige Informationen wieS_IFREG s<strong>in</strong>d <strong>in</strong> sys/stat.h <strong>de</strong>f<strong>in</strong>iert. Die Zeitangaben wer<strong>de</strong>nwie im vorigen Abschnitt umgerechnet.


1.2. PROGRAMMER’S WORKBENCH 65In UNIX-Datei-Systemen enthält je<strong>de</strong> Datei am Anfang e<strong>in</strong>eMagic Number, die über die Art <strong>de</strong>r Datei Auskunft gibt(man magic). Mittels <strong>de</strong>s Systemaufrufs open(2) wird die fraglicheDatei zum Lesen geöffnet, mittels lseek(2) <strong>de</strong>r Lesezeigerauf die Magic Number gesetzt und mittels read(2) die Zahlgelesen. Der Systemaufruf close(2) schließt die Datei wie<strong>de</strong>r.Die Systemaufrufe f<strong>in</strong><strong>de</strong>t man unter ihren Namen <strong>in</strong> Sektion (2),e<strong>in</strong>e Erläuterung <strong>de</strong>r Magic Numbers unter magic(4). Nun dasProgramm:/* Informationen ueber e<strong>in</strong>e Datei */#<strong>de</strong>f<strong>in</strong>e MEZ 3600#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> void exit(); long lseek();<strong>in</strong>t ma<strong>in</strong>(argc, argv, envp){<strong>in</strong>t argc; char *argv[], *envp[];<strong>in</strong>t i, fil<strong>de</strong>s;struct stat buffer;long asec, msec, csec;struct tm *pa, *pm, *pc;if (argc < 2) {puts("Date<strong>in</strong>ame fehlt"); return (-1);}/* Informationen aus <strong>de</strong>m Environment */for (i = 0; envp[i] != NULL; i++)if (!(strncmp(envp[i], "LOGNAME", 4)))pr<strong>in</strong>tf("\n%s\n", envp[i]);/* Informationen mittels Systemaufruf access(2) */


66 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>pr<strong>in</strong>tf("\nFile heisst: %8s\n", argv[1]);if (!access(argv[1], 0))puts("File existiert");elseputs("File existiert nicht");if (!access(argv[1], 1))puts("File darf ausgefuehrt wer<strong>de</strong>n");elseputs("File darf nicht ausgefuehrt wer<strong>de</strong>n");if (!access(argv[1], 2))puts("File darf beschrieben wer<strong>de</strong>n");elseputs("File darf nicht beschrieben wer<strong>de</strong>n");if (!access(argv[1], 4))puts("File darf gelesen wer<strong>de</strong>n");elseputs("File darf nicht gelesen wer<strong>de</strong>n");/* Informationen aus <strong>de</strong>r Ino<strong>de</strong>, Systemaufruf stat(2) */if (!(stat(argv[1], &buffer))) {pr<strong>in</strong>tf("\nDevice:%ld\n", buffer.st <strong>de</strong>v);pr<strong>in</strong>tf("Ino<strong>de</strong>-Nr.: %lu\n", buffer.st <strong>in</strong>o);pr<strong>in</strong>tf("File Mo<strong>de</strong>: %hu\n\n", buffer.st mo<strong>de</strong>);switch(buffer.st mo<strong>de</strong> & S IFMT) {case S IFREG:{puts("File ist regulaer");break;}case S IFDIR:{puts("File ist e<strong>in</strong> Verzeichnis");break;}case S IFCHR:case S IFBLK:case S IFNWK:{puts("File ist e<strong>in</strong> Special File");


1.2. PROGRAMMER’S WORKBENCH 67break;}case S IFIFO:{puts("File ist e<strong>in</strong>e Pipe");break;}<strong>de</strong>fault:{puts("Filetyp unbekannt (Ino<strong>de</strong>)");}}pr<strong>in</strong>tf("\nL<strong>in</strong>ks:%hd\n", buffer.st nl<strong>in</strong>k);pr<strong>in</strong>tf("Owner-ID: %hu\n", buffer.st uid);pr<strong>in</strong>tf("Group-Id: %hu\n", buffer.st gid);pr<strong>in</strong>tf("Device-ID: %ld\n", buffer.st r<strong>de</strong>v);pr<strong>in</strong>tf("Filegroesse: %ld\n", buffer.st size);asec = buffer.st atime + MEZ; pa = gmtime(&asec);msec = buffer.st mtime + MEZ; pm = gmtime(&msec);csec = buffer.st ctime + MEZ; pc = gmtime(&csec);pr<strong>in</strong>tf("Letzter Zugriff: %d. %d. %d\n",pa->tm mday, pa->tm mon + 1, pa->tm year);pr<strong>in</strong>tf("Letzte Modifik.: %d. %d. %d\n",pm->tm mday, pm->tm mon + 1, pm->tm year);pr<strong>in</strong>tf("Letzte Stat.Ae.: %d. %d. %d\n",pc->tm mday, pc->tm mon + 1, pc->tm year);}elseputs("Ke<strong>in</strong> Zugriff auf Ino<strong>de</strong>");/* Pruefung auf Text o<strong>de</strong>r Co<strong>de</strong> (magic number) *//* Systemaufrufe open(2), lseek(2), read(2), close(2) *//* Magic Numbers siehe magic(4) */{MAGICmagbuf;fil<strong>de</strong>s = open(argv[1], O RDONLY);if (lseek(fil<strong>de</strong>s, MAGIC OFFSET, 0) >= (long)0) {read(fil<strong>de</strong>s, &magbuf, sizeof magbuf);switch(magbuf.file type) {case RELOC MAGIC:{


68 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>puts("File ist relocatable");break;}case EXEC MAGIC:case SHARE MAGIC:case DEMAND MAGIC:{puts("File ist executable");break;}case DL MAGIC:case SHL MAGIC:{puts("File ist Library");break;}<strong>de</strong>fault:puts("Filetyp unbekannt (Magic Number)");lseek(fil<strong>de</strong>s, 0L, 0);}}else {puts("Probleme mit <strong>de</strong>m Filepo<strong>in</strong>ter");}}close(fil<strong>de</strong>s);}Quelle 1.18 : C-Programm zum Abfragen von Informationen übere<strong>in</strong>e DateiDie Verwendung von Systemaufrufen o<strong>de</strong>r Standardfunktionen<strong>in</strong> C-Programmen ist nicht schwieriger als <strong>de</strong>r Gebrauchan<strong>de</strong>rer Funktionen. Man muss sich nur an die im Referenz-Handbuch Sektionen (2) und (3) nachzulesen<strong>de</strong> Syntax halten.Es empfiehlt sich, die genannten Sektionen e<strong>in</strong>mal durchzublättern,um e<strong>in</strong>e Vorstellung davon zu gew<strong>in</strong>nen, wofür es Systemaufrufeund Standardfunktionen gibt. Die Ausgabe <strong>de</strong>s Programmssieht folgen<strong>de</strong>rmaßen aus:LOGNAME=wualex1Datei heisst:Datei existierta.out


1.2. PROGRAMMER’S WORKBENCH 69Datei darf ausgefuehrt wer<strong>de</strong>n.Datei darf nicht beschrieben wer<strong>de</strong>n.Datei darf gelesen wer<strong>de</strong>n.Device: 13Ino<strong>de</strong>-Nr.: 43787File Mo<strong>de</strong>: 33216Datei ist regulaerL<strong>in</strong>ks: 1Owner-ID: 101Group-ID: 20Device-ID: 102536Dateigroesse: 53248Letzter Zugriff: 24. 1. 91Letzte Modifik.: 24. 1. 91Letzte Stat.Ae.: 24. 1. 91Datei ist executableDie Be<strong>de</strong>utung von File Mo<strong>de</strong> f<strong>in</strong><strong>de</strong>n Sie bei mknod(2). Eshan<strong>de</strong>lt sich um ausführliche Informationen über die Zugriffsrechteusw. Ähnliche Auskünfte über e<strong>in</strong>e Datei liefert das Kommandochatr(1).1.2.9.4 Beispiel Prozesserzeugung (exec, fork)Zunächst e<strong>in</strong> kle<strong>in</strong>es, aber fieses Programm namens forkbomb,mit <strong>de</strong>m man die Robustheit se<strong>in</strong>es Systems auf die Probe stellenkann.(kommt <strong>de</strong>mnaechst)Quelle 1.19 : C-Programm zum Erzeugen vieler Prozesse (Fork-Bombe)Der Systemaufruf fork(2) erzeugt e<strong>in</strong>e Kopie <strong>de</strong>s aufrufen<strong>de</strong>nProzesses mit e<strong>in</strong>er neuen Prozess-ID. Im Beispiel wirdfork(2) <strong>in</strong> e<strong>in</strong>er ewigen for-Schleife aufgerufen.


70 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.2.10 Begriffe Programmer’s WorkbenchFolgen<strong>de</strong> Begriffe sollten klarer gewor<strong>de</strong>n se<strong>in</strong>:• Archiv, Bibliothek• Buil<strong>de</strong>r (make)• Debugger• L<strong>in</strong>ker• Profiler• Quelltext o<strong>de</strong>r -co<strong>de</strong>, ausführbarer Co<strong>de</strong>• Übersetzer, Compiler, Interpreter• Systemaufruf – Standardfunktion• VersionsverwaltungFolgen<strong>de</strong> Kommandos sollten beherrscht wer<strong>de</strong>n:• cc o<strong>de</strong>r gcc• l<strong>in</strong>t• Anfänge von make• Anfänge von RCS (ci, co)1.2.11 Memo Programmer’s Workbench• Die Programmquellen wer<strong>de</strong>n mit e<strong>in</strong>em Editor geschrieben.• Mit <strong>de</strong>m Syntaxprüfer l<strong>in</strong>t(1) läßt sich die syntaktischeRichtigkeit von C-Programmen prüfen, lei<strong>de</strong>r nicht die von<strong>C++</strong>-Programmen.• Schon bei kle<strong>in</strong>en Programmierprojekten ist das Werkzeugmake(1) dr<strong>in</strong>gend zu empfehlen. Der Compileraufruf vere<strong>in</strong>fachtsich wesentlich. Auch für Texte verwendbar.• Mit e<strong>in</strong>em Compiler wird <strong>de</strong>r Quellco<strong>de</strong> <strong>in</strong> <strong>de</strong>n Masch<strong>in</strong>enco<strong>de</strong><strong>de</strong>s jeweiligen Prozessors übersetzt.• Der schwerste Hammer bei <strong>de</strong>r Fehlersuche ist e<strong>in</strong> Debugger,lernbedürftig, aber nicht immer vermeidbar.• Programmfunktionen (aber auch an<strong>de</strong>re Dateien) lassensich <strong>in</strong> Bibliotheken archivieren, die bequemer zu handhabens<strong>in</strong>d als e<strong>in</strong>e Menge von e<strong>in</strong>zelnen Funktionen.


1.2. PROGRAMMER’S WORKBENCH 71• Bei größeren Projekten kommt man nicht um e<strong>in</strong> Kontrollsystemwie RCS o<strong>de</strong>r CVS herum, vor allem dann, wennmehrere Personen beteiligt s<strong>in</strong>d. Das Lernen kostet Zeit,die aber beim R<strong>in</strong>gen mit <strong>de</strong>m Chaos mehr als wettgemachtwird.• CASE-Tools vere<strong>in</strong>igen die e<strong>in</strong>zelnen Werkzeuge unter e<strong>in</strong>ergeme<strong>in</strong>samen Benutzeroberfläche. Der Programmiererbraucht gar nicht mehr zu wissen, was e<strong>in</strong> Compiler ist.• Systemaufrufe s<strong>in</strong>d die Verb<strong>in</strong>dungen <strong>de</strong>s Betriebssystemsnach oben, zu <strong>de</strong>n Anwendungsprogrammen h<strong>in</strong>. Sie s<strong>in</strong>dTeil <strong>de</strong>s Betriebssystems.• Systemaufrufe haben vorwiegend mit Prozessen, <strong>de</strong>nDatei-Systemen und <strong>de</strong>r E<strong>in</strong>- und Ausgabe zu tun.• UNIX-Systemaufrufe s<strong>in</strong>d C-Funktionen, die sich im Gebrauchnicht von an<strong>de</strong>ren C-Funktionen unterschei<strong>de</strong>n.• C-Standardfunktionen gehören zum C-Compiler, nicht zumBetriebssystem.• E<strong>in</strong> FORTRAN-Programmierer auf e<strong>in</strong>em UNIX-Systemist auf die UNIX-Systemaufrufe angewiesen, nicht aberauf die C-Standardfunktionen (dafür gibt es FORTRAN-Standardfunktionen). Dasselbe gilt für je<strong>de</strong> an<strong>de</strong>re Programmiersprache.1.2.12 Übung Programmer’s WorkbenchAnmel<strong>de</strong>n wie gewohnt. Zum Üben brauchen wir e<strong>in</strong> kle<strong>in</strong>es Programmmit bestimmten Fehlern. Legen Sie mit mkdir prog e<strong>in</strong>Unterverzeichnis prog an, wechseln Sie mit cd prog dorth<strong>in</strong>und geben Sie mit vi fehler.c folgen<strong>de</strong>s C-Programm (ohne<strong>de</strong>n Kommentar) unter <strong>de</strong>m Namen fehler.c e<strong>in</strong>:/* Uebungsprogramm mit mehreren Fehlern *//* 1. Fehler: Es wird e<strong>in</strong>e symbolische Konstante PI<strong>de</strong>f<strong>in</strong>iert, die nicht gebraucht wird. Dieser Fehlerhat ke<strong>in</strong>e Auswirkungen und wird von ke<strong>in</strong>emProgramm bemerkt.2. Fehler: E<strong>in</strong>e Ganzzahl-Variable d wird <strong>de</strong>klariert,aber nicht gebraucht. Dieser Fehler hat ke<strong>in</strong>e


72 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Auswirkungen, wird aber von l<strong>in</strong>t beanstan<strong>de</strong>t.3. Fehler: Die Funktion scanf verlangt Po<strong>in</strong>ter alsArgument, es muss &a heissen. HeimtueckischerSyntaxfehler. l<strong>in</strong>t gibt e<strong>in</strong>e irrefuehren<strong>de</strong> Warnungaus, <strong>de</strong>r Compiler merkt nichts. Zur Laufzeit e<strong>in</strong>memory fault.4. Fehler: Es wird durch nichts verh<strong>in</strong><strong>de</strong>rt, dass fuerb e<strong>in</strong>e Null e<strong>in</strong>gegeben wird. Das kann zu e<strong>in</strong>emLaufzeitfehler fuehren, wird we<strong>de</strong>r von l<strong>in</strong>t nochvom Compiler bemerkt.5. Fehler: Es sollte die Summe ausgerechnet wer<strong>de</strong>n,nicht <strong>de</strong>r Quotient. Logischer Fehler, wird we<strong>de</strong>rvon l<strong>in</strong>t noch vom Compiler bemerkt.6. Fehler: Abschliessen<strong>de</strong> Klammer fehlt. Syntaxfehler,wird von l<strong>in</strong>t und Compiler beanstan<strong>de</strong>t.Darueberh<strong>in</strong>aus spricht l<strong>in</strong>t noch H<strong>in</strong>weise bezueglichma<strong>in</strong>, pr<strong>in</strong>tf und scanf aus. Diese Funktionen s<strong>in</strong>daber <strong>in</strong> Ordnung, Warnungen ueberhoeren. */#<strong>de</strong>f<strong>in</strong>e PI 3.14159#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t a, b, c, d;puts("Bitte 1. Summan<strong>de</strong>n e<strong>in</strong>geben: ");scanf("%d", a);puts("Bitte 2. Summan<strong>de</strong>n e<strong>in</strong>geben: ");scanf("%d", &b);c = a / b;pr<strong>in</strong>tf("Die Summe ist: %d\n", c);Quelle 1.20 : C-Programm mit FehlernAls erstes lassen wir <strong>de</strong>n Syntaxprüfer l<strong>in</strong>t(1) auf das Programmlos:l<strong>in</strong>t fehler.cund erhalten das Ergebnis:fehler.c


1.2. PROGRAMMER’S WORKBENCH 73==============(36) warn<strong>in</strong>g: a may be used before set(41) syntax error(41) warn<strong>in</strong>g: ma<strong>in</strong>() returns random value to environment==============function returns value which is always ignoredpr<strong>in</strong>tf scanfZeile 41 ist das Programmen<strong>de</strong>, dort steckt e<strong>in</strong> Fehler. Die Warnungens<strong>in</strong>d nicht so dr<strong>in</strong>gend. Mit <strong>de</strong>m vi(1) ergänzen wirdie fehlen<strong>de</strong> geschweifte Klammer am Schluß. Der Fehler hätteuns eigentlich nicht unterlaufen dürfen, da <strong>de</strong>r vi(1) e<strong>in</strong>eHilfe zur Klammerprüfung bietet (Prozentzeichen). Neuer Laufvon l<strong>in</strong>t(1):fehler.c==============(36) warn<strong>in</strong>g: a may be used before set(33) warn<strong>in</strong>g: d unused <strong>in</strong> function ma<strong>in</strong>(41) warn<strong>in</strong>g: ma<strong>in</strong>() returns random value to environment==============function returns value which is always ignoredpr<strong>in</strong>tf scanfWir werfen die überflüssige Variable d <strong>in</strong> <strong>de</strong>r Deklaration heraus.Nochmals l<strong>in</strong>t(1).fehler.c==============(36) warn<strong>in</strong>g: a may be used before set(41) warn<strong>in</strong>g: ma<strong>in</strong>() returns random value to environment==============function returns value which is always ignoredpr<strong>in</strong>tf scanfJetzt ignorieren wir die Warnung von l<strong>in</strong>t(1) bezüglich <strong>de</strong>rVariablen a (obwohl heimtückischer Fehler, aber das ahnen wirnoch nicht). Wir lassen kompilieren und rufen das kompilierteProgramm a.out(4) auf:


74 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>cc fehler.ca.outDer Compiler hat nichts zu beanstan<strong>de</strong>n. ErstenSumman<strong>de</strong>n e<strong>in</strong>geben, Antwort: memory fault o<strong>de</strong>rBus error - core dumped. Debugger 20 e<strong>in</strong>setzen, dazunochmals mit <strong>de</strong>r Option -g und <strong>de</strong>m vom Debugger verwen<strong>de</strong>tenObjektfile /usr/lib/xdbend.o kompilieren undanschließend laufen lassen, um e<strong>in</strong>en aktuellen Speicherauszug(Coredump) zu erzeugen:cc -g fehler.c /usr/lib/xdbend.ochmod 700 a.outa.outxdbStandardmäßig greift <strong>de</strong>r Debugger auf die ausführbare Dateia.out(4) und das beim Zusammenbruch erzeugte Corefilecore(4) zurück. Er promptet mit >. Wir wählen mit <strong>de</strong>rE<strong>in</strong>gabe s E<strong>in</strong>zelschritt-Ausführung. Mehrmals mit RETURNweitergehen, bis Auffor<strong>de</strong>rung zur E<strong>in</strong>gabe von a kommt (ke<strong>in</strong>Prompt). Irgen<strong>de</strong><strong>in</strong>en Wert für a e<strong>in</strong>geben. Fehlermeldung <strong>de</strong>sDebuggers Bus error. Wir holen uns weitere Informationenvom Debugger:Tsq(stack view<strong>in</strong>g)(E<strong>in</strong>zelschritt)(quit)Nach<strong>de</strong>m wir wissen, daß <strong>de</strong>r Fehler nach <strong>de</strong>r E<strong>in</strong>gabe von aauftritt, schauen wir uns die Zeile mit scanf( ..., a) an undbemerken, daß wir <strong>de</strong>r Funktion scanf(3) e<strong>in</strong>e Variable statte<strong>in</strong>es Po<strong>in</strong>ters übergeben haben (man scanf o<strong>de</strong>r im Anhangnachlesen). Wir ersetzen also a durch &a. Das Compilieren erleichternwir uns durch make(1). Wir schreiben e<strong>in</strong>e Datei namensmakefile mit folgen<strong>de</strong>n Zeilen:fehler: fehler.ccc fehler.c -o fehler20 Real programmers can read core dumps.


1.2. PROGRAMMER’S WORKBENCH 75und rufen anschließend nur noch das Kommando make(1) ohneArgumente auf. Das Ergebnis ist e<strong>in</strong> lauffähiges Programmmit Namen fehler. Der Aufruf von fehler führt bei s<strong>in</strong>nvollenE<strong>in</strong>gaben zu e<strong>in</strong>er Ausgabe, die richtig se<strong>in</strong> könnte. Wir habenaber noch e<strong>in</strong>en Denkfehler dar<strong>in</strong>. Statt <strong>de</strong>r Summe wird <strong>de</strong>rInteger-Quotient berechnet. Wir berichtigen auch das und testendas Programm mit e<strong>in</strong>igen E<strong>in</strong>gaben. Da unser Quelltext richtigzu se<strong>in</strong> sche<strong>in</strong>t, verschönern wir se<strong>in</strong>e vorläufig endgültige Fassungmit <strong>de</strong>m Beautifier cb(1):cb fehler.c > fehler.brm fehler.cmv fehler.b fehler.cSchließlich löschen wir das nicht mehr benötigte Corefile unduntersuchen das Programm noch mit e<strong>in</strong>igen Werkzeugen:time fehlercflow fehler.ccxref fehler.cstr<strong>in</strong>gs fehlernm fehlersize fehlerls -l fehlerstrip fehlerls -l fehlerstr<strong>in</strong>gs(1) ist e<strong>in</strong> ziemlich dummes Werkzeug, das aus e<strong>in</strong>erausführbaren Datei alles heraussucht, was nach Str<strong>in</strong>g aussieht.Das Werkzeug nm(1) gibt e<strong>in</strong>e Liste aller Symbole aus, die langwer<strong>de</strong>n kann. strip(1) wirft aus e<strong>in</strong>er ausführbaren Datei dienur für <strong>de</strong>n Debugger, nicht aber für die Ausführung wichtigenInformationen heraus und verkürzt dadurch die Datei. Abmel<strong>de</strong>nmit exit.Schreiben Sie <strong>in</strong> e<strong>in</strong>er Programmiersprache Ihrer Wahl (ichempfehle C) e<strong>in</strong> Programm, das• e<strong>in</strong>e Datei mittels creat(2) erzeugt,• <strong>de</strong>ssen Zugriffsrechte mittels chmod(2) und se<strong>in</strong>e Zeitstempelmittels utime(2) setzt,• die verwen<strong>de</strong>ten Werte mittels fpr<strong>in</strong>tf(3) als Text <strong>in</strong> dieDatei schreibt. fpr<strong>in</strong>tf(3) f<strong>in</strong><strong>de</strong>n Sie unter pr<strong>in</strong>tf(3).


76 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Schreiben Sie e<strong>in</strong> Programm ähnlich who(1). Sie brauchen dazugetut(3) und utmp(4).1.2.13 Fragen Programmer’s Workbench• Wozu braucht man e<strong>in</strong>en Compiler? E<strong>in</strong>en L<strong>in</strong>ker?• Was ist l<strong>in</strong>t?• Was macht make? Wie sieht e<strong>in</strong> e<strong>in</strong>faches Makefile aus?• Wozu braucht man Debugger?• Was ist e<strong>in</strong>e Funktionsbibliothek? Vorteil?• Wozu braucht man e<strong>in</strong>e Versionsverwaltung? Wie benutztman RCS?• Was s<strong>in</strong>d Systemaufrufe? Wer braucht sie?• Unterschied zu Standardfunktionen?• Welche Aufgaben erledigen die Systemaufrufe hauptsächlich?1.3 Bauste<strong>in</strong>e e<strong>in</strong>es Quelltextes1.3.1 ÜbersichtAlle Zeichen o<strong>de</strong>r Zeichengruppen e<strong>in</strong>es Programmes im Quellco<strong>de</strong>s<strong>in</strong>d entwe<strong>de</strong>r• Kommentar (comment),• Namen (i<strong>de</strong>ntifier),• Schlüsselwörter (Wortsymbole) (keyword),• Operatoren (operator),• Konstanten (Literale) (constant, literal),• Trennzeichen (separator) o<strong>de</strong>r• be<strong>de</strong>utungslos.E<strong>in</strong> Quelltext (Programmquelle, Source) ist e<strong>in</strong> Textfile, bestehendaus Zeilen, diese wie<strong>de</strong>rum aus druck- und sichtbarenZeichen (fast immer <strong>de</strong>s US-ASCII-Zeichensatzes) e<strong>in</strong>schließlich<strong>de</strong>s Zwischenraums (space). Die Zeichen s<strong>in</strong>d zu Wörtern


1.3. BAUSTEINE EINES QUELLTEXTES 77gruppiert, die durch Trennzeichen vone<strong>in</strong>an<strong>de</strong>r abgetrennt s<strong>in</strong>d,meist durch m<strong>in</strong><strong>de</strong>stens e<strong>in</strong>en Zwischenraum. Zeilen wer<strong>de</strong>ndurch das Zeilenen<strong>de</strong> markiert, meist durch die ASCII-ZeichenCR und/o<strong>de</strong>r LF. S<strong>in</strong>ne<strong>in</strong>heiten wie Wörter, Zahlen o<strong>de</strong>r Operatorenwer<strong>de</strong>n als Token bezeichnet, sie dürfen nicht durch Trennzeicheno<strong>de</strong>r Zeilenwechsel unterbrochen wer<strong>de</strong>n.Kommentar ist nur für <strong>de</strong>n menschlichen Leser bestimmtund gelangt <strong>in</strong> C/<strong>C++</strong> gar nicht bis zum Übersetzungsvorgang,son<strong>de</strong>rn wird schon vom Präprozessor entfernt und kann bis aufse<strong>in</strong>e Begrenzungen frei gestaltet wer<strong>de</strong>n. Ebenso entfernt <strong>de</strong>rPräprozessor das Zeichenpaar Backslash-Zeilenwechsel und verb<strong>in</strong><strong>de</strong>tsomit zwei Zeilen. Auf diese Weise lassen sich lange Anweisungenauf mehrere Zeilen verteilen. Schlüsselwörter undOperatoren s<strong>in</strong>d festgelegte Zeichen o<strong>de</strong>r Zeichengruppen, andie je<strong>de</strong>r gebun<strong>de</strong>n ist. Namen wer<strong>de</strong>n nach gewissen Regelnvom Programmierer gebil<strong>de</strong>t, ebenso Konstanten. Trennzeichentrennen die genannten Bauste<strong>in</strong>e o<strong>de</strong>r ganze Anweisungenvone<strong>in</strong>an<strong>de</strong>r und s<strong>in</strong>d festgelegt, meist Leerzeichen (space),Semikolons und L<strong>in</strong>efeeds. Be<strong>de</strong>utungslose Zeichen s<strong>in</strong>d überzähligeLeerzeichen, Tabs o<strong>de</strong>r L<strong>in</strong>efeeds.Der C-Standard – gegenwärtig ISO/IEC 9899:1999 – legtnicht alle E<strong>in</strong>zelheiten fest. Zu manchen Fragen spricht er nurEmpfehlungen aus o<strong>de</strong>r überlässt sogar die Wahl <strong>de</strong>m Compilerund/o<strong>de</strong>r <strong>de</strong>m Betriebssystem. Gerät man an solche Probleme,braucht man e<strong>in</strong>e genaue Beschreibung <strong>de</strong>r bei<strong>de</strong>n, sollte experimentellprüfen, was geschieht, und se<strong>in</strong> Programm ausführlichkommentieren.1.3.2 Syntax-DiagrammeDie Syntax <strong>de</strong>r e<strong>in</strong>zelnen Bauste<strong>in</strong>e – das heißt ihr regelgerechterGebrauch – kann mittels Text beschrieben wer<strong>de</strong>n. Das ist oftumständlich und teilweise schwer zu verstehen. Deshalb nimmtman Beispiele zu Hilfe, die aber selten die Syntax vollständigerfassen. So haben sich Syntax-Diagramme e<strong>in</strong>gebürgert, dienach etwas Übung leicht zu lesen s<strong>in</strong>d. In Abbildung 1.3 auf Seite79 ist die Syntax zweier C-Bauste<strong>in</strong>e dargestellt, nämlich dieif-else-Anweisung und <strong>de</strong>n Block. Die if-else-Anweisungbesteht aus:• <strong>de</strong>m Schlüsselwort if,


78 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>• e<strong>in</strong>er öffnen<strong>de</strong>n run<strong>de</strong>n Klammer,• e<strong>in</strong>em booleschen Ausdruck (true – false),• e<strong>in</strong>er schließen<strong>de</strong>n run<strong>de</strong>n Klammer,• e<strong>in</strong>er Anweisung – auch die leere Anweisung – o<strong>de</strong>r e<strong>in</strong>emBlock,• dann ist entwe<strong>de</strong>r En<strong>de</strong> <strong>de</strong>r if-Anweisung o<strong>de</strong>r es folgt• das Schlüsselwort else, gefolgt von• e<strong>in</strong>er Anweisung o<strong>de</strong>r e<strong>in</strong>em Block.Ist <strong>de</strong>r boolesche Ausdruck true, dann wird die erste Anweisungausgeführt, an<strong>de</strong>rnfalls die zweite. Fehlt <strong>de</strong>r else-Zweig,so liegt e<strong>in</strong>e bed<strong>in</strong>gte Anweisung vor, die nur dann ausgeführtwird, wenn <strong>de</strong>r boolesche Ausdruck true ist. Danach geht es imProgramm weiter.E<strong>in</strong> Block se<strong>in</strong>erseits besteht aus:• e<strong>in</strong>er öffnen<strong>de</strong>n geschweiften Klammer,• dann entwe<strong>de</strong>r nichts (leerer Block) o<strong>de</strong>r• e<strong>in</strong>er Anweisung,• gegebenenfalls weiteren Anweisungen,• und e<strong>in</strong>er schließen<strong>de</strong>n geschweiften Klammer.Da e<strong>in</strong> Block syntaktisch gleichwertig e<strong>in</strong>er Anweisung ist, lassensich Blöcke schachteln. E<strong>in</strong> Block kann überall stehen, woe<strong>in</strong>e Anweisung erwartet wird.E<strong>in</strong> weiterer Weg zur Beschreibung <strong>de</strong>r Syntax e<strong>in</strong>er Programmierspracheist die Backus-Naur-Form, die von JOHNBACKUS, e<strong>in</strong>em <strong>de</strong>r Väter von FORTRAN, und PETER NAUR, e<strong>in</strong>em<strong>de</strong>r Väter von ALGOL, als Metasprache zu ALGOL 60 entwickeltwor<strong>de</strong>n ist. Weiteres siehe bei D. GRIES.1.3.3 KommentarAlle Programmiersprachen ermöglichen, Text <strong>in</strong> e<strong>in</strong> Programme<strong>in</strong>zufügen, <strong>de</strong>r vom Compiler überlesen wird und nur für <strong>de</strong>nmenschlichen Leser bestimmt ist. Dieser Kommentar muss mite<strong>in</strong>em beson<strong>de</strong>ren Zeichen e<strong>in</strong>geleitet und gegebenenfalls been<strong>de</strong>twer<strong>de</strong>n.


1.3. BAUSTEINE EINES QUELLTEXTES 79if-else-Anweisung✗✔ ✗✔✲if✲✖✕ ✖✕(✲ bool.Ausdr.✗✔✲✖✕)✲ Anw.Block✛✘✖✲✚✙else ✲ Anw.Block✲✻✕Block✗✔✗✔✲✖✕✻✗✔{ ✲ Anweisung ❄ ✲ }✲✖✕✖✕Abb. 1.3: Syntax-Diagramm <strong>de</strong>r if-else-Anweisung und <strong>de</strong>sBlockesIn C/<strong>C++</strong> leitet die Zeichengruppe /* <strong>de</strong>n Kommentar e<strong>in</strong>. Erkann sich über mehrere Zeilen erstrecken, darf aber nicht geschachteltwer<strong>de</strong>n. Zu e<strong>in</strong>er ungewollten Schachtelung kommtes, wenn man kommentierte Programmteile durch E<strong>in</strong>rahmenmit Kommentarzeichen vorübergehend unwirksam macht. DieFehlermeldung <strong>de</strong>s Compilers sagt irgen<strong>de</strong>twas mit Po<strong>in</strong>ternund führt irre. Die Zeichengruppe */ kennzeichnet das En<strong>de</strong>.E<strong>in</strong> Zeilenen<strong>de</strong> been<strong>de</strong>t diesen Kommentar nicht. Ansonstenkann Kommentar überall stehen, nicht nur auf e<strong>in</strong>er eigenenZeile. E<strong>in</strong> Beispiel:/*Die ersten Zeilen enthalten Programmnamen, Zweck, Autor,Datum, Compiler, Literatur und aehnliches.*/#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){/* Dies ist e<strong>in</strong>e eigene Kommentarzeile */


80 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>puts("Erste Zeile");puts("Zweite Zeile"); /* Kommentar *//* Kommentar */ puts("Dritte Zeile");/*puts("Vierte Zeile"); /* Kommentar geschachtelt!!! */*/puts("En<strong>de</strong>");return 0;}Quelle 1.21 : C-Programm mit KommentarenAuf unserem System haben wir folgen<strong>de</strong> Regel e<strong>in</strong>geführt: daFehlermeldungen <strong>de</strong>s Systems <strong>in</strong> Englisch ausgegeben wer<strong>de</strong>n,schreiben wir die Meldungen unserer Programme <strong>in</strong> Deutsch(man sollte sie ohnedies mittels #<strong>de</strong>f<strong>in</strong>e-Anweisungen irgendwozusammenfassen, so dass sie leicht ausgetauscht wer<strong>de</strong>n können).Damit sieht man sofort, woher e<strong>in</strong>e Meldung stammt. Kommentarschreiben wir wie<strong>de</strong>r <strong>in</strong> Englisch, da die Programmbeispieleauch per Mail o<strong>de</strong>r News <strong>in</strong> die unendlichen Weiten <strong>de</strong>sInternet geschickt wer<strong>de</strong>n, wo Englisch nun e<strong>in</strong>mal die l<strong>in</strong>guafranca ist. An Kommentar 21 soll man nicht sparen, <strong>de</strong>nn er kostetwenig Aufwand und kann viel helfen, während die Dokumentationzum Programm nur zu oft ad calendas Graecas (Sankt-Nimmerle<strong>in</strong>s-Tag) verschoben wird.In <strong>C++</strong> kommt e<strong>in</strong>e weitere Art von Kommentar h<strong>in</strong>zu. Erbeg<strong>in</strong>nt mit zwei Schrägstrichen und en<strong>de</strong>t mit <strong>de</strong>m Zeilenwechsel,weshalb er Zeilenkommentar genannt wird. Dieser Kommentardarf <strong>in</strong>nerhalb <strong>de</strong>s oben genannten Kommentars vorkommen.Die umgekehrte Folge ist auch zulässig, aber seltenanzutreffen.1.3.4 NamenNamen (i<strong>de</strong>ntifier) bezeichnen Funktionen, Konstanten, Variable,Makros o<strong>de</strong>r Sprungmarken (Labels). Sie müssen mit e<strong>in</strong>emBuchstaben o<strong>de</strong>r e<strong>in</strong>em Unterstrich (un<strong>de</strong>rscore) beg<strong>in</strong>nen. BenutzereigeneNamen sollten immer mit e<strong>in</strong>em Buchstaben an-21 Real programmers don’t comment their co<strong>de</strong>.


1.3. BAUSTEINE EINES QUELLTEXTES 81fangen, <strong>de</strong>r Unterstrich als erstes Zeichen wird vom Compilero<strong>de</strong>r vom System verwen<strong>de</strong>t. Die weiteren Zeichen <strong>de</strong>s Namenskönnen Buchstaben, Ziffern o<strong>de</strong>r <strong>de</strong>r Unterstrich se<strong>in</strong>. Groß- undKle<strong>in</strong>buchstaben wer<strong>de</strong>n unterschie<strong>de</strong>n. Die maximal zulässigeLänge von Namen kann durch <strong>de</strong>n Compiler, <strong>de</strong>n L<strong>in</strong>ker o<strong>de</strong>r dasBestriebssystem gegeben se<strong>in</strong> und lässt sich daher nicht allgeme<strong>in</strong>angeben. Ab 255 Zeichen wird es kritisch. Signifikant s<strong>in</strong>dm<strong>in</strong><strong>de</strong>stens die ersten sieben Zeichen, nach ANSI die ersten e<strong>in</strong>unddreißig.Verwen<strong>de</strong>t man Funktionen frem<strong>de</strong>r Herkunft, sollteman mit nur sechs signifikanten Zeichen rechnen sowie damit,dass Groß- und Kle<strong>in</strong>buchstaben nicht unterschie<strong>de</strong>n wer<strong>de</strong>n.1.3.5 SchlüsselwörterIn C/<strong>C++</strong> wie <strong>in</strong> je<strong>de</strong>r an<strong>de</strong>ren Programmiersprache haben bestimmteWörter e<strong>in</strong>e beson<strong>de</strong>re Be<strong>de</strong>utung, beispielsweise ma<strong>in</strong>,while und if. Diese Wortsymbole o<strong>de</strong>r Schlüsselwörter 22dürfen auf ke<strong>in</strong>en Fall als Namen verwen<strong>de</strong>t wer<strong>de</strong>n, die Namen<strong>de</strong>r Standardfunktionen wie pr<strong>in</strong>tf() o<strong>de</strong>r fopen() sollennicht umfunktioniert wer<strong>de</strong>n. C zeichnet sich durch e<strong>in</strong>eger<strong>in</strong>ge Anzahl von Schlüsselwörtern aus, etwa dreißig, sieheAnhang D.1 C-Lexikon, Schlüsselwörter auf Seite 317. Mit <strong>C++</strong>kommen nochmal dreißig dazu. Unterboten wird C/<strong>C++</strong> dar<strong>in</strong>nur von SMALLTALK mit fünf Schlüsselwörtern.22 Es gibt die Bezeichnungen Wortsymbol, Schlüsselwort undreserviertes Wort. Geme<strong>in</strong>t ist <strong>in</strong> je<strong>de</strong>m Fall, dass das Wort – e<strong>in</strong>ebestimmte Zeichenfolge – nicht une<strong>in</strong>geschränkt als Namenverwen<strong>de</strong>t wer<strong>de</strong>n darf. In C dürfen diese Wörter – außer imKommentar – ke<strong>in</strong>esfalls für e<strong>in</strong>en an<strong>de</strong>ren als ihren beson<strong>de</strong>renZweck verwen<strong>de</strong>t wer<strong>de</strong>n. In FORTRAN dürfen diese Wörter<strong>in</strong> Zusammenhängen, die e<strong>in</strong>e Deutung als Schlüsselwort ausschließen,auch als Namen verwen<strong>de</strong>t wer<strong>de</strong>n. Man darf also e<strong>in</strong>eVariable if nennen, und <strong>in</strong> <strong>de</strong>r Zuweisung if = 3 wird dieZeichenfolge if als Variable und nicht als Wortsymbol im S<strong>in</strong>nevon falls verstan<strong>de</strong>n.


82 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.3.6 Operan<strong>de</strong>nWir schränken hier <strong>de</strong>n Begriff Daten etwas e<strong>in</strong> und verstehendarunter nur die passiven Objekte, mit <strong>de</strong>nen e<strong>in</strong> Programm etwastut, also Text, Zahlen, Grafiken usw. Diese Objekte und ihreUntere<strong>in</strong>heiten nennen wir Operan<strong>de</strong>n (operand). Mit ihnenwer<strong>de</strong>n Operationen durchgeführt. Das Wort Objekt 23 vermei<strong>de</strong>ich hier, um ke<strong>in</strong>e Assoziationen an objektorientiertes Programmierenzu wecken. E<strong>in</strong> Operand• hat e<strong>in</strong>en Namen (i<strong>de</strong>ntifier),• gehört e<strong>in</strong>em Typ (type) an,• hat e<strong>in</strong>en konstanten o<strong>de</strong>r variablen Wert (value),• belegt zur Laufzeit Speicherplatz im Computer,• hat e<strong>in</strong>en Geltungsbereich (scope) und• e<strong>in</strong>e Lebensdauer (lifetime).Auf <strong>de</strong>n Operan<strong>de</strong>n wird über <strong>de</strong>n Namen o<strong>de</strong>r die Speicheradressezugegriffen. Die Speicheradresse e<strong>in</strong>es Operan<strong>de</strong>n kann<strong>in</strong> e<strong>in</strong>em weiteren Operan<strong>de</strong>n abgelegt wer<strong>de</strong>n, <strong>de</strong>r Zeiger, Referenz,Adressvariable o<strong>de</strong>r Po<strong>in</strong>ter genannt wird. Ich bevorzugedas englische Wort Po<strong>in</strong>ter, weil das <strong>de</strong>utsche Wort Zeiger dreiBe<strong>de</strong>utungen hat: Po<strong>in</strong>ter, In<strong>de</strong>x, Cursor. Außer<strong>de</strong>m bezeichneich Po<strong>in</strong>ter nicht als Variable, obwohl ihr Wert verän<strong>de</strong>rlich ist.Wer das englische Wort nicht mag, sollte von Adressvariablen re<strong>de</strong>n.Po<strong>in</strong>ter auf Po<strong>in</strong>ter s<strong>in</strong>d Po<strong>in</strong>ter 2. Ordnung usw. Der Geltungsbereiche<strong>in</strong>es Operan<strong>de</strong>n ist e<strong>in</strong> Block, e<strong>in</strong>e Funktion, e<strong>in</strong>eDatei o<strong>de</strong>r das ganze Programm. Gleiches gilt für die Lebensdauer.In <strong>de</strong>r Deklaration e<strong>in</strong>es Operan<strong>de</strong>n wer<strong>de</strong>n se<strong>in</strong> Nameund se<strong>in</strong>e Eigenschaften vere<strong>in</strong>bart. In <strong>de</strong>r Def<strong>in</strong>ition erhält ere<strong>in</strong>en Wert und benötigt spätestens dann e<strong>in</strong>en Platz im Arbeitsspeicher.Deklaration und Def<strong>in</strong>ition können <strong>in</strong> e<strong>in</strong>er Anweisungzusammengezogen se<strong>in</strong>. Die erstmalige Zuweisung e<strong>in</strong>es Wertesan e<strong>in</strong>e Variable heißt Initialisierung. Deklaration und Def<strong>in</strong>itionwer<strong>de</strong>n auch unter <strong>de</strong>m Begriff Vere<strong>in</strong>barung zusammengefasst.23 KERNIGHAN + RITCHIE gebrauchen Objekt im S<strong>in</strong>ne e<strong>in</strong>esSpeicherbereiches, auf <strong>de</strong>n mittels e<strong>in</strong>es Namens zugegriffenwird.


1.3. BAUSTEINE EINES QUELLTEXTES 83Auf die Auswahl und Strukturierung <strong>de</strong>r Operan<strong>de</strong>n soll manSorgfalt verwen<strong>de</strong>n. E<strong>in</strong>e zweckmäßige Datenstruktur erleichtertdas Programmieren und führt zu besseren Programmen. E<strong>in</strong>enachträgliche Än<strong>de</strong>rung <strong>de</strong>r Datenstruktur erfor<strong>de</strong>rt meiste<strong>in</strong>en großen Aufwand, weil viele Programme o<strong>de</strong>r Programmteiledavon betroffen s<strong>in</strong>d. Die Namen <strong>de</strong>r Operan<strong>de</strong>n sollen ihreBe<strong>de</strong>utung erklären, erfor<strong>de</strong>rlichenfalls ist ihre Be<strong>de</strong>utung imKommentar o<strong>de</strong>r <strong>in</strong> e<strong>in</strong>er Aufzählung festzuhalten.1.3.6.1 Konstanten und VariableOperan<strong>de</strong>n können während <strong>de</strong>s Ablaufs e<strong>in</strong>es Programmes konstantbleiben (wie die Zahl π) o<strong>de</strong>r sich än<strong>de</strong>rn (wie die Anzahl<strong>de</strong>r Iterationen zur Lösung e<strong>in</strong>er Gleichung o<strong>de</strong>r das Ergebnise<strong>in</strong>er Berechnung o<strong>de</strong>r Textsuche). Es kommt auch vor, dass e<strong>in</strong>Operand für e<strong>in</strong>en Programmaufruf konstant ist, beim nächstenAufruf aber e<strong>in</strong>en an<strong>de</strong>ren Wert hat (wie <strong>de</strong>r Mehrwertsteuersatz).Man tut gut, sämtliche Operan<strong>de</strong>n e<strong>in</strong>es Programmes an wenigenStellen zusammenzufassen und zu <strong>de</strong>klarieren. In <strong>de</strong>nFunktionen o<strong>de</strong>r Prozeduren sollen ke<strong>in</strong>e geheimnisvollen Zahlen(magic numbers) auftauchen, son<strong>de</strong>rn nur Namen. Konstanten,die im Programm über ihren Namen aufgerufen wer<strong>de</strong>n,heißen symbolische Konstanten.Für <strong>de</strong>n Computer s<strong>in</strong>d Konstanten Bestandteil <strong>de</strong>s Programmco<strong>de</strong>s,das unter UNIX <strong>in</strong> das Co<strong>de</strong>segment <strong>de</strong>s zugehörigenProzesses kopiert und vor schreiben<strong>de</strong>n Zugriffen geschütztwird. Diese Konstanten wer<strong>de</strong>n auch Literale genannt. Variableh<strong>in</strong>gegen belegen Speicherplätze im User Data Segment, <strong>de</strong>renAdressen das Programm kennt und auf die es lesend und schreibendzugreift.In ANSI-C s<strong>in</strong>d die Typ-Attribute (type qualifier) constund volatile e<strong>in</strong>geführt wor<strong>de</strong>n, die e<strong>in</strong>e bestimmte Behandlung<strong>de</strong>r zugehörigen Operan<strong>de</strong>n erzw<strong>in</strong>gen. Sie wer<strong>de</strong>n seltengebraucht.1.3.6.2 Typen – GrundbegriffeJe<strong>de</strong>r Operand gehört e<strong>in</strong>em Typ an, <strong>de</strong>r über• <strong>de</strong>n Wertebereich (siehe /usr/<strong>in</strong>clu<strong>de</strong>/limits.h),


84 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>• die zulässigen Operationen,• <strong>de</strong>n Speicherbedarfentschei<strong>de</strong>t. Die Typen wer<strong>de</strong>n <strong>in</strong> drei Gruppen e<strong>in</strong>geteilt:• e<strong>in</strong>fache, skalare o<strong>de</strong>r elementare Typen• zusammengesetzte o<strong>de</strong>r strukturierte Typen• Po<strong>in</strong>ter (Adressvariable)In C gibt es nur konstante Typen, das heißt, e<strong>in</strong> Operand, <strong>de</strong>re<strong>in</strong>mal als ganzzahlig <strong>de</strong>klariert wor<strong>de</strong>n ist, bleibt dies während<strong>de</strong>s ganzen Programmes. E<strong>in</strong>ige Programmiersprachen erlaubenauch variable Typen, die erst zur Laufzeit bestimmt wer<strong>de</strong>no<strong>de</strong>r sich während dieser än<strong>de</strong>rn. Typfreie Sprachen kennennur das Byte o<strong>de</strong>r das Masch<strong>in</strong>enwort als Datentyp. Die Typisierung24 erleichtert die Arbeit und erhöht die Sicherheit sowiedie Rechengeschw<strong>in</strong>digkeit. Stellen Sie sich vor, Sie müssten beiGleitkommazahlen Exponent und Mantisse je<strong>de</strong>smal selbst aus<strong>de</strong>n Bytes herausdröseln. O<strong>de</strong>r <strong>de</strong>r Computer müsste je<strong>de</strong>smalaus <strong>de</strong>m Zusammenhang e<strong>in</strong>er Operation ermitteln, um was füre<strong>in</strong>en Typ von Operan<strong>de</strong>n es sich han<strong>de</strong>lt. Es gibt aber auchAufgaben, bei <strong>de</strong>nen <strong>de</strong>r Verzicht auf e<strong>in</strong>e Typisierung Vorteilebr<strong>in</strong>gt. Oft ist das bei Aufgaben <strong>de</strong>r Fall, die mittels Skriptsprachenbearbeitet wer<strong>de</strong>n.Die Typ<strong>de</strong>klarationen <strong>in</strong> C/<strong>C++</strong> können ziemlich schwierig zuverstehen se<strong>in</strong>, vor allem bei mangeln<strong>de</strong>r Übung. Im Netz f<strong>in</strong><strong>de</strong>tsich e<strong>in</strong> Programm c<strong>de</strong>cl, das Typ<strong>de</strong>klarationen <strong>in</strong> e<strong>in</strong>fachesEnglisch übersetzt. Füttert man <strong>de</strong>m Programm folgen<strong>de</strong> Deklaration:char (*(*x[3]) ()) [5]so erhält man zur Antwort:<strong>de</strong>clare x as array 3 of po<strong>in</strong>ter to function return<strong>in</strong>gpo<strong>in</strong>ter to array 5 of charSo schnell wie c<strong>de</strong>cl hätte ich die Antwort nicht gefun<strong>de</strong>n.24 Real programmers don’t worry about types.


1.3. BAUSTEINE EINES QUELLTEXTES 851.3.6.3 E<strong>in</strong>fache TypenIn je<strong>de</strong>r Programmiersprache gibt es Grundtypen, aus <strong>de</strong>nen allehöheren Typen zusammengesetzt wer<strong>de</strong>n. In C/<strong>C++</strong> s<strong>in</strong>d diesganze Zahlen, Gleitkommazahlen und Zeichen.Ganze Zahlen In C/<strong>C++</strong> gibt es ganze Zahlen mit o<strong>de</strong>r ohneVorzeichen sowie <strong>in</strong> halber, e<strong>in</strong>facher o<strong>de</strong>r doppelter Länge:• <strong>in</strong>t ganze Zahl mit Vorzeichen• unsigned <strong>in</strong>t ganze Zahl ohne Vorzeichen• short kurze ganze Zahl mit Vorzeichen• unsigned short kurze ganze Zahl ohne Vorzeichen• long ganze Zahl doppelter Länge mit Vorzeichen• unsigned long ganze Zahl doppelter Länge ohne VorzeichenDie Deklaration von Variablen als ganzzahlig sieht so aus:<strong>in</strong>t x, y, z;unsigned long anzahl;Die Länge <strong>de</strong>r ganzen Zahlen <strong>in</strong> Bytes ist nicht festgelegt undbeim Portieren zu beachten. Häufig s<strong>in</strong>d <strong>in</strong>t und long gleichund belegen e<strong>in</strong> Masch<strong>in</strong>enwort, auf unserer Anlage also 4 Bytesgleich 32 Bits (32-Bit-Architektur). Festgelegt ist nur die Reihenfolge:char


86 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>wer<strong>de</strong>n, wird sich die Diskussion nochmals wie<strong>de</strong>rholen, allerd<strong>in</strong>gsaufbauend auf <strong>de</strong>n Erfahrungen <strong>de</strong>s gegenwärtigen Wechsels.Das Ziel s<strong>in</strong>d Programme, die unabhängig von <strong>de</strong>r Datengrößeauf allen Architekturen laufen, und Daten, die zwischenverschie<strong>de</strong>nen Architekturen ausgetauscht wer<strong>de</strong>n können.Datentyp LP32 ILP32 ILP64 LLP64 LP642/4/4 4/4/4 8/8/8 4/4/8 4/8/8char 8 8 8 8 8short 16 16 16 16 16<strong>in</strong>t 16 32 64 32 32long 32 32 64 32 64Po<strong>in</strong>ter 32 32 64 64 64Tab. 1.1: Länge von Datentypen auf verschie<strong>de</strong>nen ArchitekturenJe nach Länge <strong>de</strong>r Datentypen <strong>in</strong>t (I), long (L) und Po<strong>in</strong>ter(P) unterschei<strong>de</strong>t man heute die <strong>in</strong> Tabelle 1.1 auf Seite 86aufgeführten Architekturen. Es wür<strong>de</strong> zu weit führen, hier dieVor- und Nachteile je<strong>de</strong>r Architektur gegene<strong>in</strong>an<strong>de</strong>r abzuwägen.Wichtig ist, die Architektur <strong>de</strong>r eigenen Masch<strong>in</strong>e zu kennen (<strong>in</strong>unserem Fall ILP32) und die Programme möglichst portabel zugestalten. Hierzu Empfehlungen im Abschnitt 1.13 Portieren vonProgrammen auf Seite 280.Für ganze Zahlen s<strong>in</strong>d die Addition, die Subtraktion, dieMultiplikation, die Modulo-Operation (Divisionsrest) und die Divisionunter Vernachlässigung <strong>de</strong>s Divisionsrestes <strong>de</strong>f<strong>in</strong>iert, fernerVergleiche mittels größer – gleich – kle<strong>in</strong>er.Gleitkommazahlen Gleitkommazahlen – auch als Reals o<strong>de</strong>rFloat<strong>in</strong>g Po<strong>in</strong>t Numbers bezeichnet – wer<strong>de</strong>n durch e<strong>in</strong>e Mantisseund e<strong>in</strong>en Exponenten dargestellt. Der Exponent verstehtsich nach außen zur Basis 10, <strong>in</strong>tern wird die Basis 2 verwen<strong>de</strong>t.Die Mantisse ist auf e<strong>in</strong>e Stelle ungleich 0 vor <strong>de</strong>m Dezimalkommao<strong>de</strong>r -punkt normiert. Es gibt:• float Gleitkommazahl e<strong>in</strong>facher Genauigkeit• double Gleitkommazahl doppelter Genauigkeit


1.3. BAUSTEINE EINES QUELLTEXTES 87• long double Gleitkommazahl noch höherer Genauigkeit(exten<strong>de</strong>d precision)Die Deklaration von Gleitkomma-Variablen sieht so aus:float x, y, z;double geschw<strong>in</strong>digkeit;Gleitkommazahlen haben immer e<strong>in</strong> Vorzeichen. Man beachte,daß die Typen sich nicht nur <strong>in</strong> ihrem Wertebereich, son<strong>de</strong>rnauch <strong>in</strong> ihrer Genauigkeit (Anzahl <strong>de</strong>r signifikanten Stellen) unterschei<strong>de</strong>n,an<strong>de</strong>rs als bei Ganzzahlen. Der Typ long doubleist selten.Für Gleitkommazahlen s<strong>in</strong>d die Addition, die Subtraktion,die Multiplikation, die Division sowie Vergleiche zulässig. DieAbfrage auf Gleichheit ist jedoch heikel, da aufgrund von Rundungsfehlernzwei Gleitkommazahlen selten gleich s<strong>in</strong>d. Wennmöglich, mache man um Gleitkommazahlen e<strong>in</strong>en großen Bogen.Die Operationen dauern länger als die entsprechen<strong>de</strong>n fürGanzzahlen, und die Auswirkungen von Rundungsfehlern s<strong>in</strong>dschwierig abzuschätzen. Zur <strong>in</strong>ternen Darstellung von Gleitkommazahlensiehe Abschnitt ?? Arithmetikprozessoren auf Seite ??.Alphanumerischer Typ E<strong>in</strong>e Größe, <strong>de</strong>ren Wertevorrat dieZeichen <strong>de</strong>r ASCII-Tabelle o<strong>de</strong>r e<strong>in</strong>er an<strong>de</strong>ren Tabelle s<strong>in</strong>d,ist vom Typ alphanumerisch o<strong>de</strong>r character, bezeichnet mitchar. In C wer<strong>de</strong>n sie durch e<strong>in</strong>e Integerzahl zwischen 0 und 127(7-bit-Zeichensätze) beziehungsweise 255 (8-bit-Zeichensätze)dargestellt. Der Speicherbedarf beträgt e<strong>in</strong> Byte. Mittlerweilegibt es auch <strong>in</strong>ternationale Zeichensätze, <strong>de</strong>ren Zeichen je zweiBytes belegen. Die Deklaration von alphanumerischen Variablensieht so aus:char a, b, c;Mit wachsen<strong>de</strong>r Verbreitung von 16-bit-Zeichensätzen (Unico<strong>de</strong>,Interco<strong>de</strong>) ist zu erwarten, dass die Länge <strong>de</strong>s char-Typs angepasstwird.Die Verwandtschaft zwischen Ganzzahlen und Zeichen <strong>in</strong> Cverwirrt anfangs. Man mache sich die Geme<strong>in</strong>samkeiten an e<strong>in</strong>emkle<strong>in</strong>en Programm klar:


88 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>/* Programm zum Demonstrieren von character und <strong>in</strong>teger */#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t i, j, k; char a, b;i = 65; j = 233; k = 333; a = ’B’; b = ’!’;pr<strong>in</strong>tf("Ganzzahlen: %d %d %d %d\n", i, j, k, a);pr<strong>in</strong>tf("Zeichen : %c %c %c %c\n", i, j, k, a);puts("Nun rechnen wir mit Zeichen (B = 66, ! = 33):");pr<strong>in</strong>tf("%c + %c = %d\n", a, b, a + b);pr<strong>in</strong>tf("%c - %c = %d\n", b, a, b - a);pr<strong>in</strong>tf("%c - %c = %c\n", b, a, b - a);return 0;}Quelle 1.22 : C-Programm mit <strong>de</strong>n Typen character und <strong>in</strong>tegerDie Ausgabe <strong>de</strong>s Programms lautet:Ganzzahlen: 65 233 333 66Zeichen : A é M BNun rechnen wir mit Zeichen (B = 66, ! = 33):B + ! = 99! - B = -33! - B = SSIn <strong>de</strong>r ersten Zeile wer<strong>de</strong>n alle Werte entsprechend <strong>de</strong>m Formatstr<strong>in</strong>g<strong>de</strong>r Funktion pr<strong>in</strong>tf(3) als <strong>de</strong>zimale Ganzzahlen ausgegeben,wobei <strong>de</strong>r Buchstabe B durch se<strong>in</strong>e ASCII-Nummer 66vertreten ist. In <strong>de</strong>r zweiten Zeile wer<strong>de</strong>n alle Werte als 7-bit-ASCII-Zeichen verstan<strong>de</strong>n, wobei die Zahlen, die mehr als 7 Bit(> 127) beanspruchen, nach 7 Bit l<strong>in</strong>ks abgeschnitten wer<strong>de</strong>n.Die Zahl 233 führt so zur Ausgabe <strong>de</strong>s Zeichens Nr. 233 - 128= 105. Die Zahl - 33 wird als Zeichen Nr. 128 - 33 = 95, <strong>de</strong>mUnterstrich, ausgegeben. Wie man an <strong>de</strong>r Rechnung erkennt,wer<strong>de</strong>n Zeichen vom Prozessor wie ganze Zahlen behan<strong>de</strong>lt un<strong>de</strong>rst bei <strong>de</strong>r Ausgabe e<strong>in</strong>er Zahl o<strong>de</strong>r e<strong>in</strong>em ASCII-Zeichen zugeordnet.Es ist zu erwarten, daß auf Systemen mit 8-bit- o<strong>de</strong>r


1.3. BAUSTEINE EINES QUELLTEXTES 8916-bit-Zeichensätzen die Grenze höher liegt, aber die Arbeitsweisebleibt. Manchmal will man e<strong>in</strong> Byte wahlweise als Ganzzahlo<strong>de</strong>r als Zeichen auffassen, aber das gehört zu <strong>de</strong>n berüchtigtenTricks <strong>in</strong> C. Me<strong>in</strong>t man <strong>de</strong>n Buchstaben a, sollte man auch’a’ schreiben, <strong>de</strong>nn <strong>de</strong>r Gebrauch <strong>de</strong>r Nummer 97 anstelle <strong>de</strong>sZeichens setzt voraus, dass das System, auf <strong>de</strong>m das Programmausgeführt wird, <strong>de</strong>n ASCII-Zeichensatz verwen<strong>de</strong>t, womit diePortabilität <strong>de</strong>s Programms e<strong>in</strong>geschränkt wird.Das Ausgabegerät empfängt nur die Nummer <strong>de</strong>s auszugeben<strong>de</strong>nZeichens gemäß se<strong>in</strong>er Zeichensatz-Tabelle (ASCII, RO-MAN8), die Umwandlung <strong>de</strong>s Wertes entsprechend se<strong>in</strong>em Typist Aufgabe <strong>de</strong>r Funktion pr<strong>in</strong>tf(3).Boolescher Typ E<strong>in</strong>e Größe vom Typ boolean o<strong>de</strong>r logicalkann nur die Werte true (wahr, richtig) o<strong>de</strong>r false (falsch) annehmen.In C wer<strong>de</strong>n statt <strong>de</strong>s booleschen Typs die Integerwerte0 (= false) und nicht-0 (= true) verwen<strong>de</strong>t. Verwirrend ist, dassviele Funktionen bei Erfolg <strong>de</strong>n Wert 0 und bei Fehlern Werteungleich 0 zurückgeben.Leerer Typ Der leere Datentyp void wird zum Deklarierenvon Funktionen verwen<strong>de</strong>t, die ke<strong>in</strong> Ergebnis zurückliefern, sowiezum Erzeugen generischer (allgeme<strong>in</strong>er) Po<strong>in</strong>ter, die auf Variablene<strong>in</strong>es vorläufig beliebigen Typs zeigen. Der Typ hat ke<strong>in</strong>eGröße. Der Bytebedarf e<strong>in</strong>es Po<strong>in</strong>ters dagegen liegt fest, auchwenn <strong>de</strong>r zugehörige Variablentyp noch offen ist. Zur Po<strong>in</strong>ter-Arithmetik muss jedoch <strong>de</strong>r Typ (das heißt <strong>de</strong>r Bytebedarf <strong>de</strong>rzugehörigen Variablen) bekannt se<strong>in</strong>. Variablen vom Typ voidlassen sich nicht verarbeiten, weil sie nicht existieren. Man bezeichnet<strong>de</strong>n Typ void als unvollständig, da er nicht alle Fähigkeitene<strong>in</strong>es vollständigen Typs wie <strong>in</strong>t aufweist. Man brauchtdiesen schrägen Typ aus ähnlichen Grün<strong>de</strong>n wie die leere Menge<strong>in</strong> <strong>de</strong>r Mathematik.Vor <strong>de</strong>r Erf<strong>in</strong>dung <strong>de</strong>s Typs void wur<strong>de</strong> für generische Po<strong>in</strong>ter<strong>de</strong>r Typ char genommen, <strong>de</strong>r e<strong>in</strong> Byte umfasst, woraus sichalle an<strong>de</strong>ren Typen zusammensetzen lassen. Man hätte <strong>de</strong>n Typauch byte nennen können.


90 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.3.6.4 Zusammengesetzte Typen (Arrays, Strukturen)Arrays Die meisten Programmiersprachen kennen Arrays,auch als Vektoren o<strong>de</strong>r unglücklicherweise als Fel<strong>de</strong>r 25 bezeichnet;das s<strong>in</strong>d geordnete Mengen von Größen <strong>de</strong>sselben Typs. Je<strong>de</strong>mElement ist e<strong>in</strong> fortlaufen<strong>de</strong>r In<strong>de</strong>x (Hausnummer) zugeordnet,<strong>de</strong>r <strong>in</strong> C stets mit 0 beg<strong>in</strong>nt. In e<strong>in</strong>em Array von zwölfElementen läuft also <strong>de</strong>r In<strong>de</strong>x von 0 bis 11, aufpassen.Elemente e<strong>in</strong>es Arrays dürfen Konstanten o<strong>de</strong>r Variable allere<strong>in</strong>fachen Typen, an<strong>de</strong>re Arrays, Strukturen, Unions o<strong>de</strong>r Po<strong>in</strong>terse<strong>in</strong>, jedoch ke<strong>in</strong>e Funktionen. Dateien s<strong>in</strong>d formal Strukturen,e<strong>in</strong> Array von Dateien ist also erlaubt. Die Deklaration vonArrays sieht folgen<strong>de</strong>rmaßen aus:<strong>in</strong>t zahlen[100], nr[12];<strong>in</strong>t matrix[4][3];double realnumbers[1000];char names[33];char zeichen[] = "abcd";Der Compiler muss die Größe e<strong>in</strong>es Arrays (Anzahl und Typ <strong>de</strong>rElemente) wissen. Sie muss bereits im Programm stehen undkann nicht erst zur Laufzeit errechnet wer<strong>de</strong>n. Man kann jedochdie Größe e<strong>in</strong>es Arrays zur Laufzeit mittels <strong>de</strong>r Standardfunktionmalloc(3) än<strong>de</strong>rn, siehe Abschnitt 1.11.9 DynamischeSpeicherverwaltung auf Seite 258.Es gibt mehrdimensionale Arrays (Matrizen usw.) mit entsprechendvielen In<strong>de</strong>xfolgen. Die Elemente wer<strong>de</strong>n im Speicherh<strong>in</strong>tere<strong>in</strong>an<strong>de</strong>r <strong>in</strong> <strong>de</strong>r Weise abgelegt, dass sich <strong>de</strong>r letzte In<strong>de</strong>xam schnellsten än<strong>de</strong>rt. Der Compiler l<strong>in</strong>earisiert das Array, wieman sagt. E<strong>in</strong>e Matrix wird zeilenweise gespeichert. Vorsichtbeim Übertragen von o<strong>de</strong>r nach FORTRAN: dort läuft die Indizierungan<strong>de</strong>rs als <strong>in</strong> C/<strong>C++</strong>, e<strong>in</strong>e Matrix wird spaltenweisegespeichert. PASCAL verhält sich wie C/<strong>C++</strong>.Der Name e<strong>in</strong>es Arrays ist e<strong>in</strong>e Adresskonstante und kanndaher nicht auf <strong>de</strong>r l<strong>in</strong>ken Seite e<strong>in</strong>er Zuweisung vorkommen.Weiteres dazu im Abschnitt 1.3.6.7 Po<strong>in</strong>ter auf Seite 94.25 Fel<strong>de</strong>r <strong>in</strong> Datensätzen s<strong>in</strong>d etwas völlig an<strong>de</strong>res.


1.3. BAUSTEINE EINES QUELLTEXTES 91Str<strong>in</strong>gs (Zeichenketten) In C/<strong>C++</strong> s<strong>in</strong>d Str<strong>in</strong>gs o<strong>de</strong>r Zeichenketten(cha<strong>in</strong>e <strong>de</strong> caractères) Arrays of characters, abgeschlossendurch das ASCII-Zeichen Nr. 0 (nicht zu verwechselnmit <strong>de</strong>r Ziffer 0 entsprechend ASCII-Nr. 48). Str<strong>in</strong>gs dürfen nichtbeliebig lang wer<strong>de</strong>n. Wenn nicht Arbeitsspeicher, Editor o<strong>de</strong>ran<strong>de</strong>re Faktoren vorher zuschlagen, muss man ab 32 kByte aufProbleme gefasst se<strong>in</strong>, wohlgmerkt beim e<strong>in</strong>zelnen Str<strong>in</strong>g, nichtbei e<strong>in</strong>em aus vielen Str<strong>in</strong>gs bestehen<strong>de</strong>n Text. Man stößt seltenan diese Grenze, <strong>de</strong>shalb wird sie <strong>in</strong> vielen Büchern nichterwähnt.Wir bevorzugen das Wort Str<strong>in</strong>g um hervorzuheben, dass essich hierbei um Zeichenfolgen <strong>in</strong> e<strong>in</strong>em bestimmten, sprachenspezifischenFormat han<strong>de</strong>lt. Zum Speichern <strong>de</strong>s Str<strong>in</strong>gs <strong>Alex</strong>ist e<strong>in</strong> Array of characters mit wenigstens fünf Elementen zu <strong>de</strong>klarieren:char myname[5];In an<strong>de</strong>ren Sprachen wer<strong>de</strong>n Str<strong>in</strong>gs an<strong>de</strong>rs dargestellt. E<strong>in</strong>Str<strong>in</strong>g lässt sich am Stück verarbeiten o<strong>de</strong>r durch Zugriff aufse<strong>in</strong>e Elemente. Man kann fertige Str<strong>in</strong>g-Funktionen verwen<strong>de</strong>no<strong>de</strong>r eigene Funktionen schreiben, muss sich dann aber auchselbst um die ASCII-Null kümmern.Will man bei <strong>de</strong>r E<strong>in</strong>gabe von Werten mittels <strong>de</strong>r Tastatur je<strong>de</strong>nbeliebigen Uns<strong>in</strong>n zulassen, dann muss man die E<strong>in</strong>gabenals lange (e<strong>in</strong>ige Zeilen) Str<strong>in</strong>gs übernehmen, die Str<strong>in</strong>gs prüfenund dann – sofern sie vernünftig s<strong>in</strong>d – <strong>in</strong> <strong>de</strong>n gewünschtenTyp umwan<strong>de</strong>ln. E<strong>in</strong> gutes Programm vertraut E<strong>in</strong>gabenniemals bl<strong>in</strong>dl<strong>in</strong>gs, son<strong>de</strong>rn prüft sie vor <strong>de</strong>r weiteren Verarbeitunggründlich. E<strong>in</strong> Programmbeispiel dazu f<strong>in</strong><strong>de</strong>t sich im Abschnitt1.11.7.2 Po<strong>in</strong>ter auf Typ void: xread.c auf Seite 243.Merke: Es gibt Arrays of characters, die ke<strong>in</strong>e Str<strong>in</strong>gs s<strong>in</strong>d,nämlich solche, die nicht mit <strong>de</strong>m ASCII-Zeichen Nr. 0 abgeschlossens<strong>in</strong>d. Sie müssen als Array angesprochen wer<strong>de</strong>n wiee<strong>in</strong> Array von Zahlen.Merke zweitens: E<strong>in</strong> e<strong>in</strong>zelnes Zeichen kann als Zeichen (character,’a’) o<strong>de</strong>r als Str<strong>in</strong>g (array of characters, "a") dargestelltwer<strong>de</strong>n. Für e<strong>in</strong> Programm s<strong>in</strong>d das verschie<strong>de</strong>ne D<strong>in</strong>ge.Strukturen E<strong>in</strong>e Struktur, auch als Verbund und <strong>in</strong> PAS-CAL als Record bezeichnet, vere<strong>in</strong>t Komponenten ungleichen


92 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Typs im Gegensatz zum Array. E<strong>in</strong>e Ordnung <strong>de</strong>r Komponentenliegt nicht vor, ebenfalls an<strong>de</strong>rs als beim Array. Strukturen dürfengeschachtelt wer<strong>de</strong>n, aber nicht sich selbst enthalten (ke<strong>in</strong>eRekursion). Möglich ist jedoch, dass e<strong>in</strong>e Struktur e<strong>in</strong>en Po<strong>in</strong>terauf sich selbst enthält – e<strong>in</strong> Po<strong>in</strong>ter ist ja nicht die Strukturselbst – womit Verkettungen hergestellt wer<strong>de</strong>n. Das Schlüsselwortlautet struct.E<strong>in</strong> typisches Beispiel für e<strong>in</strong>e Struktur ist e<strong>in</strong>e Personalo<strong>de</strong>rMitglie<strong>de</strong>rliste, bestehend aus alphanumerischen und numerischenKomponenten. Mit <strong>de</strong>n numerischen wird gerechnet,auf die alphanumerischen wer<strong>de</strong>n Str<strong>in</strong>gfunktionen angewen<strong>de</strong>t.Telefonnummern o<strong>de</strong>r Postleitzahlen s<strong>in</strong>d alphanumerischeGrößen, da Rechenoperationen mit ihnen s<strong>in</strong>nlos s<strong>in</strong>d. Wir erzeugene<strong>in</strong>en Strukturtyp ohne eigenen Namen und <strong>de</strong>klarierenzugleich e<strong>in</strong>e Variable namens mitglied:struct {char nachname[32];char vorname[32];<strong>in</strong>t beitrag;} Mitglied;Man kann auch zuerst nur die Struktur <strong>de</strong>f<strong>in</strong>ieren und <strong>in</strong> e<strong>in</strong>emzweiten Schritt Variablen vom Typ dieser Struktur:struct mg {char nachname[32];char vorname[32];<strong>in</strong>t beitrag;};struct mg Mitglied;Je<strong>de</strong> Datei ist e<strong>in</strong>e Struktur namens FILE, die <strong>in</strong> <strong>de</strong>r <strong>in</strong>clu<strong>de</strong>-Datei stdio.h <strong>de</strong>klariert ist:type<strong>de</strong>f struct {<strong>in</strong>t _cnt;unsigned charunsigned charshort _flag;char _file;} FILE;*_ptr;*_base;


1.3. BAUSTEINE EINES QUELLTEXTES 93Mit dieser type<strong>de</strong>f-Deklaration wird e<strong>in</strong> Strukturname FILEvere<strong>in</strong>bart, <strong>de</strong>r <strong>in</strong> weiteren Deklarationen als Typ auftritt. FILEist ke<strong>in</strong>e Variable, son<strong>de</strong>rn e<strong>in</strong> Synonym für obige Struktur. Anschließendlassen sich Variable vom Typ FILE o<strong>de</strong>r auch Dateipo<strong>in</strong>ter<strong>de</strong>klarieren:FILE myfile, yourfile;FILE *fp;Dies ist e<strong>in</strong> dritter Weg, <strong>de</strong>n wir im Abschnitt Weitere Namen fürTypen auf Seite 103 kennenlernen.In C/<strong>C++</strong> s<strong>in</strong>d alle Dateien ungeglie<strong>de</strong>rte Folgen von Bytes(Bytestreams), so dass es ke<strong>in</strong>en Unterschied zwischen Textfilesund sonstigen Dateien gibt. Die Glie<strong>de</strong>rung erzeugt das lesen<strong>de</strong>o<strong>de</strong>r schreiben<strong>de</strong> Programm. An<strong>de</strong>rs als <strong>in</strong> PASCAL ist daher<strong>de</strong>r Typ FILE nicht e<strong>in</strong> FILE of irgen<strong>de</strong>twas.E<strong>in</strong>e beson<strong>de</strong>re Struktur ist das Bitfeld. Die Strukturkomponentens<strong>in</strong>d e<strong>in</strong>zelne Bits o<strong>de</strong>r Gruppen von Bits, die überihren Komponentennamen angesprochen wer<strong>de</strong>n. E<strong>in</strong>e Bitfeld-Struktur darf ke<strong>in</strong>e weiteren Komponenten enthalten und sollmöglichst vom Basistyp unsigned se<strong>in</strong>. E<strong>in</strong> e<strong>in</strong>zelnes Bitfelddarf maximal die Länge e<strong>in</strong>es Masch<strong>in</strong>enwortes haben, es kannalso nicht über e<strong>in</strong>e Wortgrenze h<strong>in</strong>ausragen. Bitfel<strong>de</strong>r s<strong>in</strong>d ke<strong>in</strong>eArrays, es gibt ke<strong>in</strong>en In<strong>de</strong>x. Ebensowenig lassen sich Bitfel<strong>de</strong>rreferenzieren (&-Operator). Bitfel<strong>de</strong>r wer<strong>de</strong>n verwen<strong>de</strong>t, ummehrere Ja-ne<strong>in</strong>-Angaben <strong>in</strong> e<strong>in</strong>em Wort unterzubr<strong>in</strong>gen.Der Name e<strong>in</strong>er Strukturvariablen ist e<strong>in</strong> gewöhnlicher Variablenname,ke<strong>in</strong> Po<strong>in</strong>ter.1.3.6.5 UnionE<strong>in</strong>e Variable <strong>de</strong>s Typs union kann Werte unterschiedlichenTyps aufnehmen, zu e<strong>in</strong>em Zeitpunkt jedoch immer nur e<strong>in</strong>en.Es liegt <strong>in</strong> <strong>de</strong>r Hand <strong>de</strong>s Programms, über <strong>de</strong>n augenblicklichenTyp Buch zu führen. In FORTRAN dient die equivalence-Anweisung <strong>de</strong>mselben Zweck, <strong>in</strong> PASCAL <strong>de</strong>r variante Record.E<strong>in</strong>e Union belegt so viele Bytes wie <strong>de</strong>r längste <strong>in</strong> ihr untergebrachteDatentyp. Die Deklaration e<strong>in</strong>er Variablen als Unionsieht aus wie bei e<strong>in</strong>er Struktur:union unione<strong>in</strong>s {


94 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong><strong>in</strong>t i;double x;char c;} ux;Damit wird e<strong>in</strong> Unionstyp mit <strong>de</strong>m Namen unione<strong>in</strong>s <strong>de</strong>klariertund zugleich e<strong>in</strong>e Variable ux dieses Typs. Auf die jeweiligeVariable wird zugegriffen wie auf die Komponenten e<strong>in</strong>er Struktur:pr<strong>in</strong>tf("%d\n", ux.i);pr<strong>in</strong>tf("%f\n", ux.x);pr<strong>in</strong>tf("%c\n", ux.c);Man darf nur jeweils die Variable herausholen, die als letzte h<strong>in</strong>e<strong>in</strong>gestecktwor<strong>de</strong>n ist, an<strong>de</strong>rnfalls gibt es Überraschungen. DieUnion habe ich noch nie gebraucht, sie soll <strong>in</strong> <strong>de</strong>r Systemprogrammierungvorkommen und trägt sicher nicht zur Klarheit e<strong>in</strong>esProgrammes bei.1.3.6.6 AufzählungstypenDurch Aufzählen lassen sich benutzereigene Typen schaffen.Denkbar ist:enum wochentag {montag, dienstag, mittwoch, donnerstag,freitag, samstag, sonntag} tag;Die Variable tag ist vom Typ wochentag und kann die oben aufgezähltenWerte annehmen. Die Reihenfolge <strong>de</strong>r Werte ist maßgebendfür Vergleiche: montag ist kle<strong>in</strong>er als dienstag. AuchFarben bieten sich für e<strong>in</strong>en Aufzählungstyp an. In <strong>de</strong>r Masch<strong>in</strong>ewer<strong>de</strong>n Aufzählungstypen durch Ganzzahlen dargestellt, <strong>in</strong>sofernhan<strong>de</strong>lt es sich nicht um e<strong>in</strong>en neuen Typ. Aufzählungstypenverbessern die Lesbarkeit <strong>de</strong>r Programme.1.3.6.7 Po<strong>in</strong>ter (Zeiger)Po<strong>in</strong>ter s<strong>in</strong>d vom Geheimnis umwittert. Wer mit Po<strong>in</strong>tern umgehenkann (o<strong>de</strong>r wenigstens so tut), verfügt über magische Kräfteund steht mit f<strong>in</strong>steren Mächten im Bun<strong>de</strong>. Vermutlich frisst erauch kle<strong>in</strong>e K<strong>in</strong><strong>de</strong>r o<strong>de</strong>r unschuldige W<strong>in</strong>dows-Benutzer. Dabei


1.3. BAUSTEINE EINES QUELLTEXTES 95ist das Arbeiten mit Po<strong>in</strong>tern e<strong>in</strong>fach, man muss nur langsamund klar <strong>de</strong>nken und saubere Begriffe verwen<strong>de</strong>n.Po<strong>in</strong>ter erweitern die Möglichkeiten <strong>de</strong>s Programmierers. E<strong>in</strong>Beispiel für <strong>de</strong>n s<strong>in</strong>nvollen E<strong>in</strong>satz von Po<strong>in</strong>tern: das Sortierenvon Datensätzen. Die Datensätze enthalten <strong>in</strong> Form e<strong>in</strong>er StrukturNamen, Anschrift und weitere Angaben zu Personen. DieDatensätze sollen nach <strong>de</strong>m Namen sortiert wer<strong>de</strong>n, um e<strong>in</strong>enschnellen Zugriff zu ermöglichen. Wür<strong>de</strong>n wir die Datensätzenach H<strong>in</strong>zufügen o<strong>de</strong>r Löschen e<strong>in</strong>zelner Sätze je<strong>de</strong>smal neu sortieren,so wäre das mit viel Kopierarbeit verbun<strong>de</strong>n. Statt<strong>de</strong>ssenlegt man e<strong>in</strong> Hilfsfile, e<strong>in</strong>en In<strong>de</strong>x an, <strong>de</strong>r nur die Sortierschlüssel(Namen) und die Speicheradressen (Po<strong>in</strong>ter) <strong>de</strong>r zugehörigenDatensätze enthält. Dieser In<strong>de</strong>x wird sortiert, was mitwesentlich weniger Kopierarbeit verbun<strong>de</strong>n ist, weil die Sätzekürzer s<strong>in</strong>d. Suche ich nun nach e<strong>in</strong>em Datensatz mit e<strong>in</strong>em bestimmtenSchlüssel, so gehe ich <strong>in</strong> <strong>de</strong>n sortierten In<strong>de</strong>x, suchedort möglichst geschickt nach <strong>de</strong>m Schlüssel und spr<strong>in</strong>ge dannzu <strong>de</strong>r bei <strong>de</strong>m Schlüssel stehen<strong>de</strong>n Speicheradresse <strong>de</strong>s Datensatzes.Ich kann auch zwei In<strong>de</strong>xfiles mit verschie<strong>de</strong>nen SortierschLüsseln(Namen, Geburtstag) anlegen, während die Datensätzebestenfalls nach e<strong>in</strong>em e<strong>in</strong>zigen Schlüssel sortiert se<strong>in</strong>können. Meistens verzichtet man darauf, die Datensätze zu sortieren.Der dritte Band von DONALD E. KNUTH befasst sich nurmit Suchen und Sortieren, e<strong>in</strong> <strong>in</strong>teressantes Gebiet. Je<strong>de</strong>r verstehtdie Aufgaben, die Lösungen können trickreich se<strong>in</strong>.E<strong>in</strong> weiteres E<strong>in</strong>satzgebiet von Po<strong>in</strong>tern ist die Parameterübergabevon Funktionen, siehe Abschnitt 1.4.3 Parameterübergabeauf Seite 137. Und schließlich können C-Funktionen nure<strong>in</strong>en e<strong>in</strong>zigen Wert zurückgeben. Setzt sich ihr Ergebnis ausmehreren Werten zusammen – wie bei e<strong>in</strong>em Str<strong>in</strong>g o<strong>de</strong>r e<strong>in</strong>emVektor – so geht das nur über e<strong>in</strong>en Po<strong>in</strong>ter auf das erste Element<strong>de</strong>s Ergebnisses.Auf Variablen kann mittels ihres Namens o<strong>de</strong>r ihrer Speicheradresse(Hausnummer) zugegriffen wer<strong>de</strong>n. Die Speicheradressebraucht nicht absolut o<strong>de</strong>r relativ zu e<strong>in</strong>em Anfangswertbekannt zu se<strong>in</strong>, son<strong>de</strong>rn ist wie<strong>de</strong>rum über e<strong>in</strong>en Namen ansprechbar,<strong>de</strong>n Namen e<strong>in</strong>es Po<strong>in</strong>ters. Genaugenommen gehörendie Adressen zur Hardware und s<strong>in</strong>d für <strong>de</strong>n Programmiererfast immer be<strong>de</strong>utungslos, während die Po<strong>in</strong>ter Operan<strong>de</strong>n <strong>de</strong>rProgrammiersprache s<strong>in</strong>d, <strong>de</strong>nen zur Laufzeit als Wert Adres-


96 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>sen zugewiesen wer<strong>de</strong>n. Deshalb wer<strong>de</strong>n sie auch als Adressvariable26 bezeichnet. Po<strong>in</strong>ter haben Namen, Adressen s<strong>in</strong>d hexa<strong>de</strong>zimaleZahlen. Das Arbeiten mit Adressen beziehungsweisePo<strong>in</strong>tern erlaubt gelegentlich e<strong>in</strong>e elegante Programmierung, istmanchmal unvermeidlich und im übrigen älter als die Verwendungvon Variablennamen. Man muss nur stets sorgfältig die Variablevon ihrem Po<strong>in</strong>ter unterschei<strong>de</strong>n. Wenn man Arrays vonPo<strong>in</strong>tern auf Str<strong>in</strong>gs verwaltet, wird das schnell unübersichtlich.Es ist gute Praxis, aber nicht zw<strong>in</strong>gend, Po<strong>in</strong>ternamen mit e<strong>in</strong>emp beg<strong>in</strong>nen o<strong>de</strong>r aufhören zu lassen.E<strong>in</strong> Po<strong>in</strong>ter ist immer e<strong>in</strong> Po<strong>in</strong>ter auf e<strong>in</strong>en Variablentyp, unterUmstän<strong>de</strong>n auf e<strong>in</strong>en weiteren Po<strong>in</strong>ter. Typlose Po<strong>in</strong>ter gibtes nicht <strong>in</strong> C 27 . Der Wert e<strong>in</strong>es Po<strong>in</strong>ters ist ke<strong>in</strong>e Ganzzahl (<strong>in</strong>t)und darf nicht wie e<strong>in</strong>e Ganzzahl behan<strong>de</strong>lt wer<strong>de</strong>n, obwohl letztenEn<strong>de</strong>s die Speicheradressen (Hausnummern) ganze Zahlens<strong>in</strong>d. Die zulässigen, s<strong>in</strong>nvollen Operationen s<strong>in</strong>d an<strong>de</strong>re als beiganzen Zahlen. Hausnummern s<strong>in</strong>d Zahlen, die Multiplikationzweier Hausnummern ist möglich, ergibt jedoch nichts S<strong>in</strong>nvolles.Genauso ist es mit Po<strong>in</strong>tern.Aus e<strong>in</strong>em Variablennamen x entsteht <strong>de</strong>r Po<strong>in</strong>ter auf die Variable&x durch Voransetzen <strong>de</strong>s Referenzierungsoperators &.Umgekehrt wird aus <strong>de</strong>m Po<strong>in</strong>ter p die zugehörige Variable *pdurch Voransetzen <strong>de</strong>s Dereferenzierungsoperators *. Referenziertwer<strong>de</strong>n kann nur e<strong>in</strong> Objekt im Speicher, also e<strong>in</strong>e Variable,aber nicht e<strong>in</strong> Ausdruck o<strong>de</strong>r e<strong>in</strong>e Konstante 28 . Dereferenziertwer<strong>de</strong>n kann nur e<strong>in</strong> Po<strong>in</strong>ter, <strong>de</strong>r bereits auf e<strong>in</strong> Objektim Speicher verweist, <strong>de</strong>r also e<strong>in</strong>e Speicheradresse enthält. E<strong>in</strong>eSpeicheradresse belegt e<strong>in</strong> Objekt erst, wenn es <strong>de</strong>f<strong>in</strong>iert ist(e<strong>in</strong>en Wert hat), nicht schon mit <strong>de</strong>r Deklaration. Folgen<strong>de</strong> Zeilens<strong>in</strong>d zulässig beziehungsweise nicht:<strong>in</strong>t x = 12, *py;*py = x; /* zu frueh, unzulaessig */26 Es gibt natürlich auch Adresskonstanten, <strong>de</strong>ren Wert während<strong>de</strong>s Programmablaufs – von <strong>de</strong>r Initialisierung abgesehen– konstant bleibt.27 Der <strong>in</strong> ANSI-C e<strong>in</strong>geführte Po<strong>in</strong>ter auf <strong>de</strong>n Typ void ist e<strong>in</strong>Po<strong>in</strong>ter, <strong>de</strong>r zunächst auf ke<strong>in</strong>en bestimmten Typ zeigt.28 Konstanten s<strong>in</strong>d Teil <strong>de</strong>s Programmco<strong>de</strong>s.


1.3. BAUSTEINE EINES QUELLTEXTES 97py = &x;*py = x; /* erlaubt, aber ueberfluessig */pr<strong>in</strong>tf("%d%d\n", x, *py);Wir <strong>de</strong>klarieren e<strong>in</strong>e Variable x als ganzzahlig und weisen ihrzugleich e<strong>in</strong>en Wert zu. Sie ist damit <strong>de</strong>f<strong>in</strong>iert und belegt e<strong>in</strong>enSpeicherplatz. Ferner <strong>de</strong>klarieren wir py als Po<strong>in</strong>ter auf e<strong>in</strong>eGanzzahl. Der erste Versuch, py zu <strong>de</strong>referenzieren, ist verfrühtund führt zu e<strong>in</strong>em tödlichen Bus Error, da noch ke<strong>in</strong> Objekt y<strong>de</strong>f<strong>in</strong>iert ist, <strong>de</strong>ssen Adresse <strong>de</strong>r Po<strong>in</strong>ter py enthalten könnte.Der Po<strong>in</strong>ter ist <strong>de</strong>klariert, aber nicht <strong>de</strong>f<strong>in</strong>iert. Wohl aber kannich die <strong>de</strong>klarierte und <strong>de</strong>f<strong>in</strong>ierte Variable x referenzieren undihre Adresse <strong>de</strong>m Po<strong>in</strong>ter py zuweisen. Damit enthält auch ere<strong>in</strong>en Wert – und zwar die Adresse von x – und darf beliebigweiterverwen<strong>de</strong>t wer<strong>de</strong>n. Ausgegeben wird zweimal <strong>de</strong>r Wert 12.Die Zuweisung <strong>de</strong>s Wertes von x an *py ist überflüssig, da py aufdie Adresse zeigt, unter <strong>de</strong>r x abgelegt ist. Das Beispiel ver<strong>de</strong>utlicht<strong>de</strong>n Unterschied zwischen Deklaration und Def<strong>in</strong>ition undzeigt, dass man e<strong>in</strong>e Variable – genauso e<strong>in</strong>en Po<strong>in</strong>ter – außerauf <strong>de</strong>r l<strong>in</strong>ken Seite e<strong>in</strong>er Zuweisung erst dann verwen<strong>de</strong>n darf,wenn sie e<strong>in</strong>en Wert hat.Der Name von Arrays ist die Adresskonstante ihres erstenElementes (In<strong>de</strong>x 0). Die Bezeichnung <strong>de</strong>s Arraynamens alsPo<strong>in</strong>ter ist nicht korrekt, aber gebräuchlich. Po<strong>in</strong>ter als (Adress-)Variable können auf <strong>de</strong>r l<strong>in</strong>ken Seite e<strong>in</strong>er Zuweisung auftauchen,e<strong>in</strong> Arrayname ist wie je<strong>de</strong> Konstante als L<strong>in</strong>kswert ungeeignet.Der Name von Funktionen ohne das Klammernpaarist die Adresskonstante mit <strong>de</strong>r E<strong>in</strong>sprungadresse <strong>de</strong>r Funktion,auf die erste ausführbare Anweisung.E<strong>in</strong> Po<strong>in</strong>ter, <strong>de</strong>r auf die Adresse NULL verweist, wird Nullpo<strong>in</strong>tergenannt und zeigt auf ke<strong>in</strong> gültiges Datenobjekt. Wieim richtigen Leben gibt es ke<strong>in</strong>e Hausnummer Null. Se<strong>in</strong> Auftretenkennzeichnet e<strong>in</strong>e Ausnahme o<strong>de</strong>r e<strong>in</strong>en Fehler. Der WertNULL ist <strong>de</strong>r e<strong>in</strong>zige, <strong>de</strong>r direkt e<strong>in</strong>em Po<strong>in</strong>ter zugewiesen wer<strong>de</strong>nkann; je<strong>de</strong> Zuweisung e<strong>in</strong>er Ganzzahl ist e<strong>in</strong> Fehler, da Po<strong>in</strong>terke<strong>in</strong>e Ganzzahlen s<strong>in</strong>d. Ansonsten dürfen nur Werte, die sichaus e<strong>in</strong>er Po<strong>in</strong>teroperation o<strong>de</strong>r e<strong>in</strong>er entsprechen<strong>de</strong>n Funktion(<strong>de</strong>ren Ergebnis e<strong>in</strong> Po<strong>in</strong>ter ist) e<strong>in</strong>em Po<strong>in</strong>ter zugewiesen wer<strong>de</strong>n.


98 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Für Po<strong>in</strong>ter s<strong>in</strong>d die Operationen Inkrementieren, Dekrementierenund Vergleichen zulässig. Die Multiplikation zweierPo<strong>in</strong>ter dürfen Sie versuchen, es kommt aber nichts Brauchbaresheraus, meist e<strong>in</strong> Laufzeitfehler (memory fault). Inkrementierenbe<strong>de</strong>utet Erhöhung um e<strong>in</strong>e o<strong>de</strong>r mehrere E<strong>in</strong>heiten <strong>de</strong>s Typs,auf <strong>de</strong>n <strong>de</strong>r Po<strong>in</strong>ter verweist. Dekrementieren entsprechend e<strong>in</strong>eVerm<strong>in</strong><strong>de</strong>rung. Sie brauchen nicht zu berücksichtigen, um wievieleBytes es geht, das weiß <strong>de</strong>r Compiler aufgrund <strong>de</strong>r Deklaration.Diese Po<strong>in</strong>ter-Arithmetik erleichtert das Programmierenerheblich; <strong>in</strong> typlosen Sprachen muss man Bytes zählen.Wir wollen anhand e<strong>in</strong>iger Beispiele mit Arrays <strong>de</strong>n Gebrauchvon Po<strong>in</strong>tern ver<strong>de</strong>utlichen und <strong>de</strong>klarieren e<strong>in</strong> e<strong>in</strong>dimensionalesArray von vier Ganzzahlen:<strong>in</strong>t a[4];Der Name a für sich alle<strong>in</strong> ist <strong>de</strong>r Po<strong>in</strong>ter (Po<strong>in</strong>terkonstante)auf <strong>de</strong>n Anfang <strong>de</strong>s Arrays. Es sei mit <strong>de</strong>n Zahlen 4, 7, 1 und 2besetzt. Dann hat es folgen<strong>de</strong>n Aufbau:Po<strong>in</strong>ter Speicher Variable = Werta ↔ 4 ∗a = a[0] = 4a + 1 ↔ 7 ∗(a + 1) = a[1] = 7a + 2 ↔ 1 ∗(a + 2) = a[2] = 1a + 3 ↔ 2 ∗(a + 3) = a[3] = 2Der Pfeil ist zu lesen als zeigt auf o<strong>de</strong>r ist die Adresse von. DerWert <strong>de</strong>s Po<strong>in</strong>ters a – die Adresse also, unter <strong>de</strong>r die Zahl 4 abgelegtist – ist irgen<strong>de</strong><strong>in</strong>e kaum verständliche und völlig belangloseHexa<strong>de</strong>zimalzahl. Der Wert <strong>de</strong>r Variablen a[0] h<strong>in</strong>gegen ist4 und das aus Grün<strong>de</strong>n, die im wirklichen Leben zu suchen s<strong>in</strong>d.E<strong>in</strong> Zugriff auf das nicht <strong>de</strong>klarierte Element a[4] führt spätestenszur Laufzeit auf e<strong>in</strong>en Fehler. Bei <strong>de</strong>r Deklaration <strong>de</strong>s Arraysmuss se<strong>in</strong>e Länge bekannt se<strong>in</strong>. Später, wenn es nur um <strong>de</strong>nTyp geht – wie bei <strong>de</strong>r Parameterübergabe – reicht die Angabe<strong>in</strong>t *a.E<strong>in</strong> Str<strong>in</strong>g ist e<strong>in</strong> Array von Zeichen (characters), abgeschlossenmit <strong>de</strong>m unsichtbaren ASCII-Zeichen Nr. 0, hier dargestelltdurch ⊗. Infolge<strong>de</strong>ssen muss das Array immer e<strong>in</strong> Element längerse<strong>in</strong> als <strong>de</strong>r Str<strong>in</strong>g Zeichen enthält. Wir <strong>de</strong>klarieren e<strong>in</strong>en


1.3. BAUSTEINE EINES QUELLTEXTES 99ausreichend langen Str<strong>in</strong>g und belegen ihn gleichzeitig mit <strong>de</strong>mWort UNIX:char s[6] = "UNIX";Die Längenangabe 6 könnte entfallen, da <strong>de</strong>r Compiler aufgrund<strong>de</strong>r Zuweisung <strong>de</strong>r Str<strong>in</strong>gkonstanten die Länge weiß. Der Str<strong>in</strong>gist unnötig lang, aber vielleicht wollen wir später e<strong>in</strong> an<strong>de</strong>resWort dar<strong>in</strong> unterbr<strong>in</strong>gen. Das Array sieht dann so aus:Po<strong>in</strong>ter (Adresse) Speicher Wert (Variable)s ↔ U ∗s = s[0] = Us + 1 ↔ N ∗(s + 1) = s[1] = Ns + 2 ↔ I ∗(s + 2) = s[2] = Is + 3 ↔ X ∗(s + 3) = s[3] = Xs + 4 ↔ ⊗ ∗(s + 4) = s[4] = ⊗s + 5 ↔ ?? ∗(s + 5) = s[5] =??Die Fragezeichen <strong>de</strong>uten an, dass diese Speicherstelle nicht mite<strong>in</strong>em bestimmten Wert belegt ist. Der Zugriff ist erlaubt; wasdar<strong>in</strong> steht, ist nicht abzusehen. Man darf nicht davon ausgehen,dass Str<strong>in</strong>gs immer mit Spaces <strong>in</strong>itialisiert wer<strong>de</strong>n o<strong>de</strong>r Zahlenmit Null.Wir <strong>de</strong>klarieren nun e<strong>in</strong> zweidimensionales Array von Ganzzahlen,e<strong>in</strong>e nichtquadratische Matrix:<strong>in</strong>t a[3][4];die mit folgen<strong>de</strong>n Werten belegt sei:⎛⎝ 1 2 3 45 6 7 89 10 11 12Im Arbeitsspeicher steht dann folgen<strong>de</strong>s:Po<strong>in</strong>ter 2. Po<strong>in</strong>ter 1. SpeicherWert (Variable)a ↔ a[0] ↔ 1 ∗ ∗ a = ∗a[0] = a[0][0] = 1↔ a[0] + 1 ↔ 2 ∗(a[0] + 1) = a[0][1] = 2↔ a[0] + 2 ↔ 3 ∗(a[0] + 2) = a[0][2] = 3↔ a[0] + 3 ↔ 4 ∗(a[0] + 3) = a[0][3] = 4⎞⎠


100 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>a + 1 ↔ a[1] ↔ 5 ∗a[1] = a[1][0] = 5↔ a[1] + 1 ↔ 6 ∗(a[1] + 1) = a[1][1] = 6↔ a[1] + 2 ↔ 7 ∗(a[1] + 2) = a[1][2] = 7↔ a[1] + 3 ↔ 8 ∗(a[1] + 3) = a[1][3] = 8a + 2 ↔ a[2] ↔ 9 ∗a[2] = a[2][0] = 9↔ a[2] + 1 ↔ 10 ∗(a[2] + 1) = a[2][1] = 10↔ a[2] + 2 ↔ 11 ∗(a[2] + 2) = a[2][2] = 11↔ a[2] + 3 ↔ 12 ∗(a[2] + 3) = a[2][3] = 12Der Po<strong>in</strong>ter 2. Ordnung a zeigt auf e<strong>in</strong> Array aus 3 Po<strong>in</strong>tern1. Ordnung a[0], a[1] und a[2]. Die Po<strong>in</strong>ter 1. Ordnung a[0], a[1]und a[2] zeigen ihrerseits auf 3 Arrays bestehend aus je 4 Ganzzahlen.Gespeichert s<strong>in</strong>d 12 Ganzzahlen, die Po<strong>in</strong>ter 1. Ordnungs<strong>in</strong>d nicht gespeichert. Da die Elemente allesamt gleich großs<strong>in</strong>d (gleich viele Bytes lang), h<strong>in</strong><strong>de</strong>rt uns nichts daran, das Elementa[1][2], nämlich die Zahl 7, als Element a[0][6] aufzufassen.Die gespeicherten Werte lassen sich auch als e<strong>in</strong>dimensionalesArray b[12] verstehen. Solche Tricks müssen sorgfältigkommentiert wer<strong>de</strong>n, sonst blickt man nach kurzer Zeit nichtmehr durch und Außenstehen<strong>de</strong> nie. Versuchen Sie, an Handobigen Schemas folgen<strong>de</strong> Behauptungen nachzuvollziehen:∗∗(a+1) = 5(a+1) = a[0]+4 = a[1](∗(a+2)−1) = 8(∗(a+1)+1) = ∗(a[1]+1) = 6Im Programm 1.16 zeit.c auf Seite 61 haben wir e<strong>in</strong> Arrayvon Str<strong>in</strong>gs kennengelernt, also e<strong>in</strong> Array von Arrays vonZeichen, abgeschlossen jeweils mit <strong>de</strong>m ASCII-Zeichen Nr. 0. Esenthält die Namen <strong>de</strong>r Wochentage, mit Spaces aufgefüllt aufgleiche Länge:char *ptag[] = {"Sonntag, ", "Montag, ", ...};Hier wird e<strong>in</strong> Array von 7 Po<strong>in</strong>tern gespeichert. Dazu kommennatürlich noch die Str<strong>in</strong>gs, die wegen <strong>de</strong>s Aussehens auf <strong>de</strong>mBildschirm gleich lang s<strong>in</strong>d, aber vom Programm her ungleichlang se<strong>in</strong> dürften.Po<strong>in</strong>ter 2. Po<strong>in</strong>ter 1. Sp. Wert (Variable)ptag ↔ ptag[0] ↔ S ∗ ∗ ptag = ∗ptag[0] = ptag[0][0] = S↔ ptag[0] + 1↔ o ∗(ptag[0] + 1) = ptag[0][1] = o


1.3. BAUSTEINE EINES QUELLTEXTES 101↔ ptag[0] + 2↔ n ∗(ptag[0] + 2) = ptag[0][2] = n↔ ptag[0] + 3↔ n ∗(ptag[0] + 3) = ptag[0][3] = n↔ ptag[0] + 4↔ t ∗(ptag[0] + 4) = ptag[0][4] = t↔ ptag[0] + 5↔ a ∗(ptag[0] + 5) = ptag[0][5] = a↔ ptag[0] + 6↔ g ∗(ptag[0] + 6) = ptag[0][6] = g↔ ptag[0] + 7↔ , ∗(ptag[0] + 7) = ptag[0][7] =,↔ ptag[0] + 8↔ ∗(ptag[0] + 8) = ptag[0][8] =↔ ptag[0] + 9↔ ⊗ ∗(ptag[0] + 9) = ptag[0][9] = ⊗ptag + 1↔ ptag[1] ↔ M ∗ptag[1] = ptag[1][0] = M↔ ptag[1] + 1↔ o ∗(ptag[1] + 1) = ptag[1][1] = o↔ ptag[1] + 2↔ n ∗(ptag[1] + 2) = ptag[1][2] = nWir brechen nach <strong>de</strong>m n von Montag ab. ptag ist die Adresse<strong>de</strong>s Speicherplatzes, <strong>in</strong> <strong>de</strong>m ptag[0] abgelegt ist. ptag[0] istdie Adresse <strong>de</strong>s Speicherplatzes, <strong>in</strong> <strong>de</strong>m das Zeichen S abgelegtist. Durch zweimaliges Dereferenzieren von ptag erhalten wirdas Zeichen S. Die an<strong>de</strong>ren Zeichen liegen auf höheren Speicherplätzen,<strong>de</strong>ren Adressen wir durch Inkrementieren entwe<strong>de</strong>rvon ptag o<strong>de</strong>r von ptag[ ] erhalten, wobei man normalerweisedie zweidimensionale Struktur <strong>de</strong>s Arrays berücksichtigt, obwohl<strong>de</strong>m Computer das ziemlich gleich ist.Es s<strong>in</strong>d noch weitere Schreibweisen möglich, die oben wegen<strong>de</strong>r begrenzten Breite nicht unterzubr<strong>in</strong>gen s<strong>in</strong>d. Greifen wir dieletzte Zeile heraus, das n von Montag. Re<strong>in</strong> mit Indizes geschriebengilt:ptag[1][2] = nSo entwerfen wir vermutlich e<strong>in</strong> Programm, weil wir das Arbeitenmit Indizes aus <strong>de</strong>r Mathematik gewohnt s<strong>in</strong>d. Unter Ausnutzen<strong>de</strong>r Po<strong>in</strong>ter-Arithmetik gilt aber auch:∗(∗(ptag + 1) + 2) = ∗(ptag[1] + 2) = (∗(ptag + 1))[2] = ptag[1][2] = nFür <strong>de</strong>n Computer ist Po<strong>in</strong>ter-Schreibweise mit weniger Arbeitverbun<strong>de</strong>n, da er Adressen kennt und Indizes erst <strong>in</strong> Adressenumrechnen muß./* array2.c, Indizes und Po<strong>in</strong>ter */#<strong>in</strong>clu<strong>de</strong>


102 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>char a[] = "abcd"; /* Array of chars */<strong>in</strong>t ma<strong>in</strong>(){pr<strong>in</strong>tf("a[2] = %c\n", a[2]);pr<strong>in</strong>tf("*(a + 2) = %c\n", *(a + 2));pr<strong>in</strong>tf("*(2 + a) = %c\n", *(2 + a));pr<strong>in</strong>tf("2[a] = %c\n", 2[a]);return 0;}Quelle 1.23 : C-Programm zur Ver<strong>de</strong>utlichung <strong>de</strong>r Po<strong>in</strong>terarithmetikNun e<strong>in</strong>e leicht verrückte, aber richtige Überlegung. Wir <strong>de</strong>klarierenund <strong>in</strong>itialisieren e<strong>in</strong>en Str<strong>in</strong>g a[]. Mit Hilfe <strong>de</strong>r Standardfunktionpr<strong>in</strong>tf() geben wir das Element mit <strong>de</strong>r Hausnummer2 aus, also das Zeichen c. Dann greifen wir auf dasselbeElement zu, <strong>in</strong><strong>de</strong>m wir <strong>de</strong>n Po<strong>in</strong>ter auf <strong>de</strong>n Anfang <strong>de</strong>s Arraysum 2 hochzählen und anschließend <strong>de</strong>referenzieren. Jetzt fälltuns e<strong>in</strong>, dass die Addition – auch <strong>in</strong> <strong>de</strong>r Po<strong>in</strong>ter-Arithmetik –kommutativ ist, wir vertauschen die bei<strong>de</strong>n Summan<strong>de</strong>n. Erwartungsgemäßgeht das gut. Schließlich wan<strong>de</strong>ln wir die Po<strong>in</strong>ter-Schreibweise wie<strong>de</strong>r zurück <strong>in</strong> die In<strong>de</strong>x-Schreibweise unter Beibehaltung<strong>de</strong>r vertauschten Reihenfolge. Auch das funktioniert,logisch.Po<strong>in</strong>ter und Variable gehören verschie<strong>de</strong>nen Referenzebenen(level) an, die nicht gemischt wer<strong>de</strong>n dürfen. Der gleicheFall liegt auch <strong>in</strong> <strong>de</strong>r L<strong>in</strong>guistik vor, wenn über Wörter gesprochenwird. Vergleichen Sie die bei<strong>de</strong>n s<strong>in</strong>nvollen Sätze:• Kaffee ist e<strong>in</strong> Getränk.• Kaffee ist e<strong>in</strong> Substantiv.Im ersten Satz ist die Flüssigkeit geme<strong>in</strong>t, im zweiten das Wort,was gelegentlich durch Kursivschreibung o<strong>de</strong>r Gänsefüßchen ange<strong>de</strong>utetwird. Der erste Satz ist e<strong>in</strong>faches Deutsch, <strong>de</strong>r zweitegehört e<strong>in</strong>er Metasprache an, <strong>in</strong> <strong>de</strong>r Aussagen über die <strong>de</strong>utscheSprache vorgenommen wer<strong>de</strong>n, verwirren<strong>de</strong>rweise mit <strong>de</strong>nselbenWörtern und <strong>de</strong>rselben Grammatik. Genauso kann x e<strong>in</strong>eVariable o<strong>de</strong>r e<strong>in</strong> Po<strong>in</strong>ter auf e<strong>in</strong> Variable se<strong>in</strong> o<strong>de</strong>r e<strong>in</strong> Po<strong>in</strong>terauf e<strong>in</strong>en Po<strong>in</strong>ter auf e<strong>in</strong>e Variable. Erst e<strong>in</strong> Blick auf die Deklarationschafft Klarheit.


1.3. BAUSTEINE EINES QUELLTEXTES 103In C-Programmen wird gern von Po<strong>in</strong>tern Gebrauch gemacht.In <strong>de</strong>r C-Bibel von BRIAN W. KERNIGHAN und DENNIS M. RIT-CHIE ist ihnen daher e<strong>in</strong> ganzes, gut lesbares Kapitel gewidmet.1.3.6.8 Weitere Namen für Typen (type<strong>de</strong>f)Mithilfe <strong>de</strong>r type<strong>de</strong>f-Anweisung kann sich <strong>de</strong>r Benutzer eigene,zusätzliche Namen für C-Datentypen schaffen. Der neue Namemuss e<strong>in</strong><strong>de</strong>utig se<strong>in</strong>, darf also nicht mit e<strong>in</strong>em bereits an<strong>de</strong>rweitigbelegten Namen übere<strong>in</strong>stimmen. type<strong>de</strong>f erzeugt ke<strong>in</strong>enneuen Datentyp, son<strong>de</strong>rn veranlasst <strong>de</strong>n Compiler, im Programm<strong>de</strong>n neuen Namen wörtlich durch se<strong>in</strong>e Def<strong>in</strong>ition zu ersetzen,was man zur Prüfung auch von Hand machen kann. Derneue Typname ist e<strong>in</strong> Synonym. Der Zweck neuer Typnamen iste<strong>in</strong>e Verbesserung <strong>de</strong>r Lesbarkeit und Portierbarkeit <strong>de</strong>s Quelltextes.E<strong>in</strong>ige Beispiele. Wir wollen uns e<strong>in</strong>en Typnamen BOOLEANschaffen, <strong>de</strong>r zwar im Grun<strong>de</strong> nichts an<strong>de</strong>res ist als <strong>de</strong>r Typ <strong>in</strong>t,aber die Verwendung <strong>de</strong>utlicher erkennen lässt. Zu Beg<strong>in</strong>n <strong>de</strong>rDeklarationen o<strong>de</strong>r vor ma<strong>in</strong>() schreiben wir:type<strong>de</strong>f <strong>in</strong>t BOOLEAN;(die Großschreibung ist nicht zw<strong>in</strong>gend) und können anschließen<strong>de</strong><strong>in</strong>e Variable jane<strong>in</strong> als BOOLEAN <strong>de</strong>klarierenBOOLEANjane<strong>in</strong>;Der Compiler ersetzt <strong>de</strong>n Str<strong>in</strong>g BOOLEAN <strong>in</strong> Deklarationendurch <strong>de</strong>n Str<strong>in</strong>g <strong>in</strong>t, ähnlich wie es <strong>de</strong>r Präprozessor bei#<strong>de</strong>f<strong>in</strong>e-Anweisungen macht.In FORTRAN gibt es <strong>de</strong>n Datentyp complex, <strong>de</strong>n wir <strong>in</strong> Cdurch e<strong>in</strong>e Struktur nachbil<strong>de</strong>n:type<strong>de</strong>f struct {double real;double imag;} COMPLEX;Hiermit ist nur e<strong>in</strong> neuer, e<strong>in</strong>facherer Name für <strong>de</strong>n Strukturtypstruct geschaffen wor<strong>de</strong>n. Dann <strong>de</strong>klarieren wir die komplexeVariable:


104 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>COMPLEX z, R[20];z ist e<strong>in</strong>e komplexe Variable, R e<strong>in</strong> Array von 20 komplexen Variablen.Lei<strong>de</strong>r ist damit noch nicht alles erledigt, <strong>de</strong>nn die arithmetischenOperatoren von C gelten nur für Ganz- und Gleitkommazahlen,nicht für Strukturen. Wir müssen noch Funktionenfür die Operationen mit komplexen Variablen schreiben. InFORTRAN h<strong>in</strong>gegen gelten die gewohnten arithmetischen Operatorenauch für komplexe Daten. In <strong>C++</strong> lassen sich die Be<strong>de</strong>utungen<strong>de</strong>r Operatoren erweitern (überla<strong>de</strong>n), aber <strong>in</strong> C nicht.Bei Str<strong>in</strong>gs taucht das Problem <strong>de</strong>r Längenangabe auf. Folgen<strong>de</strong>rWeg ist gangbar, erfüllt aber nicht alle Wünsche:type<strong>de</strong>f char *STRING;Dann können wir schreibenSTRING fehler = "Falsche E<strong>in</strong>gabe";Der Compiler weiß die Länge <strong>de</strong>r Str<strong>in</strong>gs aufgrund <strong>de</strong>r Zuweisung<strong>de</strong>r Str<strong>in</strong>gkonstanten. H<strong>in</strong>gegen ist die nachstehen<strong>de</strong> Deklarationfehlerhaft, wie man durch E<strong>in</strong>setzen erkennt:STRINGabc[16];Die Typ<strong>de</strong>f<strong>in</strong>ition e<strong>in</strong>gesetzt ergibt:char*abc[16];und das ist ke<strong>in</strong> Str<strong>in</strong>g, son<strong>de</strong>rn e<strong>in</strong> Array von Str<strong>in</strong>gs. Erst zweimaligesDereferenzieren führt auf <strong>de</strong>n Typ char. Die Schreibweise:type<strong>de</strong>f char [16] STRING;STRING abc;die dieses Problem lösen wür<strong>de</strong>, haben wir zwar <strong>in</strong> e<strong>in</strong>em Buchgefun<strong>de</strong>n, wur<strong>de</strong> aber nicht von unserem Compiler angenommen.Ist man darauf angewiesen, dass e<strong>in</strong> Datentyp e<strong>in</strong>e bestimmteAnzahl von Bytes umfasst, erleichtert man das Portieren,<strong>in</strong><strong>de</strong>m man e<strong>in</strong>en eigenen Typnamen <strong>de</strong>klariert und imweiteren Verlauf nur diesen verwen<strong>de</strong>t. Bei e<strong>in</strong>er Portierung istdann nur die Typ<strong>de</strong>f<strong>in</strong>ition anzupassen. Es wer<strong>de</strong> e<strong>in</strong>e Ganzzahlvon vier Byte Länge verlangt. Dann <strong>de</strong>klariert man:


1.3. BAUSTEINE EINES QUELLTEXTES 105type<strong>de</strong>f <strong>in</strong>t INT4; /* Ganzzahl von 4 Bytes */INT4 i, j, k;und än<strong>de</strong>rt bei Bedarf nur die type<strong>de</strong>f-Zeile. Zweckmäßig packtman die Typen<strong>de</strong>f<strong>in</strong>ition <strong>in</strong> e<strong>in</strong>e private <strong>in</strong>clu<strong>de</strong>-Datei, die manfür mehrere Programme verwen<strong>de</strong>n kann.1.3.6.9 SpeicherklassenIn C gibt es vier Speicherklassen (storage classes):• auto• extern• register• staticDie Speicherklasse geht <strong>de</strong>m Typ <strong>in</strong> <strong>de</strong>r Deklaration voraus:static <strong>in</strong>t x;Die Klasse auto ist die Defaultklasse für lokale Variableund braucht nicht eigens angegeben zu wer<strong>de</strong>n. Variablen dieserKlasse leben nur <strong>in</strong>nerhalb <strong>de</strong>s Bereiches, <strong>in</strong> <strong>de</strong>m sie <strong>de</strong>klariertwur<strong>de</strong>n, und sterben beim Verlassen <strong>de</strong>s Bereiches, <strong>de</strong>r vonihnen belegte Speicher wird freigegeben.E<strong>in</strong>e globale Variable darf <strong>in</strong> e<strong>in</strong>em Programm nur e<strong>in</strong>mal<strong>de</strong>klariert wer<strong>de</strong>n. Erstreckt sich e<strong>in</strong> Programm über mehreregetrennt zu kompilieren<strong>de</strong> Dateien, so darf sie nur <strong>in</strong> e<strong>in</strong>er <strong>de</strong>rDateien <strong>de</strong>klariert wer<strong>de</strong>n. Da aber <strong>de</strong>r Compiler auch <strong>in</strong> <strong>de</strong>nübrigen Dateien <strong>de</strong>n Typ <strong>de</strong>r Variablen kennen muss, wird dieVariable hier als extern <strong>de</strong>klariert. Globale Variable s<strong>in</strong>d perDefault extern. Funktionen gehören stets <strong>de</strong>r Speicherklasse externan.register-Variable wer<strong>de</strong>n nach Möglichkeit <strong>in</strong> Registern nahe<strong>de</strong>m Rechenwerk gehalten und s<strong>in</strong>d damit schnell verfügbar.Ansonsten verhalten sie sich wie auto-Variable. Sie müssen vomTyp <strong>in</strong>t o<strong>de</strong>r char se<strong>in</strong>. E<strong>in</strong>e typische Anwendung s<strong>in</strong>d Schleifenzähler.Optimieren<strong>de</strong> Compiler ordnen von sich aus e<strong>in</strong>ige Variabledieser Speicherklasse zu. Auf register-Variable kann<strong>de</strong>r Referenzierungs-Operator & nicht angewen<strong>de</strong>t wer<strong>de</strong>n. Esist auch unsicher, ob das System <strong>de</strong>r register-Anweisung folgt.Am besten verzichtet man auf diese Speicherklasse.


106 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Lokale Operan<strong>de</strong>n gelten und leben nur <strong>in</strong>nerhalb <strong>de</strong>sBlockes, <strong>in</strong> <strong>de</strong>m sie <strong>de</strong>klariert wur<strong>de</strong>n. Durch die Zuordnungzur Speicherklasse static verlängert man ihre Lebensdauer –nicht ihren Geltungsbereich – über das En<strong>de</strong> <strong>de</strong>s Blockes h<strong>in</strong>aus.Bei e<strong>in</strong>em erneuten Aufruf <strong>de</strong>s Blockes hat e<strong>in</strong> static-Operand<strong>de</strong>n Wert, <strong>de</strong>n er beim vorherigen Verlassen <strong>de</strong>s Blockes hatte.1.3.6.10 GeltungsbereichE<strong>in</strong>e Variable gilt nur <strong>in</strong>nerhalb <strong>de</strong>s Bereiches (Programmabschnittes),zu <strong>de</strong>ssen Beg<strong>in</strong>n 29 sie <strong>de</strong>klariert wor<strong>de</strong>n ist. IhrSichtbarkeits- o<strong>de</strong>r Geltungsbereich (scope) ist dieser Bereich.Außerhalb <strong>de</strong>s zugehörigen Bereiches ist die Variable unbekannt(nicht existent) o<strong>de</strong>r unsichtbar (existent, aber nicht zugänglich).Der Name <strong>de</strong>r Variablen ist <strong>in</strong> diesem Zusammenhang be<strong>de</strong>utungslos.E<strong>in</strong> Bereich ist:• e<strong>in</strong> Programm,• e<strong>in</strong>e Funktion,• e<strong>in</strong> logischer Block zwischen { und },• e<strong>in</strong>e Datei.Variable, die vor allen Funktionen – <strong>in</strong> <strong>de</strong>r Regel vor ma<strong>in</strong>()– <strong>de</strong>klariert wer<strong>de</strong>n, gelten <strong>in</strong>folge<strong>de</strong>ssen global <strong>in</strong> allen Funktionen,die <strong>in</strong> <strong>de</strong>rselben Datei <strong>de</strong>klariert wer<strong>de</strong>n, das heißt imganzen Programm, wenn dieses nur aus e<strong>in</strong>er Datei besteht. Variable,die zu Beg<strong>in</strong>n e<strong>in</strong>er Funktion – vor allen Anweisungen <strong>in</strong><strong>de</strong>r Funktion – <strong>de</strong>klariert wer<strong>de</strong>n, gelten <strong>in</strong>nerhalb dieser Funktion,aber nicht außerhalb. Sie s<strong>in</strong>d lokal gültig. Variable, die zuBeg<strong>in</strong>n e<strong>in</strong>es Blockes – vor allen Anweisungen im Block – <strong>de</strong>klariertwer<strong>de</strong>n, gelten nur <strong>in</strong> diesem Block. Das kommt selten vor,ist aber völlig <strong>in</strong> Ordnung.Erstreckt sich e<strong>in</strong> Programm über mehrere Dateien, so geltenzu Beg<strong>in</strong>n e<strong>in</strong>er Datei – vor <strong>de</strong>n dar<strong>in</strong> enthaltenen Funktionen– <strong>de</strong>klarierte Operan<strong>de</strong>n global für die Funktionen <strong>in</strong> <strong>de</strong>r Datei,aber nicht für das gesamte Programm. Soll e<strong>in</strong> Operand globalim gesamten Programm gelten, so ist er <strong>in</strong> je<strong>de</strong>r Datei erneut zu29 In <strong>C++</strong> dürfen Variable an beliebiger Stelle <strong>in</strong>nerhalb e<strong>in</strong>esBereiches <strong>de</strong>klariert wer<strong>de</strong>n, jedoch muss dies vor ihrer erstenVerwendung erfolgen.


1.3. BAUSTEINE EINES QUELLTEXTES 107<strong>de</strong>klarieren. Dies wi<strong>de</strong>rspricht jedoch <strong>de</strong>r For<strong>de</strong>rung, dass e<strong>in</strong>und<strong>de</strong>rselbe Operand nur e<strong>in</strong>mal <strong>de</strong>klariert wer<strong>de</strong>n darf. DerAusweg liegt dar<strong>in</strong>, ihn nur e<strong>in</strong>mal <strong>in</strong> beschriebener Weise zu<strong>de</strong>klarieren und <strong>in</strong> allen an<strong>de</strong>ren Dateien vor die Deklarationdas Wort extern zu setzen. Damit ist <strong>de</strong>r For<strong>de</strong>rung nach E<strong>in</strong><strong>de</strong>utigkeitGenüge getan, und <strong>de</strong>r Compiler weiß trotz<strong>de</strong>m beije<strong>de</strong>r Datei, mit welchen Typen er es zu tun hat.Wird e<strong>in</strong> Operand <strong>de</strong>sselben Namens <strong>in</strong>nerhalb e<strong>in</strong>es Bereichesnochmals <strong>de</strong>klariert, so hat für diesen Bereich die lokaleDeklaration Vorrang vor <strong>de</strong>r äußeren Deklaration. Es wird e<strong>in</strong>neuer, lokaler Operand erzeugt. Der Geltungsbereich <strong>de</strong>s äußerenOperan<strong>de</strong>n hat e<strong>in</strong>e Lücke, <strong>de</strong>r äußere Operand wird verschattet.Das Konzept <strong>de</strong>s Geltungsbereiches lässt sich über e<strong>in</strong>Programm h<strong>in</strong>aus erweitern. Die exportierten Umgebungs-Variablen <strong>de</strong>r Sitzungsshell gelten für alle Prozesse e<strong>in</strong>er Sitzungund können von diesen abgefragt o<strong>de</strong>r verän<strong>de</strong>rt wer<strong>de</strong>n.Darüber h<strong>in</strong>aus s<strong>in</strong>d auch Variable <strong>de</strong>nkbar, die <strong>in</strong> e<strong>in</strong>em Verzeichnis,e<strong>in</strong>em Datei-System o<strong>de</strong>r <strong>in</strong> e<strong>in</strong>er Netz-Doma<strong>in</strong> gelten.Je größer <strong>de</strong>r Geltungsbereich ist, <strong>de</strong>sto sorgfältiger muss manmit <strong>de</strong>r Schreibberechtigung umgehen.1.3.6.11 LebensdauerBeim E<strong>in</strong>tritt <strong>in</strong> e<strong>in</strong>en Bereich wird für die <strong>in</strong> diesem Bereich <strong>de</strong>f<strong>in</strong>iertenVariablen Speicher zugewiesen (allokiert). Beim Verlassen<strong>de</strong>s Bereiches wird <strong>de</strong>r Speicher freigegeben, von <strong>de</strong>n Variablenbleibt ke<strong>in</strong>e Spur zurück. Ihre Lebensdauer (lifetime) istdie aktive Zeitspanne <strong>de</strong>s Bereiches. Beim nächsten Aufruf <strong>de</strong>sBereiches wird neuer Speicher zugewiesen und <strong>in</strong>itialisiert. DieseSpeicherklasse wird als auto bezeichnet und ist die Standardklassealler Variablen, für die nichts an<strong>de</strong>res vere<strong>in</strong>bart wird.Möchte man jedoch mit <strong>de</strong>n alten Werten weiterrechnen, somuss man die Variable <strong>de</strong>r Speicherklasse static zuweisen.Der Geltungsbereich wird davon nicht berührt, aber <strong>de</strong>r Speichersamt Inhalt bleibt beim Verlassen <strong>de</strong>r Funktion bestehen.Die Variable besteht, ist aber vorübergehend unsichtbar (existent,aber nicht zugänglich).


108 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.3.7 Operationen1.3.7.1 AusdrückeWir haben bisher Operan<strong>de</strong>n betrachtet, aber nichts mit ihnengemacht. Nun wollen wir uns ansehen, was man mit <strong>de</strong>n Operan<strong>de</strong>nanstellen kann. Der Operator bestimmt, was mit <strong>de</strong>mOperand geschieht. Unäre Operatoren wirken auf genau e<strong>in</strong>enOperan<strong>de</strong>n, b<strong>in</strong>äre auf zwei, ternäre auf drei. Mehr Operan<strong>de</strong>ns<strong>in</strong>d selten. Operator plus Operan<strong>de</strong>n bezeichnet man als Ausdruck(expression). E<strong>in</strong> Ausdruck hat nach se<strong>in</strong>er Auswertunge<strong>in</strong>en Wert und kann überall dort stehen, wo e<strong>in</strong> Wert verlangtwird. E<strong>in</strong>e Funktion, die e<strong>in</strong>en Wert zurückgibt, kann anstellee<strong>in</strong>es Ausdrucks o<strong>de</strong>r Wertes stehen.1.3.7.2 ZuweisungE<strong>in</strong>e Zuweisung (assignment) weist e<strong>in</strong>er Variablen e<strong>in</strong>en Wertzu. Der Operator ist das Gleichheitszeichen (ohne Doppelpunktwie <strong>in</strong> PASCAL, wegen Faulheit). Das Gleichheitszeichen darfvon Spaces umgeben se<strong>in</strong> und sollte es wegen <strong>de</strong>r besseren Lesbarkeitauch. Wert und Variable sollten vom selben Typ se<strong>in</strong>. Esgibt zwar <strong>in</strong> C automatische Typumwandlungen, aber man solltewenig Gebrauch davon machen. Sie führen zu <strong>de</strong>n berüchtigtenunlesbaren C-Programmen und gefähr<strong>de</strong>n die Portabilität.Da e<strong>in</strong> Ausdruck wie e<strong>in</strong>e Summe o<strong>de</strong>r e<strong>in</strong>e entsprechen<strong>de</strong>Funktion e<strong>in</strong>en Wert abliefert, kann <strong>in</strong> e<strong>in</strong>er Zuweisung anstelle<strong>de</strong>s Wertes immer e<strong>in</strong> Ausdruck stehen. Die Zuweisung selbstliefert <strong>de</strong>n zugewiesenen Wert zurück und kann daher als Wert<strong>in</strong> e<strong>in</strong>em übergeordneten Ausdruck auftreten.Auf <strong>de</strong>r rechten Seite e<strong>in</strong>er Zuweisung kann alles stehen, wase<strong>in</strong>en Wert hat, beispielsweise e<strong>in</strong>e Konstante, e<strong>in</strong> berechenbarerAusdruck o<strong>de</strong>r e<strong>in</strong>e Funktion, aber ke<strong>in</strong> Array und damitauch ke<strong>in</strong> Str<strong>in</strong>g. Solche Glie<strong>de</strong>r wer<strong>de</strong>n als r-Werte (r-value)bezeichnet. Auf <strong>de</strong>r l<strong>in</strong>ken Seite e<strong>in</strong>er Zuweisung kann alles stehen,was e<strong>in</strong>en Wert annehmen kann, beispielsweise e<strong>in</strong>e Variable,aber ke<strong>in</strong>e Konstante und ke<strong>in</strong>e Funktion. Diese Glie<strong>de</strong>rheißen l-Werte (l-value).E<strong>in</strong>e Zuweisung ist ke<strong>in</strong>e mathematische Gleichung. Die Formelx = x + 1 (1.1)


1.3. BAUSTEINE EINES QUELLTEXTES 109ist als Gleichung für je<strong>de</strong>n endlichen Wert von x falsch, als Zuweisungdagegen ist sie gebräuchlich und be<strong>de</strong>utet: Addiere 1 zu<strong>de</strong>m Wert von x und schreibe das Ergebnis <strong>in</strong> die Speicherstellevon x. Damit erhält die Variable x e<strong>in</strong>en neuen Wert. Bei e<strong>in</strong>erGleichung gibt es we<strong>de</strong>r alt noch neu, die Zeit spielt ke<strong>in</strong>e Rolle.Bei e<strong>in</strong>er Zuweisung gibt es e<strong>in</strong> Vorher und Nachher. Die Formelx + 2 = 5 (1.2)h<strong>in</strong>gegen ist als Gleichung <strong>in</strong> Ordnung, nicht aber als Zuweisung,da auf <strong>de</strong>r l<strong>in</strong>ken Seite e<strong>in</strong> Ausdruck steht und nicht e<strong>in</strong>e<strong>in</strong>facher Variablenname. Wegen dieser Diskrepanz zwischenGleichung und Zuweisung ist letztere etwas umstritten. Ihre Begründungkommt nicht aus <strong>de</strong>r Problemstellung, son<strong>de</strong>rn aus<strong>de</strong>r Hardware, nämlich <strong>de</strong>r Speicherbehandlung. Und gera<strong>de</strong>diese möchte man mit <strong>de</strong>n höheren Programmiersprachen ver<strong>de</strong>cken.1.3.7.3 Arithmetische OperationenDie arithmetischen Operationen s<strong>in</strong>d:• Vorzeichenumkehr - (unärer Operator)• Addition +• Subtraktion - (b<strong>in</strong>ärer Operator)• Multiplikation *• Division /• Modulus % (Divisionsrest, nur für ganze Zahlen)• Inkrement ++• Dekrement --Inkrement und Dekrement s<strong>in</strong>d Abkürzungen. Der Operatorkann vor o<strong>de</strong>r nach <strong>de</strong>m Operan<strong>de</strong>n (Präfix, Postfix) stehen. DerAusdrucki++gibt <strong>de</strong>n Wert von i zurück und erhöht ihn dann um e<strong>in</strong>s. DerAusdruck++i


110 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>erhöht <strong>de</strong>n Wert von i um e<strong>in</strong>s und gibt dann <strong>de</strong>n erhöhten Wertzurück. Für das Dekrement gilt das Entsprechen<strong>de</strong>. Der kompilierteCo<strong>de</strong> ist effektiver als <strong>de</strong>r <strong>de</strong>s äquivalenten Ausdrucksi = i + 1Spielt es vom Programm her ke<strong>in</strong>e Rolle, ob man <strong>de</strong>n Präfixo<strong>de</strong>r <strong>de</strong>n Postfix verwen<strong>de</strong>t, ist <strong>de</strong>r Präfix ++i unter Umstän<strong>de</strong>nschneller und daher zu bevorzugen. Ferner gibt es noch e<strong>in</strong>e abgekürzteSchreibweise für häufig wie<strong>de</strong>rkehren<strong>de</strong> Operationen:+=, -=, *=, /=Der Ausdrucky += xweist die Summe <strong>de</strong>r bei<strong>de</strong>n Operan<strong>de</strong>n <strong>de</strong>m l<strong>in</strong>ken Operan<strong>de</strong>nzu und ist somit gleichbe<strong>de</strong>utend mit <strong>de</strong>m Ausdruck:y = y + xEntsprechen<strong>de</strong>s gilt für die an<strong>de</strong>ren Abkürzungen. Die ausführlicheSchreibweise bleibt weiterh<strong>in</strong> erlaubt.Die Division für ganze Zahlen ist e<strong>in</strong>e an<strong>de</strong>re Operation alsfür Gleitkommazahlen (die übrigen Operationen auch, nur fälltes da nicht auf). In manchen Programmiersprachen wer<strong>de</strong>n folgerichtigunterschiedliche Operatoren verwen<strong>de</strong>t, <strong>in</strong> C nicht. DerCompiler entnimmt aus <strong>de</strong>m Zusammenhang, welche Divisiongeme<strong>in</strong>t ist. Diese Mehrfachverwendung e<strong>in</strong>es Operators wirdÜberladung genannt und spielt <strong>in</strong> objektorientierten Sprachenwie <strong>C++</strong> e<strong>in</strong>e Rolle. In FORTRAN, das <strong>de</strong>n komplexen Zahlentypkennt, gelten die arithmetischen Operatoren auch für diesen.Vorstellbar ist ebenso e<strong>in</strong>e Addition (Verkettung) von Str<strong>in</strong>gs.1.3.7.4 Logische OperationenDie logischen Operationen s<strong>in</strong>d:• bitweise Negation (not) ~ (Til<strong>de</strong>)• ausdrucksweise Negation (not) !• bitweises Und (and) &• ausdrucksweises Und (and) &&


1.3. BAUSTEINE EINES QUELLTEXTES 111• bitweises exklusives O<strong>de</strong>r (xor) ^ (Circumflex, caret)• bitweises <strong>in</strong>klusives O<strong>de</strong>r (or) |• ausdrucksweises <strong>in</strong>klusives O<strong>de</strong>r (or) ||Auch hier gibt es abgekürzte Schreibweisen:^=, |=, &=Der Ausdrucky &= xbe<strong>de</strong>utet dasselbe wiey = y & xDie Operan<strong>de</strong>n y und x wer<strong>de</strong>n bitweise durch Und verknüpft,das Ergebnis wird y zugewiesen. Entsprechen<strong>de</strong>s gilt für die bei<strong>de</strong>nan<strong>de</strong>ren Abkürzungen.Der Unterschied zwischen e<strong>in</strong>er ausdrucksweisen und e<strong>in</strong>erbitweisen logischen Operation ist folgen<strong>de</strong>r: In C gilt <strong>de</strong>rZahlenwert 0 als logisch falsch (false), je<strong>de</strong>r Wert ungleich 0 alslogisch wahr (true). Die Zeilen:...<strong>in</strong>t x = 0;if (x) pr<strong>in</strong>tf("if-Zweig\n");else pr<strong>in</strong>tf("else-Zweig\n");...führen zur Ausführung <strong>de</strong>s else-Zweiges. Die Variable x hat<strong>de</strong>n Wert 0, bei <strong>de</strong>m auch alle Bits auf 0 stehen. Sowie e<strong>in</strong> beliebigesBit auf 1 stün<strong>de</strong>, hätte die Variable e<strong>in</strong>en Wert ungleich0 und wür<strong>de</strong> als wahr angesehen. Die ausdrucksweise Negation:if (!x) pr<strong>in</strong>tf ...kehrt die Verhältnisse um, <strong>de</strong>r if-Zweig wird ausgeführt. Diebitweise Negation hätte hier zwar <strong>de</strong>nselben Erfolg, wäre jedochnicht s<strong>in</strong>nvoll, da die e<strong>in</strong>zelnen Bits nicht <strong>in</strong>teressieren.Der Buchstabe G wird <strong>in</strong> 7-bit-ASCII durch die Bitfolge1000111 dargestellt. Ihre bitweise Negation ist 0111000, was <strong>de</strong>rZiffer 8 entspricht. Das M<strong>in</strong>i-Programm:


112 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>/* Bitweise Negation */#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){char x = ’G’;pr<strong>in</strong>tf("%c %c\n", x, ~x);return 0;}Quelle 1.24 : C-Programm zur Veranschaulichung <strong>de</strong>r bitweisenNegationgibt <strong>de</strong>n Buchstaben G und die Ziffer 8 aus, zum<strong>in</strong><strong>de</strong>st auf Masch<strong>in</strong>en,die <strong>de</strong>n 7-bit-ASCII-Zeichensatz verwen<strong>de</strong>n. Der Zweck<strong>de</strong>r bitweisen Operation ist <strong>de</strong>r Umgang mit Informationen, dienicht <strong>in</strong> e<strong>in</strong>em Wert als Ganzem, son<strong>de</strong>rn <strong>in</strong> e<strong>in</strong>zelnen Bits stecken.Das kommt bei <strong>de</strong>r Systemprogrammierung vor. Beispielsweiselässt sich die Information, ob e<strong>in</strong> Gerät e<strong>in</strong>- o<strong>de</strong>r ausgeschaltetist, <strong>in</strong> e<strong>in</strong>em Bit unterbr<strong>in</strong>gen. In <strong>de</strong>r Anwendungsprogrammierungist man meist großzügiger und spendiert e<strong>in</strong>e ganzeInteger-Variable dafür.Merke: Ausdrucksweise logische Operationen und die nochfolgen<strong>de</strong>n Vergleichs-Operationen haben e<strong>in</strong> Ergebnis, das wahro<strong>de</strong>r falsch lautet (nicht-0 o<strong>de</strong>r 0). Bitweise logische Operationenkönnen je<strong>de</strong>s beliebige Ergebnis im Bereich <strong>de</strong>r ganzen Zahlenhaben.1.3.7.5 VergleicheDie Vergleichs- o<strong>de</strong>r Relations-Operationen s<strong>in</strong>d:• gleich == (weil = schon die Zuweisung ist)• ungleich !=• kle<strong>in</strong>er =• Bed<strong>in</strong>gte Bewertung ?:


1.3. BAUSTEINE EINES QUELLTEXTES 113Das Ergebnis e<strong>in</strong>es Vergleichs ist e<strong>in</strong> boolescher Wert, also trueo<strong>de</strong>r false beziehungsweise <strong>in</strong> C die entsprechen<strong>de</strong>n Zahlennicht-0 o<strong>de</strong>r 0.E<strong>in</strong> häufiger Fehler ist die Verwendung <strong>de</strong>s e<strong>in</strong>fachen Gleichheitszeichensfür die Abfrage auf Gleichheit. Dieser Fehler istschwierig zu erkennen, da <strong>de</strong>r fehlerhafte Ausdruck syntaktischkorrekt ist, er be<strong>de</strong>utet nur e<strong>in</strong>e Zuweisung an Stelle <strong>de</strong>s beabsichtigtenVergleichs:if (x = 0) { ... /* statt (x == 0) */Der Compiler protestiert nicht. Da <strong>in</strong> Vergleichen oft auf e<strong>in</strong>erSeite Ausdrücke wie Konstanten vorkommen, die nicht auf <strong>de</strong>rl<strong>in</strong>ken Seite e<strong>in</strong>er Zuweisung stehen können (r-values), empfiehltes sich, diese auf die l<strong>in</strong>ke Seite <strong>de</strong>s Vergleichs zu stellen:if (0 == x) { ..Bei <strong>de</strong>m falschen Operator protestiert dann <strong>de</strong>r Compiler o<strong>de</strong>rSyntaxprüfer. E<strong>in</strong>fach e<strong>in</strong>e kle<strong>in</strong>e Angewohnheit, die die Arbeiterleichtert.Pfiffig ist die Bed<strong>in</strong>gte Bewertung (conditional operator),auch Bed<strong>in</strong>gter Ausdruck genannt. Der Ausdruck:z = (a < 0) ? -a : ahat dieselbe Wirkung wie:if (a < 0)z = -a;elsez = a;Er weist <strong>de</strong>r Variablen z <strong>de</strong>n Betrag von a zu. Rechts <strong>de</strong>s Gleichheitszeichensstehen drei Ausdrücke, die auch zusammengesetztse<strong>in</strong> dürfen. Die ganze Bed<strong>in</strong>gte Bewertung ist selbst wie<strong>de</strong>r e<strong>in</strong>Ausdruck wie e<strong>in</strong>e Zuweisung und kann überall stehen, wo e<strong>in</strong>Wert verlangt wird. Die Bed<strong>in</strong>gte Bewertung ist e<strong>in</strong>er <strong>de</strong>r seltenenternären o<strong>de</strong>r triadischen Operatoren (drei Operan<strong>de</strong>n) undführt zu schnellerem Co<strong>de</strong> als if - else. Welchen Wert nimmtz <strong>in</strong> folgen<strong>de</strong>m Beispiel an?z = (a >= b) ? a : bE<strong>in</strong>e Anwendung f<strong>in</strong><strong>de</strong>n Sie im Abschnitt 1.4.7 Rekursiver Aufrufe<strong>in</strong>er Funktion auf Seite 159.


114 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.3.7.6 BitoperationenDie Bit-Operationen s<strong>in</strong>d:• shift l<strong>in</strong>ks Bei vorzeichenlosen Ganzzahlen ist e<strong>in</strong> Shiften nach l<strong>in</strong>ks gleichbe<strong>de</strong>utendmit e<strong>in</strong>er Multiplikation mit 2, e<strong>in</strong> Shiften nachrechts mit e<strong>in</strong>er Division durch 2. Auf die l<strong>in</strong>ks o<strong>de</strong>r rechts wegfallen<strong>de</strong>Stelle ist zu achten, nachgeschoben am an<strong>de</strong>ren En<strong>de</strong>wird e<strong>in</strong>e Null. Die Shift-Operation ist schnell. Weiterh<strong>in</strong> beziehensich e<strong>in</strong>ige logische Operationen auf Bits (siehe oben). Auchhier s<strong>in</strong>d Abkürzungen möglich:=Der Ausdrucky


1.3. BAUSTEINE EINES QUELLTEXTES 115k = i « j;pr<strong>in</strong>tf("E<strong>in</strong>gabe %d um %d Bits nach l<strong>in</strong>ks: %d\n", i, j, k)k = i » j;pr<strong>in</strong>tf("E<strong>in</strong>gabe %d um %d Bits nach rechts: %d\n", i, j, k)k = i & j;pr<strong>in</strong>tf("E<strong>in</strong>gabe %d mit %d bitweise und: %d\n", i, j, k);k = i | j;pr<strong>in</strong>tf("E<strong>in</strong>gabe %d mit %d bitweise o<strong>de</strong>r: %d\n", i, j, k)return 0;}Quelle 1.25 : C-Programm mit Bitoperationen1.3.7.7 st o<strong>in</strong>teroperationenFolgen<strong>de</strong> Operationen behan<strong>de</strong>ln Po<strong>in</strong>ter:• Referenzierung &• Dereferenzierung * o<strong>de</strong>r bei Arrays [ ]• Strukturverweis -> (m<strong>in</strong>us größer, bei Strukturpo<strong>in</strong>tern)• Strukturverweis . (Punkt, bei Strukturnamen)Weiterh<strong>in</strong> s<strong>in</strong>d folgen<strong>de</strong> für Ganzzahlen zulässige Operationenfür Po<strong>in</strong>ter <strong>de</strong>f<strong>in</strong>iert:• Vergleich zweier Po<strong>in</strong>ter auf <strong>de</strong>nselben Typ• Inkrementierung (Addition e<strong>in</strong>er ganzen Zahl)• Dekrementierung (Subtraktion e<strong>in</strong>er ganzen Zahl)• Subtraktion zweier Po<strong>in</strong>ter <strong>de</strong>sselben TypsDer Vergleich zweier gleichartiger Po<strong>in</strong>ter auf Übere<strong>in</strong>stimmungist immer möglich, e<strong>in</strong> Vergleich größer-kle<strong>in</strong>er setzt e<strong>in</strong>e bestimmteOrdnung <strong>de</strong>r Adressen voraus und ist problematisch,man lässt besser die F<strong>in</strong>ger davon:double *p1, *p2;if (p1 == p2) {} /* ok */if (p1 != p2) {} /* ok */if (p1 == NULL) {} /* ok */if (p1 < p2) {} /* gefaehrlich */


116 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Bei <strong>de</strong>r Addition o<strong>de</strong>r Subtraktion e<strong>in</strong>er ganzen Zahl be<strong>de</strong>utetdie ganze Zahl nicht e<strong>in</strong>e Anzahl von Bytes, son<strong>de</strong>rn e<strong>in</strong>e Anzahlvon Objekten <strong>de</strong>s zum Po<strong>in</strong>ter gehörigen Datentyps. Manbraucht sich also nicht darum zu kümmern, wieviele Bytes <strong>de</strong>rDatentyp belegt:double x, vektor[10];x = *vektor; /* erstes Element, In<strong>de</strong>x 0 */x = *(vektor + 2); /* uebernaechstes Element */Die selten vorkommen<strong>de</strong> Subtraktion zweier gleichartiger Po<strong>in</strong>terliefert die Anzahl <strong>de</strong>r zwischen <strong>de</strong>n bei<strong>de</strong>n Po<strong>in</strong>tern liegen<strong>de</strong>nDatenobjekte.1.3.7.8 E<strong>in</strong>- und Ausgabe-OperationenIn C gibt es ke<strong>in</strong>e Operatoren zur E<strong>in</strong>- o<strong>de</strong>r Ausgabe, vergleichbarmit read o<strong>de</strong>r write <strong>in</strong> PASCAL o<strong>de</strong>r FORTRAN. Statt<strong>de</strong>ssengreift man entwe<strong>de</strong>r auf Systemaufrufe <strong>de</strong>s Betriebssystems(z. B. UNIX) zurück o<strong>de</strong>r besser auf Funktionen <strong>de</strong>rC-Standardbibliothek, die letzten En<strong>de</strong>s auch Systemaufrufeverwen<strong>de</strong>n, nur <strong>in</strong>telligent verpackt. Die Systemaufrufe habene<strong>in</strong>e etwas schwierigere Syntax, erlauben dafür aber auch D<strong>in</strong>geaußerhalb <strong>de</strong>s Üblichen. Wer portabel für verschie<strong>de</strong>ne Betriebssystemeprogrammieren möchte, bevorzugt die Standardfunktionen,da sie die Unterschie<strong>de</strong> ver<strong>de</strong>cken. Wenn ke<strong>in</strong>e Grün<strong>de</strong> dagegensprechen, nimmt man die Standardfunktionen.Die UNIX-Systemaufrufe s<strong>in</strong>d <strong>in</strong> <strong>de</strong>r Sektion 2 <strong>de</strong>s Handbuchszu f<strong>in</strong><strong>de</strong>n, die wichtigsten lauten open(2), close(2),read(2) und write(2). Hier e<strong>in</strong> Programmbeispiel:/* Demo Systemaufruf open(2) */#<strong>in</strong>clu<strong>de</strong> /* wegen puts(3) */#<strong>in</strong>clu<strong>de</strong> /* wegen open(2) */#<strong>in</strong>clu<strong>de</strong>


1.3. BAUSTEINE EINES QUELLTEXTES 117char *buffer = "UNIX ist prima.";if (argc < 2){puts("Filenamen vergessen");return(-1);}/* File muss bereits existieren */fil<strong>de</strong>s = open(argv[1], O WRONLY); /* File-Deskriptor */bufsize = (size t)strlen(buffer);if (fil<strong>de</strong>s > 2) {puts("open() erfolgreich");n = write(fil<strong>de</strong>s, (void *)buffer, bufsize);if (n == bufsize) {puts("write() erfolgreich");}close(fil<strong>de</strong>s);}else {puts("Fehler bei open()");return(-1);}return 0;}Quelle 1.26 : C-Programm Ausgabe per Systemaufruf write(2)Mittels open(2) öffnen wir die Datei, <strong>de</strong>ren Name als erstesArgument übergeben wird, zum Schreiben. Die DAtei mussbereits vorhan<strong>de</strong>n se<strong>in</strong>. Der Systemaufruf gibt e<strong>in</strong>en Datei-Deskriptor zurück, e<strong>in</strong>e fortlaufen<strong>de</strong> Nummer <strong>de</strong>r vom Programmgeöffneten Dateien, beg<strong>in</strong>nend mit 3. Dann schreiben wir<strong>de</strong>n <strong>in</strong> e<strong>in</strong>em Puffer abgelegten Str<strong>in</strong>g zum Datei-Deskriptor undschließen die Datei. Der Rest s<strong>in</strong>d kle<strong>in</strong>e Maßnahmen zur Fehlerbehandlung.Die C-Standardfunktionen s<strong>in</strong>d <strong>in</strong> <strong>de</strong>r Sektion 3 <strong>de</strong>s Handbuchszu f<strong>in</strong><strong>de</strong>n, die wichtigsten lauten fopen(3), fclose(3),scanf(3) und pr<strong>in</strong>tf(3). Hier e<strong>in</strong> Programmbeispiel:/* Demo Standardfunktion fopen(3) */#<strong>in</strong>clu<strong>de</strong> /* wegen fopen(3), fputs(3) usw. */


118 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong><strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[]){FILE *fp; /* File-Po<strong>in</strong>ter */char *str<strong>in</strong>g = "UNIX ist prima.";<strong>in</strong>t x;if (argc < 2){puts("Filenamen vergessen");return(-1);}/* File braucht noch nicht zu existieren */fp = fopen(argv[1], "w");if (fp != NULL) {puts("fopen() erfolgreich");x = fputs(str<strong>in</strong>g, fp);if (x != EOF) {puts("fputs() erfolgreich");}fclose(fp);}else {puts("Fehler bei fopen()");return(-1);}return 0;}Quelle 1.27 : C-Programm Ausgabe per Standardfunktionfputs(3)Das Programm macht im Grun<strong>de</strong> das Gleiche wie das vorangegangene,die Schreibfunktion fputs(3) ist jedoch optimiertfür das Schreiben von Str<strong>in</strong>gs <strong>in</strong> e<strong>in</strong>e Datei. Es gibt auch e<strong>in</strong>eStandardfunktion fwrite(3) zum Schreiben e<strong>in</strong>es Blocks b<strong>in</strong>ärerDaten aus e<strong>in</strong>em Puffer <strong>in</strong> e<strong>in</strong>e Datei. E<strong>in</strong> DAtei-Po<strong>in</strong>terist e<strong>in</strong> Po<strong>in</strong>ter auf e<strong>in</strong>e Struktur <strong>de</strong>s Typs FILE, die <strong>in</strong> <strong>de</strong>rInclu<strong>de</strong>-Datei stdio.h <strong>de</strong>f<strong>in</strong>iert ist.


1.3. BAUSTEINE EINES QUELLTEXTES 1191.3.7.9 Sonstige OperationenFerner bietet C noch e<strong>in</strong>ige Operatoren für verschie<strong>de</strong>ne Aufgaben:• Datentyp-Umwandlung (cast-Operator) ()• Komma-Operator ,• sizeof-Operator sizeof()Der cast-Operator o<strong>de</strong>r Umwandlungsoperator enthält <strong>in</strong><strong>de</strong>n run<strong>de</strong>n Klammern e<strong>in</strong>e skalare Typbezeichnung ohneSpeicherklasse und geht <strong>de</strong>m umzuwan<strong>de</strong>ln<strong>de</strong>n skalaren Operan<strong>de</strong>nunmittelbar voraus:<strong>in</strong>t n;double y;y = sqrt((double) n);n sei e<strong>in</strong>e Ganzzahl. Die Funktion sqrt() erwartet jedoch alsArgument e<strong>in</strong>e Gleitkommazahl doppelter Genauigkeit. Die Typumwandlungvon n wird durch <strong>de</strong>n cast-Operator (double)bewirkt. Bei <strong>de</strong>r Typumwandlung können Bits o<strong>de</strong>r Dezimalstellenverlorengehen, wenn <strong>de</strong>r neue Typ kürzer ist als <strong>de</strong>r alte.Die Typumwandlung gilt nur im Zusammenhang mit <strong>de</strong>mcast-Operator und hat für die weiteren Anwendungen <strong>de</strong>r Variablenke<strong>in</strong>e Be<strong>de</strong>utung. Manche Compiler beanstan<strong>de</strong>n e<strong>in</strong>encast-Operator auf <strong>de</strong>r l<strong>in</strong>ken Seite e<strong>in</strong>er Zuweisung (als l-Wert).Der Komma-Operator trennt <strong>in</strong> e<strong>in</strong>er Auflistung von Ausdrückendiese vone<strong>in</strong>an<strong>de</strong>r. Sie wer<strong>de</strong>n von l<strong>in</strong>ks nach rechts abgearbeitet.Das Ergebnis <strong>de</strong>r Auflistung hat Typ und Wert <strong>de</strong>srechts außen stehen<strong>de</strong>n Ausdrucks. E<strong>in</strong> Beispiel:<strong>in</strong>t i, j = 10;i = (j++, j += 100, 999);pr<strong>in</strong>tf("%d", i);Hier wird zuerst j um 1 erhöht, dann dazu 100 addiert undschließlich <strong>de</strong>m gesamten Ausdruck <strong>de</strong>r Wert 999 zugewiesen. jhat also nach <strong>de</strong>n Operationen <strong>de</strong>n Wert 111, i <strong>de</strong>n Wert 999,<strong>de</strong>r ausgegeben wird. Der Komma-Operator wird oft im Kopfvon for-Schleifen verwen<strong>de</strong>t. Das Komma zwischen Variablennamen<strong>in</strong> Deklarationen o<strong>de</strong>r <strong>in</strong> e<strong>in</strong>er Argumentliste ist ke<strong>in</strong>


120 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Operator. Die Reihenfolge <strong>de</strong>r Abarbeitung solcher Listen ist unsicher.Der sizeof-Operator gibt die Größe <strong>de</strong>s Operan<strong>de</strong>n <strong>in</strong> Byteszurück. Der Operand kann e<strong>in</strong>e Variable, e<strong>in</strong> Ausdruck o<strong>de</strong>re<strong>in</strong> Datentyp se<strong>in</strong>, auch e<strong>in</strong> zusammengesetzter. E<strong>in</strong> Ausdruckwird dabei nicht ausgewertet. Dagegen können Funktionen o<strong>de</strong>rBitfel<strong>de</strong>r nicht als Operand von sizeof auftreten. Mit Hilfe <strong>de</strong>sOperators vermei<strong>de</strong>t man Annahmen über die Größe von Variablenbei Speicherreservierungen, das Programm wird portabler.Der Ausdrucksizeof(x)liefert die Größe von x <strong>in</strong> Bytes als vorzeichenlose Ganzzahl zurück.sizeof wird während <strong>de</strong>r Übersetzung ausgewertet (nichtjedoch vom Präprozessor) und verhält sich zur Laufzeit wie e<strong>in</strong>ekonstante ganze Zahl.1.3.7.10 Vorrang und ReihenfolgeEs gibt <strong>in</strong> C/<strong>C++</strong> ähnlich wie <strong>in</strong> <strong>de</strong>r Mathematik genaue Regelnüber <strong>de</strong>n Vorrang (prece<strong>de</strong>nce) <strong>de</strong>r Operatoren. Es ist jedochnicht sicher, dass alle C-Compiler sich genau an die Vorgaben<strong>de</strong>s ANSI-Vorschlags halten. Zu<strong>de</strong>m hat man beim Programmierenmeist nicht alle Regeln im Kopf, so dass es besserist, die Ausdrücke durch run<strong>de</strong> Klammern klar und e<strong>in</strong><strong>de</strong>utigzu kennzeichnen. Überflüssige Klammerpaare stören <strong>de</strong>n Compilernicht. Hier die Liste <strong>de</strong>r Operatoren von C mit nach untenabnehmen<strong>de</strong>m Rang:( ) [ ] -> .! ~ ++ -- - (cast) * & sizeof* / %+ ->< >=== !=&^|&&


1.3. BAUSTEINE EINES QUELLTEXTES 121||? := += -= *= /= %= = &= ^= |=,Zuerst wer<strong>de</strong>n also die run<strong>de</strong>n Klammern ausgewertet; wie <strong>in</strong><strong>de</strong>r Mathematik haben sie Vorrang vor allen an<strong>de</strong>ren Operatorenaußer <strong>de</strong>n drei weiteren <strong>in</strong> <strong>de</strong>rselben Zeile. Am schwächstenb<strong>in</strong><strong>de</strong>t <strong>de</strong>r Komma-Operator.Neben ihrem Rang haben Operatoren e<strong>in</strong>e Assoziativitäto<strong>de</strong>r Leserichtung (associativity). Die Auswertung e<strong>in</strong>es Ausdruckswie:a + b + cist durch Vorrang nicht e<strong>in</strong><strong>de</strong>utig zu klären, da die bei<strong>de</strong>n Pluszeichen<strong>de</strong>nselben Rang haben. Dieser Fall tritt immer auf, wennauf bei<strong>de</strong>n Seiten e<strong>in</strong>es Operan<strong>de</strong>n Operatoren <strong>de</strong>sselben Rangesstehen. Durch <strong>de</strong>n Compiler – nicht durch die Syntax <strong>de</strong>rSprache, die lässt die Frage offen – ist nun festgelegt, dass diearithmetischen Operatoren l<strong>in</strong>ks-assoziativ s<strong>in</strong>d. Der Operand<strong>in</strong> <strong>de</strong>r Mitte wird vom l<strong>in</strong>ken Operator geschnappt, so dass dieSumme wie folgt ausgewertet wird:(a + b) + cMan könnte auch sagen, dass <strong>de</strong>r Ausdruck von l<strong>in</strong>ks nach rechtsgelesen wird. E<strong>in</strong>e Zuweisung dagegen ist von rechts nach l<strong>in</strong>kszu lesen, sie ist rechts-assoziativ. Zuerst wird die rechte Seite <strong>de</strong>rZuweisung ausgewertet und dann das Ergebnis <strong>de</strong>r l<strong>in</strong>ken Seitezugewiesen. Im Beispiel:a = b = cwird <strong>de</strong>r Wert c <strong>de</strong>r Variablen b zugewiesen und dann das Ergebnisdieser Zuweisung (<strong>de</strong>r Wert b) <strong>de</strong>r Variablen a. Die Reihenfolgee<strong>in</strong>er Auswertung wird also zuerst durch <strong>de</strong>n Rang und danndurch die Assoziativität <strong>de</strong>r Operatoren bestimmt. Im Anhang<strong>in</strong> Abschnitt D.2 Operatoren auf Seite 320 s<strong>in</strong>d alle Operatorenvon C/<strong>C++</strong> mit Rang und Assoziativität aufgelistet.Bei Funktionsaufrufen ist ungewiss, <strong>in</strong> welcher Reihenfolgeetwaige Argumente ausgewertet wer<strong>de</strong>n. Im Beispiel:


122 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong><strong>in</strong>t n = 5;pr<strong>in</strong>tf("%d %d\n", ++n, n * n);ist unsicher, ob n erst <strong>in</strong>krementiert und dann quadriert wirdo<strong>de</strong>r umgekehrt. Das Ergebnis ist entwe<strong>de</strong>r 6, 25 o<strong>de</strong>r 6, 36. DieArgumente von pr<strong>in</strong>tf() arbeitet <strong>de</strong>r e<strong>in</strong>e Compiler von rechtsab, <strong>de</strong>r an<strong>de</strong>re von l<strong>in</strong>ks. Nur durch e<strong>in</strong>e e<strong>in</strong><strong>de</strong>utige Schreibweise:<strong>in</strong>t n = 5;++n;pr<strong>in</strong>tf{"%d %d\n", n, n * n);lässt sich e<strong>in</strong> e<strong>in</strong><strong>de</strong>utiges Ergebnis erreichen – hier 6, 36.In <strong>de</strong>r Mathematik gibt es nur e<strong>in</strong>e Leserichtung, nämlichvon l<strong>in</strong>ks nach rechts. Über die Reihenfolge <strong>de</strong>r Rechenschrittebesagt die Leserichtung nichts. Die obige mehrfache Zuweisungwäre als Gleichung unzulässig, bei <strong>de</strong>r Addition spielt die Reihenfolgeke<strong>in</strong>e Rolle für das Ergebnis.Mißachtung von Rang und Assoziativität führt zu schwierigaufzu<strong>de</strong>cken<strong>de</strong>n logischen Fehlern im Programm. Syntaktischist das Programm richtig, es tut nur etwas an<strong>de</strong>res, als sich<strong>de</strong>r Programmierer vorgestellt hat. Deshalb ist dr<strong>in</strong>gend anzuraten,die Reihenfolge e<strong>in</strong>er Auswertung durch Klammern o<strong>de</strong>rE<strong>in</strong>zelanweisungen zw<strong>in</strong>gend vorzuschreiben und Ausdrücke zuvermei<strong>de</strong>n, <strong>de</strong>ren Wert von Vermutungen über die Reihenfolge<strong>de</strong>r Auswertung abhängt.1.3.8 Anweisungen1.3.8.1 Leere AnweisungAnweisungen (statement) haben e<strong>in</strong>e Wirkung, aber ke<strong>in</strong>enWert, im Gegensatz zu Ausdrücken. Die e<strong>in</strong>fachste Anweisungist die leere Anweisung, also die Auffor<strong>de</strong>rung an <strong>de</strong>n Computer,nichts zu tun. Das sieht zwar auf <strong>de</strong>n ersten Blickschwachs<strong>in</strong>nig aus, ist aber gelegentlich nützlich. Da <strong>in</strong> C je<strong>de</strong>Anweisung mit e<strong>in</strong>em Semikolon abgeschlossen wer<strong>de</strong>n muss,ist das nackte Semikolon die leere Anweisung. In an<strong>de</strong>ren Sprachenf<strong>in</strong><strong>de</strong>t sich dafür die Anweisung nop o<strong>de</strong>r noop (no operation).E<strong>in</strong> Beispiel:


1.3. BAUSTEINE EINES QUELLTEXTES 123while ((c = getchar()) != 125);Die Schleife liest Zeichen e<strong>in</strong> und verwirft sie, bis sie auf e<strong>in</strong>Zeichen Nr. 125 (rechte geschweifte Klammer) trifft. Das wirdauch noch entsorgt, dann geht es nach <strong>de</strong>r Schleife weiter.1.3.8.2 Zuweisung als AnweisungAus e<strong>in</strong>er Zuweisung wird durch Anhängen e<strong>in</strong>es Semikolonse<strong>in</strong>e Anweisung. Kommt e<strong>in</strong>e Zuweisung beispielsweise als Argumente<strong>in</strong>er Funktion o<strong>de</strong>r <strong>in</strong> e<strong>in</strong>er Bed<strong>in</strong>gung vor, darf sienicht durch e<strong>in</strong> eigenes Semikolon abgeschlossen wer<strong>de</strong>n. DieZuweisung wird ausgeführt und ihr Wert an ihre Stelle gesetzt.Steht die Zuweisung alle<strong>in</strong>, muss sie mit e<strong>in</strong>em Semikolon been<strong>de</strong>twer<strong>de</strong>n und wird damit zu e<strong>in</strong>er Anweisung an <strong>de</strong>n Computer,etwas zu tun:pr<strong>in</strong>tf("%d %f \n", x = 3, log(4));x = 5;y = log(4);Ähnlich wie die Return-Taste <strong>in</strong> <strong>de</strong>r Kommandozeile bewirkthier erst das Semikolon, dass etwas geschieht.1.3.8.3 KontrollanweisungenKontrollanweisungen steuern <strong>in</strong> Abhängigkeit von <strong>de</strong>m Werte<strong>in</strong>es booleschen Ausdrucks (Bed<strong>in</strong>gung) die Abarbeitung vonProgrammteilen (e<strong>in</strong>zelnen Anweisungen o<strong>de</strong>r Blöcken), weshalbdie E<strong>in</strong>richtung auch Ablaufkontrolle genannt wird. DieKontrollanweisungen von C wie von vielen an<strong>de</strong>ren Sprachens<strong>in</strong>d die Bed<strong>in</strong>gung, die Verzweigung, die Auswahl, die Schleifeund <strong>de</strong>r Sprung.Sequenz Die e<strong>in</strong>fachste Kontrollanweisung ist ke<strong>in</strong>e, die Anweisungenim Programm wer<strong>de</strong>n <strong>de</strong>r Reihe nach abgearbeitet.Diese Ablaufform heißt Sequenz o<strong>de</strong>r Folge und wird <strong>de</strong>r Vollständigkeithalber erwähnt.


124 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Bed<strong>in</strong>gung Die Ausführung e<strong>in</strong>es Blocks kann von e<strong>in</strong>er Bed<strong>in</strong>gung(condition) abhängig gemacht wer<strong>de</strong>n. Die Bed<strong>in</strong>gungist e<strong>in</strong> Ausdruck, <strong>de</strong>r nur die Werte true o<strong>de</strong>r false annimmt.Ist die Bed<strong>in</strong>gung true, wird <strong>de</strong>r Block abgearbeitet und dannim Programm fortgefahren. Ist die Bed<strong>in</strong>gung false, wird <strong>de</strong>rBlock übersprungen. Kann die Bed<strong>in</strong>gung niemals true wer<strong>de</strong>n,hat man toten (unerreichbaren) Co<strong>de</strong> geschrieben. Ist die Bed<strong>in</strong>gungimmer true, sollte man auf sie verzichten.In C wird die Bed<strong>in</strong>gung mit <strong>de</strong>m Schlüsselwort if e<strong>in</strong>geleitet,ohne then (im Unterschied zu e<strong>in</strong>em Shellscript). Besteht<strong>de</strong>r Block nur aus e<strong>in</strong>er e<strong>in</strong>zigen Anweisung, kann auf die geschweiftenKlammern verzichtet wer<strong>de</strong>n:if (Ausdruck) e<strong>in</strong>zelne_Anweisung; /* o<strong>de</strong>r */if (Ausdruck) {Block von Anweisungen}Verzweigung (C) Bei e<strong>in</strong>er Verzweigung (branch) entschei<strong>de</strong>tsich <strong>de</strong>r Computer, <strong>in</strong> Abhängigkeit von e<strong>in</strong>er Bed<strong>in</strong>gung <strong>in</strong>e<strong>in</strong>em von zwei Programmzweigen weiterzumachen. Im Gegensatzzur Schleife kommt ke<strong>in</strong> Rücksprung vor. Verzweigungendürfen geschachtelt wer<strong>de</strong>n. Dem Computer macht das nichtsaus, aber vielleicht verlieren Sie die Übersicht.Oft, aber nicht notwendigerweise treffen die bei<strong>de</strong>n Zweigeim weiteren Verlauf wie<strong>de</strong>r zusammen. Die Syntax sieht folgen<strong>de</strong>rmaßenaus:if (Ausdruck) {Block 1}else {Block 2}Es wird also stets entwe<strong>de</strong>r Block 1 o<strong>de</strong>r Block 2 ausgeführt.Auswahl Stehen am Verzweigungspunkt mehr als zwei Wegeoffen, so spricht man von e<strong>in</strong>er Auswahl (selection). Sie lässtsich grundsätzlich durch e<strong>in</strong>e Schachtelung e<strong>in</strong>facher Verzweigungenmit if - else darstellen, das ist jedoch unübersichtlich.Zur Konstruktion e<strong>in</strong>er Auswahl braucht man die Schlüsselwörterswitch, case, break und <strong>de</strong>fault. Die Syntax ist diefolgen<strong>de</strong>:


1.3. BAUSTEINE EINES QUELLTEXTES 125switch(x) {case a:}case b:case c:Anweisungsfolge 1break;Anweisungsfolge 2break;<strong>de</strong>fault:Anweisungsfolge 3Die Variable x (nur vom Typ <strong>in</strong>t o<strong>de</strong>r char) wird auf Übere<strong>in</strong>stimmungmit <strong>de</strong>r typgleichen Konstanten a geprüft. Falls ja,wird die Anweisungsfolge 1 ausgeführt und <strong>in</strong>folge <strong>de</strong>r break-Anweisung die Auswahl verlassen. Stimmt x nicht mit a übere<strong>in</strong>o<strong>de</strong>r fehlt nach case a das break, wird dann x auf Übere<strong>in</strong>stimmungmit b o<strong>de</strong>r c geprüft. Trifft ke<strong>in</strong> case zu, wird die<strong>de</strong>fault-Anweisungsfolge ausgeführt. Fehlt diese, macht dasProgramm nach <strong>de</strong>r Auswahl weiter, ohne e<strong>in</strong>e <strong>de</strong>r Anweisungenausgeführt zu haben. Wenn ke<strong>in</strong>e an<strong>de</strong>ren Grün<strong>de</strong> dagegensprechen, stellt man <strong>de</strong>n häufigsten Fall an <strong>de</strong>n Anfang.Die Auswahl ist übersichtlich, e<strong>in</strong>fach zu erweitern und effektiv.Wenn aus e<strong>in</strong>er e<strong>in</strong>fachen Verzweigung e<strong>in</strong>e Auswahl wer<strong>de</strong>nkönnte, soll man gleich zu dieser greifen. Auswahlen dürfen geschachteltwer<strong>de</strong>n.Mit etwas Phantasie kann man sich die Bed<strong>in</strong>gung als e<strong>in</strong>eAuswahl mit nur e<strong>in</strong>er Wahlmöglichkeit vorstellen, die Verzweigungals e<strong>in</strong>e Auswahl mit zwei Wahlmöglichkeiten. Insofernlassen sich diese drei Kontrollstrukturen zusammenfassen,wobei die switch-Auswahl <strong>de</strong>n allgeme<strong>in</strong>en Fall darstellt.Schleifen E<strong>in</strong>em Computer macht es nichts aus, <strong>de</strong>nselbenVorgang millionenmal zu wie<strong>de</strong>rholen. Das ist se<strong>in</strong>e Stärke. Wie<strong>de</strong>rholungenvon Anweisungen kommen daher <strong>in</strong> fast allen Programmenvor, sie wer<strong>de</strong>n Schleifen (loop) genannt.E<strong>in</strong>e Schleife hat e<strong>in</strong>en E<strong>in</strong>gang, sonst käme man nicht h<strong>in</strong>e<strong>in</strong>.Die meisten Schleifen haben auch e<strong>in</strong>en Ausgang, sonstkäme man nicht wie<strong>de</strong>r heraus (außer mit <strong>de</strong>m Brecheisen <strong>in</strong>Form <strong>de</strong>r Break-Taste o<strong>de</strong>r Ähnlichem).


126 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Entwe<strong>de</strong>r E<strong>in</strong>- o<strong>de</strong>r Ausgang s<strong>in</strong>d an e<strong>in</strong>e Bed<strong>in</strong>gung geknüpft,die entschei<strong>de</strong>t, wie oft die Schleife durchlaufen wird.Folgen<strong>de</strong> Konstruktionen s<strong>in</strong>d möglich:• E<strong>in</strong>gang: E<strong>in</strong>trittsbed<strong>in</strong>gung• Schleifenrumpf (Anweisungen)• Ausgang: Rücksprung zum E<strong>in</strong>gangDiese Schleife wird nur betreten, falls die E<strong>in</strong>trittsbed<strong>in</strong>gung erfülltist, unter Umstän<strong>de</strong>n also nie. Sie wird <strong>de</strong>shalb abweisen<strong>de</strong>Schleife genannt, auch kopfgesteuerte Schleife. Wenn dieE<strong>in</strong>trittsbed<strong>in</strong>gung nicht mehr erfüllt ist, macht das Programmnach <strong>de</strong>r Schleife weiter. In C sieht diese Schleife so aus:while (Bed<strong>in</strong>gung) e<strong>in</strong>zelne_Anweisung; /* o<strong>de</strong>r */while (Bed<strong>in</strong>gung) {Block von Anweisungen}}Die zweite Möglichkeit lässt sich grundsätzlich auf die erste zurückführen,wird aber trotz<strong>de</strong>m verwen<strong>de</strong>t, weil das Programmdadurch e<strong>in</strong>facher wird:• E<strong>in</strong>gang (wird <strong>in</strong> je<strong>de</strong>m Fall betreten)• Schleifenrumpf (Anweisungen)• Ausgang: Rücksprungbed<strong>in</strong>gungDiese Schleife wird also m<strong>in</strong><strong>de</strong>stens e<strong>in</strong>mal ausgeführt und dannso lange wie<strong>de</strong>rholt, wie die Rücksprungbed<strong>in</strong>gung zutrifft. Sieheißt daher nichtabweisen<strong>de</strong> Schleife, auch fußgesteuerteSchleife. Ist die Rücksprungbed<strong>in</strong>gung nicht mehr erfüllt, machtdas Programm nach <strong>de</strong>r Schleife weiter. In C:do e<strong>in</strong>zelne_Anweisung while (Bed<strong>in</strong>gung); /* o<strong>de</strong>r */do {Block von Anweisungen} while (Bed<strong>in</strong>gung);E<strong>in</strong>e Variante, die e<strong>in</strong>e #<strong>de</strong>f<strong>in</strong>e-Zeile erfor<strong>de</strong>rt, sieht folgen<strong>de</strong>maßenaus:#<strong>de</strong>f<strong>in</strong>e Please...Please do {Block} while (Bed<strong>in</strong>gung);


1.3. BAUSTEINE EINES QUELLTEXTES 127In hartnäckigen Fällen soll diese Schleife <strong>de</strong>r Standard-Schleifeüberlegen se<strong>in</strong>.Re<strong>in</strong> aus Bequemlichkeit gibt es <strong>in</strong> C noch e<strong>in</strong>e dritte Schleifemit for, die aber stets durch e<strong>in</strong>e while-Schleife ersetzt wer<strong>de</strong>nkann. Sie sieht so aus:for (Initialisierung; Bed<strong>in</strong>gung; Inkrementierung) {Block von Anweisungen;}Vor E<strong>in</strong>tritt <strong>in</strong> die Schleife wird <strong>de</strong>r Ausdruck<strong>in</strong>itialisierung ausgewertet (also immer), dann wird <strong>de</strong>rAusdruck bed<strong>in</strong>gung geprüft und falls ungleich 0 <strong>de</strong>r Schleifenrumpfbetreten. Zuletzt wird <strong>de</strong>r Ausdruck <strong>in</strong>krementierungausgewertet und zur Bed<strong>in</strong>gung zurückgesprungen. Die for-Schleife <strong>in</strong> C hat also e<strong>in</strong>e an<strong>de</strong>re Be<strong>de</strong>utung als die for-Schleife<strong>de</strong>r Shell o<strong>de</strong>r <strong>de</strong>r Programmiersprache PASCAL. Je<strong>de</strong>r <strong>de</strong>r dreiAusdrücke darf fehlen:for (;;);ist die ewige und zugleich leere Schleife. Die Initialisierungund die Inkrementierung dürfen mehrere, durch <strong>de</strong>n Komma-Operator getrennte Ausdrücke enthalten, die Bed<strong>in</strong>gung musse<strong>in</strong>en Wert gleich o<strong>de</strong>r ungleich 0 ergeben. Zwei Beispiele:/* Beispiel fuer for-Schleife, 04.03.1993 */#<strong>de</strong>f<strong>in</strong>e MAX 10#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t i;for (i = 0; i < MAX; i++)pr<strong>in</strong>tf("Der Schleifenzaehler spricht: %d\n", i);return 0;}Quelle 1.28 : C-Programm mit e<strong>in</strong>facher for-SchleifeDer Schleifenzähler i wird mit 0 <strong>in</strong>itialisiert. Für MAX ist bereitsvom Compiler die Zahl 10 e<strong>in</strong>gesetzt wor<strong>de</strong>n; die E<strong>in</strong>trittsbed<strong>in</strong>gungi < 10 ist anfangs erfüllt, <strong>de</strong>r Schleifenrumpf wird


128 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>ausgeführt. Dann wird <strong>de</strong>r dritte Teil <strong>de</strong>r for-Zeile ausgeführt,nämlich <strong>de</strong>r Schleifenzähler i um 1 erhöht, und zur Bed<strong>in</strong>gungi < 10 zurückgesprungen. Das wie<strong>de</strong>rholt sich, bis i <strong>de</strong>n Wert10 erreicht hat. Die Bed<strong>in</strong>gung ist dann nicht mehr erfüllt, dieAusführung <strong>de</strong>s Programms geht nach <strong>de</strong>r Schleife weiter. Nun<strong>de</strong>r syntaktisch e<strong>in</strong>wandfreie Mißbrauch e<strong>in</strong>er for-Schleife:/* Testen <strong>de</strong>r for-Schleife, 04.03.1993 */#<strong>de</strong>f<strong>in</strong>e MAX 10#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t sum(<strong>in</strong>t x);<strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t i, j = 1;for (i = - 3, puts("Anfang"); i < j * MAX; i++, i = sum(i)){pr<strong>in</strong>tf("Der Schleifenzaehler spricht: %d %d\n", i, j);j = (i < 0 ? -i : 3);}return i;}/* Funktion sum(x) */<strong>in</strong>t sum(<strong>in</strong>t x){if (x < 5) return (x + 1);else return (x + 2);}Quelle 1.29 : C-Programm mit zusammengesetzter for-SchleifeIm Initialisierungsteil wird <strong>de</strong>r Schleifenzähler i mit −3 belegtund – getrennt durch <strong>de</strong>n Komma-Operator – mittels <strong>de</strong>rStandard-Funktion puts(3) e<strong>in</strong> Str<strong>in</strong>g ausgegeben. In <strong>de</strong>r E<strong>in</strong>trittsbed<strong>in</strong>gungwird gerechnet; wichtig ist nur, dass schließliche<strong>in</strong> Wert 0 o<strong>de</strong>r nicht-0 herauskommt. Dann wird gegebenenfalls<strong>de</strong>r Schleifenrumpf ausgeführt, wobei im Rumpf auf die Variableni und j <strong>de</strong>s Schleifenkopfes zugegriffen wird. Abschließendwird <strong>de</strong>r Schleifenzähler i <strong>in</strong>krementiert und – wie<strong>de</strong>r durch <strong>de</strong>n


1.3. BAUSTEINE EINES QUELLTEXTES 129Komma-Operator getrennt – nochmals mit Hilfe e<strong>in</strong>er Funktionsum(x) verän<strong>de</strong>rt. Wenn die Schleife nach e<strong>in</strong>igen Durchläufenverlassen wird, steht <strong>de</strong>r Schleifenzähler i weiterh<strong>in</strong> zur Verfügung.In <strong>de</strong>m Kopf <strong>de</strong>r for-Schleife lässt sich allerhand unterbr<strong>in</strong>gen,auch Anweisungen, die mit <strong>de</strong>r Schleife nichts zu tunhaben. Das wäre schlechter Stil.Ist die E<strong>in</strong>tritts- o<strong>de</strong>r Rücksprungbed<strong>in</strong>gung immer erfüllt,bleibt <strong>de</strong>r Computer <strong>in</strong> <strong>de</strong>r Schleife gefangen, man hat e<strong>in</strong>e ewigeSchleife programmiert. Das kann gewollt se<strong>in</strong>, ist aber oft e<strong>in</strong>Programmierfehler.Schleifen mit <strong>de</strong>r Bed<strong>in</strong>gung mitten im Schleifenrumpf s<strong>in</strong>d<strong>de</strong>nkbar und kommen vor, jedoch selten. Mehrere Ausgänge s<strong>in</strong><strong>de</strong>rlaubt, verr<strong>in</strong>gern aber die Übersicht und s<strong>in</strong>d sparsam zu verwen<strong>de</strong>n.Bei <strong>de</strong>r Behandlung von Ausnahmen (Division durchNull) braucht man sie manchmal. Das H<strong>in</strong>e<strong>in</strong>spr<strong>in</strong>gen mitten <strong>in</strong><strong>de</strong>n Schleifenrumpf ist möglich, gilt aber als schwerer Stilfehler.Die Anweisung break im Rumpf führt zum sofortigen un<strong>de</strong>ndgültigen Verlassen e<strong>in</strong>er Schleife. Die Anweisung cont<strong>in</strong>uebricht <strong>de</strong>n augenblicklichen Durchlauf ab und spr<strong>in</strong>gt zurück vordie Schleife, bei <strong>de</strong>r for-Schleife vor die Initialisierung. Der Systemaufrufexit(2) veranlasst <strong>de</strong>n sofortigen Abbruch <strong>de</strong>s ganzenProgrammes, ist also für unheilbare Ausnahmezustän<strong>de</strong> zugebrauchen (Notschlachtung).In vielen Schleifen zählt man die Anzahl <strong>de</strong>r Durchläufe (undverzählt sich dabei oft um e<strong>in</strong>s 30 ). Die zugehörige Variable ist <strong>de</strong>rSchleifenzähler. Auf se<strong>in</strong>e Initialisierung ist zu achten. DerSchleifenzähler steht <strong>in</strong> und nach <strong>de</strong>r Schleife für Rechnungenzur Verfügung, an<strong>de</strong>rs als <strong>in</strong> FORTRAN.Schleifen dürfen geschachtelt wer<strong>de</strong>n. Mit mehrfach geschachteltenSchleifen geht <strong>de</strong>r Spaß erst richtig los. Der Rumpf<strong>de</strong>r <strong>in</strong>nersten Schleife wird am häufigsten durchlaufen und hatdaher auf das Zeitverhalten <strong>de</strong>s Programmes e<strong>in</strong>en großen E<strong>in</strong>fluss.Dort sollte man nur die allernötigsten Anweisungen h<strong>in</strong>e<strong>in</strong>schreiben.Auch die Bed<strong>in</strong>gung <strong>de</strong>r <strong>in</strong>nersten Schleife sollteso e<strong>in</strong>fach und knapp wie möglich gefasst se<strong>in</strong>.30 Sogenannter Zaunpfahl-Fehler (fencepost error): Wenn Siebei e<strong>in</strong>em Zaun von 100 m Länge alle 10 m e<strong>in</strong>en Pfahl setzen,wieviele Pfähle brauchen Sie? 9? 10? 11?


130 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Sprung Es gibt die Anweisung goto, gefolgt von e<strong>in</strong>em Label(Marke). In seltenen Fällen kann e<strong>in</strong> goto das Programm verbesern,meist ist es vom Übel, weil es erstens sehr gefährlich,zweitens auch nicht nötig ist 31 .Hier e<strong>in</strong> grauenvolles Beispiel für <strong>de</strong>n Mißbrauch von goto.Das Programm ist syntaktisch richtig und tut auch das, was essoll, nämlich die e<strong>in</strong>gegebene Zahl ausgeben, falls sie durch 5teilbar ist, an<strong>de</strong>rnfalls die nächstgrößere durch 5 teilbare Zahle<strong>in</strong>schließlich <strong>de</strong>r Zwischenergebnisse. Das Programm enthälte<strong>in</strong>e schwere programmiertechnische Sün<strong>de</strong>, <strong>de</strong>n Sprung mitten<strong>in</strong> e<strong>in</strong>en Schleifenrumpf:/* Grauenvolles Beispiel fuer goto, 06.07.1992 *//* Am besten gar nicht compilieren */#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t x;pr<strong>in</strong>tf("Bitte Zahl e<strong>in</strong>geben: ");scanf("%d", &x);if (!(x % 5))goto marke;else {while (x % 5) {x++;marke:pr<strong>in</strong>tf("Ausgabe: %d\n", x);}}return 0;}Quelle 1.30 : C-Programm mit goto, grauenvollNun aber ganz schnell e<strong>in</strong>e stilistisch e<strong>in</strong>wandfreie Fassung<strong>de</strong>s Programms:/* Verbessertes Beispiel, 06.07.1992 */31 Real programmers aren’t afraid to use goto’s.


1.3. BAUSTEINE EINES QUELLTEXTES 131#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t x;pr<strong>in</strong>tf("Bitte Zahl e<strong>in</strong>geben: ");scanf("%d", &x);do {pr<strong>in</strong>tf("%d\n", x);} while (x++ % 5);return 0;}Quelle 1.31 : C-Programm, verbessertAm goto hatte sich um 1970 herum e<strong>in</strong> Glaubenskrieg entzün<strong>de</strong>t.In C-Programmen besteht äußerst selten die Notwendigkeitfür diese Anweisung, aber gebräuchliche Anweisungenwie break, cont<strong>in</strong>ue und return s<strong>in</strong>d bei Licht besehen auchnur gotos, die auf bestimmte Fälle beschränkt s<strong>in</strong>d. Immerh<strong>in</strong>verh<strong>in</strong><strong>de</strong>rn die Beschränkungen e<strong>in</strong> hemmungsloses H<strong>in</strong>undherhüpfenim Programm.1.3.8.4 RückgabewertE<strong>in</strong>e Funktion braucht ke<strong>in</strong>en Wert an die aufrufen<strong>de</strong> E<strong>in</strong>heitzurückzugeben. Sie ist dann vom Typ void. Ihre Be<strong>de</strong>utung liegtalle<strong>in</strong> <strong>in</strong> <strong>de</strong>m, was sie tut, zum Beispiel <strong>de</strong>n Bildschirm putzen.In diesem Fall en<strong>de</strong>t sie ohne return-Anweisung (schlechterStil) o<strong>de</strong>r mit e<strong>in</strong>er return-Anweisung ohne Argument. Wassie tut, wird Nebenwirkung o<strong>de</strong>r Seiteneffekt (si<strong>de</strong> effect) genannt.In FORTRAN wäre das e<strong>in</strong>e Subrout<strong>in</strong>e, <strong>in</strong> PASCAL e<strong>in</strong>eeigentliche Prozedur.Gibt man <strong>de</strong>r return-Anweisung e<strong>in</strong>en Wert mit, so kann dieFunktion von <strong>de</strong>r aufrufen<strong>de</strong>n E<strong>in</strong>heit wie e<strong>in</strong> Ausdruck angesehenwer<strong>de</strong>n. Der Rückgabewert (return value) darf nur e<strong>in</strong>e<strong>in</strong>facher Datentyp o<strong>de</strong>r e<strong>in</strong> Po<strong>in</strong>ter se<strong>in</strong>. Will man e<strong>in</strong>en Str<strong>in</strong>gzurückgeben, geht das nur über <strong>de</strong>n Po<strong>in</strong>ter auf <strong>de</strong>n Anfang <strong>de</strong>sStr<strong>in</strong>gs. Der zurückzugeben<strong>de</strong> Wert braucht nicht e<strong>in</strong>geklam-


132 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>mert zu wer<strong>de</strong>n; bei zusammengesetzten Ausdrücken sollte man<strong>de</strong>r Lesbarkeit halber Klammern setzen:return 0;return (x + y);return arrayname;Besteht das Ergebnis aus mehreren Werten, so muss man mitglobalen Variablen o<strong>de</strong>r mit Po<strong>in</strong>tern arbeiten. Der Rückgabewertkann immer nur e<strong>in</strong> e<strong>in</strong>ziger Wert se<strong>in</strong>.Es kommt vor, dass e<strong>in</strong>e Funktion zwar e<strong>in</strong>en Wert zurückgibt,dieser aber nicht weiter verwen<strong>de</strong>t wird. In diesem Fallwarnt l<strong>in</strong>t(1), aber das Programm ist korrekt. Häufig beipr<strong>in</strong>tf(3) und Verwandtschaft. Den Rückgabewert <strong>de</strong>r Funktionma<strong>in</strong>() f<strong>in</strong><strong>de</strong>t man <strong>in</strong> <strong>de</strong>r Shell-Variablen $? o<strong>de</strong>r $status.Er kann <strong>in</strong> e<strong>in</strong>em Shellscript weiterverarbeitet wer<strong>de</strong>n. Hier e<strong>in</strong>Beispiel für <strong>de</strong>n Gebrauch <strong>de</strong>r return-Anweisung:/* Beispiel fuer return-Anweisungen, 21.02.91 */#<strong>de</strong>f<strong>in</strong>e PI 3.14159#<strong>in</strong>clu<strong>de</strong> /* Funktions<strong>de</strong>klarationen (Prototypen) */void text(); <strong>in</strong>t e<strong>in</strong>gabe(); double area(float rad);char *maxi();/* Hauptprogramm */<strong>in</strong>t ma<strong>in</strong>(){float r; char w1[63], w2[63];text();if (!e<strong>in</strong>gabe())puts("E<strong>in</strong>gabe war richtig.");elseputs("E<strong>in</strong>gabe war falsch.");pr<strong>in</strong>tf("Radius e<strong>in</strong>geben: ");scanf("%f", &r);pr<strong>in</strong>tf("Kreisflaeche: %lf\n", area(r));


1.3. BAUSTEINE EINES QUELLTEXTES 133pr<strong>in</strong>tf("Bitte zwei Woerter e<strong>in</strong>geben: ");scanf("%s %s", w1, w2);pr<strong>in</strong>tf("Das laengere Wort ist: %s\n", maxi(w1, w2));return 0;}/* Funktion ohne Returnwert, Typ void */void text(){puts("\nDiese Funktion gibt nichts zurueck.");return;}/* Funktion mit richtig/falsch-Returnwert, Typ <strong>in</strong>t */<strong>in</strong>t e<strong>in</strong>gabe(){<strong>in</strong>t i;pr<strong>in</strong>tf("Bitte die Zahl 37 e<strong>in</strong>geben: ");scanf("%d", &i);if (i == 37) return 0;else return -1;}/* Funktion, die e<strong>in</strong> Rechenergebnis liefert, Typ double */double area(float rad){return (rad * rad * PI);}/* Funktion, die e<strong>in</strong>en Po<strong>in</strong>ter zurueckgibt, Typ (char *) *char *maxi(char *w1,char *w2){<strong>in</strong>t i, j;for (i = 0; w1[i] != ’\0’; i++) ;for (j = 0; w2[j] != ’\0’; j++) ;return((j > i) ? w2 : w1);}Quelle 1.32 : C-Programm mit return-AnweisungenIm Hauptprogramm ma<strong>in</strong>() haben return(n); und


134 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>exit(n); dieselbe Wirkung. In an<strong>de</strong>ren Funktionen führtreturn zur Rückkehr <strong>in</strong> die nächsthöhere E<strong>in</strong>heit, exit zumAbbruch <strong>de</strong>s gesamten Programmes. In <strong>de</strong>r Syntax unterschei<strong>de</strong>nsich bei<strong>de</strong> Aufrufe: return ist e<strong>in</strong> Schlüsselwort von C,exit() e<strong>in</strong> Systemaufruf von UNIX, also e<strong>in</strong>e Funktion. Weiterh<strong>in</strong>s<strong>in</strong>d exit und return auch e<strong>in</strong>gebaute Shell-Kommandos –siehe sh(1) o<strong>de</strong>r ksh(1) – die aber nicht <strong>in</strong> C-Programmen vorkommenkönnen.1.3.9 Memo Bauste<strong>in</strong>e• Kommentar ist für <strong>de</strong>n menschlichen Leser bestimmt, <strong>de</strong>rCompiler übergeht ihn o<strong>de</strong>r bekommt ihn gar nicht erst zuGesicht.• Namen bezeichnen Funktionen, Konstanten, Variable allerArt, Makros o<strong>de</strong>r Sprungmarken (Labels). Sie sollen mite<strong>in</strong>em Buchstaben beg<strong>in</strong>nen.• Operan<strong>de</strong>n haben Namen, Typ, Geltungsbereich, Lebensdauerund spätestens bei ihrer erstmaligen Benutzunge<strong>in</strong>en Wert und belegen damit e<strong>in</strong>en Platz und e<strong>in</strong>e Adresseim Speicher.• E<strong>in</strong>e Vere<strong>in</strong>barung besteht aus Deklaration und Def<strong>in</strong>ition.Die Deklaration weist e<strong>in</strong>em Operan<strong>de</strong>n Name und Typzu und legt se<strong>in</strong>en Geltungsbereich und se<strong>in</strong>e Lebensdauerfest. Mit <strong>de</strong>r Def<strong>in</strong>ition erhält e<strong>in</strong> Operand e<strong>in</strong>en Wert.Bei<strong>de</strong>s kann <strong>in</strong> e<strong>in</strong>er Anweisung vere<strong>in</strong>igt wer<strong>de</strong>n.• Der Typ entschei<strong>de</strong>t über Wertebereich, Operationen undSpeicherbedarf. Der Typ e<strong>in</strong>es Operan<strong>de</strong>n ist <strong>in</strong> C konstant,er än<strong>de</strong>rt sich während <strong>de</strong>r Programmausführung nicht.• Es gibt e<strong>in</strong>fache und zusammengesetzte Typen sowie Po<strong>in</strong>ter.• E<strong>in</strong>fache Typen s<strong>in</strong>d Ganzzahlen, Gleitkommazahlen undZeichen. Der Aufzählungstyp ist letzten En<strong>de</strong>s ganzzahlig.Daneben gibt es für bestimmte Fälle <strong>de</strong>n leeren Typ.• Zusammengesetzte Typen s<strong>in</strong>d Arrays und Strukturen.• E<strong>in</strong> Array ist e<strong>in</strong>e geordnete Menge von Operan<strong>de</strong>n gleichenTyps.


1.3. BAUSTEINE EINES QUELLTEXTES 135• E<strong>in</strong>e Struktur ist e<strong>in</strong>e ungeordnete Menge von Operan<strong>de</strong>nbeliebigen Typs.• Der Po<strong>in</strong>ter ist e<strong>in</strong> Typ, <strong>de</strong>ssen Wertebereich Adressen s<strong>in</strong>d.E<strong>in</strong> Po<strong>in</strong>ter zeigt immer auf e<strong>in</strong>en Typ, unter Umstän<strong>de</strong>nauf e<strong>in</strong>en weiteren Po<strong>in</strong>ter.• E<strong>in</strong> Ausdruck besteht aus Operan<strong>de</strong>n und Operationen. Erhat e<strong>in</strong>en Wert und kann überall dort stehen, wo e<strong>in</strong> Wertverlangt wird.• Die e<strong>in</strong>fachste Operation ist die Zuweisung, nicht zu verwechselnmit e<strong>in</strong>er mathematischen Gleichung. Sie hat e<strong>in</strong>el<strong>in</strong>ke und e<strong>in</strong>e rechte Seite. Rechts steht immer e<strong>in</strong>Wert, also gegebenenfalls e<strong>in</strong> Ausdruck. L<strong>in</strong>ks steht e<strong>in</strong>eVariable o<strong>de</strong>r e<strong>in</strong> Po<strong>in</strong>ter, aber niemals e<strong>in</strong> Ausdruck.• Weiterh<strong>in</strong> gibt es arithmetische, logische, vergleichen<strong>de</strong>Operationen sowie O. auf Bits, Strukturen o<strong>de</strong>r Po<strong>in</strong>ter.Dann haben wir noch <strong>de</strong>n Cast-, Komma- und Sizeof-Operator.• Anweisungen en<strong>de</strong>n immer mit e<strong>in</strong>em Semikolon.• Aus e<strong>in</strong>er Zuweisung wird durch Anfügen e<strong>in</strong>es Semikolonse<strong>in</strong>e Anweisung.• Die Kontrollanweisungen Bed<strong>in</strong>gung (if), Verzweigung (ifelse),Auswahl (switch), Schleife (while, do-while, for) undSprung (break, cont<strong>in</strong>ue, return, goto) steuern <strong>de</strong>n Programmablauf.1.3.10 Übung Bauste<strong>in</strong>eÜberlegen Sie, welche Operan<strong>de</strong>n mit welchen Typen Sie fürdas Beispiel <strong>de</strong>r Weganalyse (o<strong>de</strong>r <strong>de</strong>s Vokabeltra<strong>in</strong>ers) aus <strong>de</strong>mvorigen Abschnitt brauchen. E<strong>in</strong>e gute Datenstruktur ist schonfast das halbe Programm. Um e<strong>in</strong> richtiges Programm schreibenzu können, fehlt uns noch <strong>de</strong>r nächste Abschnitt.


136 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.4 Funktionen1.4.1 Aufbau und DeklarationIn C ist e<strong>in</strong>e Funktion e<strong>in</strong>e abgeschlossene Programme<strong>in</strong>heit,die mit <strong>de</strong>r Außenwelt über e<strong>in</strong>en E<strong>in</strong>gang und wenige Ausgänge– gegebenenfalls noch Notausgänge – verbun<strong>de</strong>n ist. Hauptprogramm,Unterprogramme, Subrout<strong>in</strong>en, Prozeduren usw. s<strong>in</strong>d <strong>in</strong>C allesamt Funktionen. E<strong>in</strong>e Funktion ist die kle<strong>in</strong>ste kompilierbareE<strong>in</strong>heit (nicht: ausführbare E<strong>in</strong>heit, das ist e<strong>in</strong> Programm),nämlich dann, wenn sie zugleich alle<strong>in</strong> <strong>in</strong> e<strong>in</strong>er Datei steht. Mitweniger als e<strong>in</strong>er Funktion kann <strong>de</strong>r Compiler nichts anfangen.Da die Def<strong>in</strong>itionen von Funktionen nicht geschachteltwer<strong>de</strong>n dürfen (wohl aber ihre Aufrufe), gelten Funktionengrundsätzlich global. In e<strong>in</strong>em C-Programm stehen alle Funktionene<strong>in</strong>schließlich ma<strong>in</strong>() auf gleicher Stufe. Das ist e<strong>in</strong> wesentlicherUnterschied zu PASCAL, wo Funktionen <strong>in</strong>nerhalb vonUnterprogrammen <strong>de</strong>f<strong>in</strong>iert wer<strong>de</strong>n dürfen. In C gibt es zu e<strong>in</strong>erFunktion ke<strong>in</strong>e übergeordnete Funktion, <strong>de</strong>ren Variable <strong>in</strong> <strong>de</strong>runtergeordneten Funktion gültig s<strong>in</strong>d.E<strong>in</strong>e Funktion übernimmt von <strong>de</strong>r aufrufen<strong>de</strong>n Anweisunge<strong>in</strong>en festgelegten Satz von Argumenten o<strong>de</strong>r Parametern, tutetwas und gibt ke<strong>in</strong>en o<strong>de</strong>r genau e<strong>in</strong>en Wert an die aufrufen<strong>de</strong>Anweisung zurück.Vor <strong>de</strong>m ersten Aufruf e<strong>in</strong>er Funktion muß ihr Typ (d. h. <strong>de</strong>rTyp ihres Rückgabewertes) bekannt se<strong>in</strong>. An<strong>de</strong>rnfalls nimmt <strong>de</strong>rCompiler <strong>de</strong>n Standardtyp <strong>in</strong>t an. Entsprechend <strong>de</strong>m ANSI-Vorschlag bürgert es sich zunehmend e<strong>in</strong>, Funktionen durch ausführlichePrototypen vor Beg<strong>in</strong>n <strong>de</strong>r Funktion ma<strong>in</strong>() zu <strong>de</strong>klarieren:/* Beispiel fuer Funktionsprototyp */float multipl(float x, float y); /* Prototyp *//* es reicht auch: float multipl(float, float); *//* frueher nach K+R: float multipl(); */<strong>in</strong>t ma<strong>in</strong>(){float a, b, z;.


1.4. FUNKTIONEN 137.z = multipl(a, b); /* Funktionsaufruf */..}float multipl(float x, float y) /* F’<strong>de</strong>f<strong>in</strong>ition */{return (x * y);}Quelle 1.33 : C-Programm mit FunktionsprototypDurch die Angabe <strong>de</strong>r Typen <strong>de</strong>r Funktion und ihrer Argumentezu Beg<strong>in</strong>n <strong>de</strong>s Programms herrscht sofort Klarheit. DieNamen <strong>de</strong>r Parameter s<strong>in</strong>d unerheblich; Anzahl, Typ und Reihenfolges<strong>in</strong>d wesentlich. Noch nicht alle Compiler unterstützendie Angabe <strong>de</strong>r Argumenttypen. Auch <strong>de</strong>n Standardtyp <strong>in</strong>t sollteman <strong>de</strong>klarieren, um zu ver<strong>de</strong>utlichen, daß man ihn nicht vergessenhat. Än<strong>de</strong>rungen wer<strong>de</strong>n erleichtert.1.4.2 Po<strong>in</strong>ter auf FunktionenDer Name e<strong>in</strong>er Funktion ohne die bei<strong>de</strong>n run<strong>de</strong>n Klammernist <strong>de</strong>r Po<strong>in</strong>ter auf ihren E<strong>in</strong>gang (entry po<strong>in</strong>t). Damit kann e<strong>in</strong>Funktionsname überall verwen<strong>de</strong>t wer<strong>de</strong>n, wo Po<strong>in</strong>ter zulässigs<strong>in</strong>d. Insbeson<strong>de</strong>re kann er als Argument e<strong>in</strong>er weiteren Funktiondienen. In funktionalen Programmiersprachen ist die Möglichkeit,Funktionen als Argumente höherer Funktionen zu verwen<strong>de</strong>n,noch weiter entwickelt. Arrays von Funktionen s<strong>in</strong>dnicht zulässig, wohl aber Arrays von Po<strong>in</strong>tern auf Funktionen,siehe Programm 1.90 auf Seite 254.Makros (#<strong>de</strong>f<strong>in</strong>e ...) s<strong>in</strong>d ke<strong>in</strong>e Funktionen, <strong>in</strong>folge<strong>de</strong>ssengibt es auch ke<strong>in</strong>e Po<strong>in</strong>ter auf Makros. Zu Makros siehe Abschnitt1.9 Präprozessor auf Seite 213.1.4.3 ParameterübergabeUm e<strong>in</strong>er Funktion die Argumente o<strong>de</strong>r Parameter zu übermitteln,gibt es mehrere Wege. Grundsätzlich müssen <strong>in</strong> <strong>de</strong>r Funktiondie entsprechen<strong>de</strong>n Variablen als Platzhalter o<strong>de</strong>r formaleParameter vorkommen und <strong>de</strong>klariert se<strong>in</strong>. Im Aufruf <strong>de</strong>r


138 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Funktion kommt <strong>de</strong>r gleiche Satz von Variablen – gegebenenfallsunter an<strong>de</strong>rem Namen – mit jeweils aktuellen Werten vor;sie wer<strong>de</strong>n als aktuelle Parameter o<strong>de</strong>r Argumente bezeichnet.Die Schnittstelle von Programm und Funktion muß zusammenpassenwie Stecker und Kupplung e<strong>in</strong>er elektrischen Verb<strong>in</strong>dung,d. h. die Liste <strong>de</strong>r aktuellen Parameter muß mit <strong>de</strong>r Liste<strong>de</strong>r formalen Parameter nach Anzahl, Reihenfolge und Typ <strong>de</strong>rParameter übere<strong>in</strong>stimmen.Bei <strong>de</strong>r Wertübergabe (call by value) wird <strong>de</strong>r Funktion e<strong>in</strong>eKopie <strong>de</strong>r aktuellen Parameter <strong>de</strong>s aufrufen<strong>de</strong>n Programmesübergeben. Daraus folgt, daß die Funktion die aktuellen Parameter<strong>de</strong>s aufrufen<strong>de</strong>n Programmes nicht verän<strong>de</strong>rn kann.Bei <strong>de</strong>r Adressübergabe (call by reference) wer<strong>de</strong>n <strong>de</strong>rFunktion die Speicheradressen <strong>de</strong>r aktuellen Parameter <strong>de</strong>s aufrufen<strong>de</strong>nProgrammes übergeben. Die Funktion kann daher dieWerte <strong>de</strong>r Parameter mit Wirkung für das aufrufen<strong>de</strong> Programmverän<strong>de</strong>rn. Sie arbeitet mit <strong>de</strong>n Orig<strong>in</strong>alen <strong>de</strong>r Parameter. Daskann erwünscht se<strong>in</strong> o<strong>de</strong>r auch nicht. Bei bei<strong>de</strong>n Mechanismenwer<strong>de</strong>n die Parameter vollständig ausgerechnet, ehe die Funktionbetreten wird.Wie die Parameterübergabe <strong>in</strong> C, FORTRAN und PASCALaussieht, entnimmt man am besten <strong>de</strong>n Beispielen. Die Parameters<strong>in</strong>d vom Typ <strong>in</strong>teger, um die Beispiele e<strong>in</strong>fach zu halten.Ferner ist noch e<strong>in</strong> Shellscript angegeben, das e<strong>in</strong>e C-Funktionaufruft, die <strong>in</strong> diesem Fall e<strong>in</strong> selbständiges Programm (Funktionma<strong>in</strong>()) se<strong>in</strong> muß.Der von e<strong>in</strong>er Funktion zurückgegebene Wert (Rückgabewert)kann nur e<strong>in</strong> e<strong>in</strong>facher Typ o<strong>de</strong>r e<strong>in</strong> Po<strong>in</strong>ter se<strong>in</strong>.Zusammengesetzte Typen wie Arrays, Str<strong>in</strong>gs o<strong>de</strong>r Strukturenkönnen nur durch Po<strong>in</strong>ter zurückgegeben wer<strong>de</strong>n. Es ist zulässig,ke<strong>in</strong>en Wert zurückzugeben. Dann ist die Funktion vom Typvoid und macht sich alle<strong>in</strong> durch ihre Nebeneffekte bemerkbar.Für die Systemaufrufe von UNIX und die Standardfunktionenvon C ist im Referenz-Handbuch <strong>in</strong> <strong>de</strong>n Sektionen (2) und (3)angegeben, von welchem Typ die Argumente und <strong>de</strong>r Funktionswerts<strong>in</strong>d. Da diese Funktionen allesamt C-Funktionen s<strong>in</strong>d, lassensie sich ohne Probleme <strong>in</strong> C-Programme e<strong>in</strong>b<strong>in</strong><strong>de</strong>n. Bei an<strong>de</strong>renSprachen ist es <strong>de</strong>nkbar, daß ke<strong>in</strong> e<strong>in</strong>em C-Typ entsprechen<strong>de</strong>rVariablentyp verfügbar ist. Auch bei Str<strong>in</strong>gs gibt es wegen<strong>de</strong>r unterschiedlichen Speicherung <strong>in</strong> <strong>de</strong>n e<strong>in</strong>zelnen Sprachen


1.4. FUNKTIONEN 139Reibereien. Falls die Übergabemechanismen unverträglich s<strong>in</strong>d,muß man die C-Funktion <strong>in</strong> e<strong>in</strong>e Funktion o<strong>de</strong>r Prozedur <strong>de</strong>ran<strong>de</strong>ren Sprache so verpacken, daß das aufrufen<strong>de</strong> Programme<strong>in</strong>e e<strong>in</strong>heitliche Programmiersprache sieht. Das Vorgehen dabeikann masch<strong>in</strong>enbezogen se<strong>in</strong>, was man eigentlich vermei<strong>de</strong>nwill.In <strong>de</strong>n folgen<strong>de</strong>n Programmbeispielen wird die Summe auszwei Summan<strong>de</strong>n berechnet, zuerst im Hauptprogramm direktund dann durch zwei Funktionen, die ihre Argumente – die Summan<strong>de</strong>n– by value beziehungsweise by reference übernehmen.Die Funktionen verän<strong>de</strong>rn ihre Summan<strong>de</strong>n, was im ersten Fallke<strong>in</strong>e Auswirkung im Hauptprogramm hat. Hauptprogrammeund Funktionen s<strong>in</strong>d <strong>in</strong> C, FORTRAN und PASCAL geschrieben,was neun Komb<strong>in</strong>ationen ergibt. Wir betreten damit zugleichdas an Fallgruben reiche Gebiet <strong>de</strong>r Mischung von Programmiersprachen(mixed language programm<strong>in</strong>g). Zunächst die bei<strong>de</strong>nFunktionen im geliebten C:/* C-Funktion (Summe) call by value *//* Compileraufruf cc -c csv.c, liefert csv.o */<strong>in</strong>t csv(<strong>in</strong>t x,<strong>in</strong>t y){<strong>in</strong>t z;puts("Funktion mit Parameteruebernahme by value:");pr<strong>in</strong>tf("C-Fkt. hat uebernommen: %d %d\n", x, y);z = x + y;pr<strong>in</strong>tf("C-Fkt. gibt folgen<strong>de</strong> Summe zurueck: %d\n", z);/* Aen<strong>de</strong>rung <strong>de</strong>r Summan<strong>de</strong>n */x = 77; y = 99;return(z);}Quelle 1.34 : C-Funktion, die Parameter by value übernimmt/* C-Funktion (Summe) call by reference *//* Compileraufruf cc -c csr.c, liefert csr.o */<strong>in</strong>t csr(<strong>in</strong>t *px,<strong>in</strong>t *py){<strong>in</strong>t z;puts("Funktion mit Parameteruebenahme by reference:");pr<strong>in</strong>tf("C-Fkt. hat uebernommen: %d %d\n", *px, *py);


140 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>z = *px + *py;pr<strong>in</strong>tf("C-Fkt. gibt folgen<strong>de</strong> Summe zurueck:/* Aen<strong>de</strong>rung <strong>de</strong>r Summan<strong>de</strong>n */*px = 66; *py = 88;return(z);}%d\n", z);Quelle 1.35 : C-Funktion, die Parameter by reference übernimmtIm bewährten FORTRAN 77 haben wir lei<strong>de</strong>r ke<strong>in</strong>en Weg gefun<strong>de</strong>n,<strong>de</strong>r Funktion beizubr<strong>in</strong>gen, ihre Parameter by value zuübernehmen (<strong>in</strong> FORTRAN 90 ist es möglich). Es bleibt daherbei nur e<strong>in</strong>er Funktion, die – wie <strong>in</strong> FORTRAN üblich – ihre Parameterby reference übernimmt:CCFortran-Funktion (Summe) call by referenceCompileraufruf f77 -c fsr.f<strong>in</strong>teger function fsr(x, y)<strong>in</strong>teger x, y, zCwrite (6,’(”F-Fkt. mit Uebernahme by reference:”)’)write (6,’(”F-Fkt. hat uebernommen: ”,2I6)’) x, yz = x + ywrite (6,’(”F-Fkt. gibt zurueck: ”,I8)’) zAen<strong>de</strong>rung <strong>de</strong>r Summan<strong>de</strong>nx = 66y = 88fsr = zendQuelle 1.36 : FORTRAN-Funktion, die Parameter by referenceübernimmtPASCAL-Funktionen kennen wie<strong>de</strong>r bei<strong>de</strong> Möglichkeiten,aber wir wer<strong>de</strong>n auf e<strong>in</strong>e an<strong>de</strong>re Schwierigkeit stoßen. Vorläufigs<strong>in</strong>d wir jedoch hoffnungsvoll:{Pascal-Funktion (Summe) call by value}{Compileraufruf pc -c psv.p}module b;import StdOutput;exportfunction psv(x, y: <strong>in</strong>teger): <strong>in</strong>teger;


1.4. FUNKTIONEN 141implementfunction psv;var z: <strong>in</strong>teger;beg<strong>in</strong>writeln(’Funktion mit P’uebernahme by value:’);writeln(’P-Fkt. hat uebernommen: ’, x, y);z := x + y;writeln(’P-Fkt. gibt folgen<strong>de</strong>n Wert zurueck: ’, z){ Aen<strong>de</strong>rung <strong>de</strong>r Summan<strong>de</strong>n }x := 77; y := 99;psv := z;end;end.Quelle 1.37 : PASCAL-Funktion, die Parameter by value übernimmt{Pascal-Funktion (Summe) call by reference}{Compileraufruf pc -c psr.p}module a;import StdOutput;exportfunction psr(var x, y: <strong>in</strong>teger): <strong>in</strong>teger;implementfunction psr;var z: <strong>in</strong>teger;beg<strong>in</strong>writeln(’Funktion mit P’uebernahme by reference:’)writeln(’P-Fkt. hat uebernommen: ’, x, y );z := x + y;writeln(’P-Fkt. gibt folgen<strong>de</strong>n Wert zurueck: ’, z){ Aen<strong>de</strong>rung <strong>de</strong>r Summan<strong>de</strong>n }x := 66; y := 88;psr := z;end;end.Quelle 1.38 : PASCAL-Funktion, die Parameter by referenceübernimmtDie Funktionen wer<strong>de</strong>n für sich mit <strong>de</strong>r Option -c ihres jeweiligenCompilers kompiliert, wodurch Objektfiles mit <strong>de</strong>r Kennung.o entstehen, die beim Kompilieren <strong>de</strong>r Hauptprogramme


142 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>aufgeführt wer<strong>de</strong>n. Nun zu <strong>de</strong>n Hauptprogrammen, zuerst wie<strong>de</strong>r<strong>in</strong> C:/* C-Programm csummec, das C-Funktionen aufruft *//* Compileraufruf cc -o csummec csummec.c csr.o csv.o */#<strong>in</strong>clu<strong>de</strong> extern <strong>in</strong>t csv(<strong>in</strong>t x,<strong>in</strong>t y),csr(<strong>in</strong>t *px,<strong>in</strong>t *py);<strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t a, b;puts("Bitte die bei<strong>de</strong>n Summan<strong>de</strong>n e<strong>in</strong>geben!");scanf("%d %d", &a, &b);pr<strong>in</strong>tf("Die Summan<strong>de</strong>n s<strong>in</strong>d: %d %d\n", a, b);pr<strong>in</strong>tf("Die Summe (direkt) ist: %d\n", (a + b));pr<strong>in</strong>tf("Die Summe ist: %d\n", csv(a, b));pr<strong>in</strong>tf("Die Summan<strong>de</strong>n s<strong>in</strong>d: %d %d\n", a, b);pr<strong>in</strong>tf("Die Summe ist: %d\n", csr(&a, &b));pr<strong>in</strong>tf("Die Summan<strong>de</strong>n s<strong>in</strong>d: %d %d\n", a, b);return 0;}Quelle 1.39 : C-Programm, das Parameter by value und by referencean C-Funktionen übergibtNun das C-Hauptprogramm, das e<strong>in</strong>e FORTRAN-Funktionaufruft, e<strong>in</strong> <strong>in</strong> <strong>de</strong>r Numerik häufiger Fall:/* C-Programm csummef, das e<strong>in</strong>e FORTRAN-Funktion aufruft *//* Compileraufruf cc -o csummef csummef.c fsr.o -lcl */#<strong>in</strong>clu<strong>de</strong> extern <strong>in</strong>t fsr(<strong>in</strong>t *x,<strong>in</strong>t *y);<strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t a, b;scanf("%d %d", &a, &b);pr<strong>in</strong>tf("Die Summan<strong>de</strong>n s<strong>in</strong>d: %d %d\n", a, b);pr<strong>in</strong>tf("Die Summe (direkt) ist: %d\n", (a + b));pr<strong>in</strong>tf("Die Summe ist: %d\n", fsr(&a, &b));pr<strong>in</strong>tf("Die Summan<strong>de</strong>n s<strong>in</strong>d: %d %d\n", a, b);


1.4. FUNKTIONEN 143return 0;}Quelle 1.40 : C-Programm, das Parameter by reference an e<strong>in</strong>eFORTRAN-Funktion übergibtDie L<strong>in</strong>ker-Option -lcl ist erfor<strong>de</strong>rlich, wenn FORTRANo<strong>de</strong>rPASCAL-Module <strong>in</strong> C-Programme e<strong>in</strong>gebun<strong>de</strong>n wer<strong>de</strong>n.Sie bewirkt die H<strong>in</strong>zunahme <strong>de</strong>r FORTRAN- und PASCAL-Laufzeitbibliothek /usr/lib/libcl.a, ohne die Bezüge (Referenzen)auf FORTRAN- o<strong>de</strong>r PASCAL-Rout<strong>in</strong>en unter Umstän<strong>de</strong>noffen bleiben. An<strong>de</strong>rs gesagt, <strong>in</strong> <strong>de</strong>n FORTRAN- o<strong>de</strong>rPASCAL-Funktionen kommen Namen vor – zum Beispiel write– <strong>de</strong>ren Def<strong>in</strong>ition <strong>in</strong> besagter Laufzeitbibliothek zu f<strong>in</strong><strong>de</strong>n ist.C und PASCAL s<strong>in</strong>d sich im großen ganzen ähnlich, es gibt aberUnterschie<strong>de</strong> h<strong>in</strong>sichtlich <strong>de</strong>s Geltungsbereiches von Variablen,die hier nicht <strong>de</strong>utlich wer<strong>de</strong>n:/* C-Programm csummep, das PASCAL-Funktionen aufruft. *//* Compiler: cc -o csummep csummep.c psv.o psr.o -lcl */#<strong>in</strong>clu<strong>de</strong> extern <strong>in</strong>t psv(<strong>in</strong>t x,<strong>in</strong>t y),psr(<strong>in</strong>t *x,<strong>in</strong>t *y)<strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t a, b;puts("Bitte die bei<strong>de</strong>n Summan<strong>de</strong>n e<strong>in</strong>geben!");scanf("%d %d", &a, &b);pr<strong>in</strong>tf("Die Summan<strong>de</strong>n s<strong>in</strong>d: %d %d\n", a, b);pr<strong>in</strong>tf("Die Summe (direkt) ist: %d\n", (a + b));pr<strong>in</strong>tf("Die Summe ist: %d\n", psv(a, b));pr<strong>in</strong>tf("Die Summan<strong>de</strong>n s<strong>in</strong>d: %d %d\n", a, b);pr<strong>in</strong>tf("Die Summe ist: %d\n", psr(&a, &b));pr<strong>in</strong>tf("Die Summan<strong>de</strong>n s<strong>in</strong>d: %d %d\n", a, b);return 0;}Quelle 1.41 : C-Programm, das Parameter by value und by referencean PASCAL-Funktionen übergibtHiernach sollte klar se<strong>in</strong>, warum die C-Standardfunktionpr<strong>in</strong>tf(3) mit Variablen als Argument arbeitet, während die


144 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>ähnliche C-Standardfunktion scanf(3) Po<strong>in</strong>ter als Argumentverlangt. pr<strong>in</strong>tf(3) gibt Werte aus, ohne sie zu än<strong>de</strong>rn. Es istfür das Ergebnis belanglos, ob die Funktion Adressen (Po<strong>in</strong>ter)o<strong>de</strong>r Kopien <strong>de</strong>r Variablen verwen<strong>de</strong>t (die Syntax legt das allerd<strong>in</strong>gsfest). H<strong>in</strong>gegen soll scanf(3) Werte mit Wirkung für dieaufrufen<strong>de</strong> Funktion e<strong>in</strong>lesen. Falls es sich nur um e<strong>in</strong>en Werthan<strong>de</strong>lte, könnte das noch über <strong>de</strong>n Returnwert bewerkstelligtwer<strong>de</strong>n, aber scanf(3) soll mehrere Werte – dazu noch verschie<strong>de</strong>nenTyps – verarbeiten. Das geht nur über von scanf(3)und <strong>de</strong>r aufrufen<strong>de</strong>n Funktion geme<strong>in</strong>sam verwen<strong>de</strong>te Po<strong>in</strong>ter.Nun die drei FORTRAN-Hauptprogramme mit Aufruf <strong>de</strong>rFunktionen <strong>in</strong> C, FORTRAN und PASCAL:CCFORTRAN-Programm, das C-Funktionen aufruftCompileraufruf f77 -o fsummec fummec.f csv.o csr.oprogram fsummec$ALIAS csv (%val, %val)<strong>in</strong>teger a, b , s, csr, csvCCwrite (6, 100)read (5, *) a, bwrite (6, 102) a, bs = a + bwrite (6, 103) scall by values = csv(a, b)write (6, 104) swrite (6, 102) a, bcall by references = csr(a, b)write (6, 105) swrite (6, 102) a, b100 format (’Bitte die bei<strong>de</strong>n Summan<strong>de</strong>n e<strong>in</strong>geben!’)102 format (’Die Summan<strong>de</strong>n s<strong>in</strong>d: ’, 2I6)103 format (’Die Summe (direkt) ist: ’, I8)104 format (’Die Summe ist: ’, I8)105 format (’Die Summe ist: ’, I8)end


1.4. FUNKTIONEN 145Quelle 1.42 : FORTRAN-Programm, das Parameter by value undby reference an C-Funktionen übergibtCCFORTRAN-Programm, das F77-Funktion aufruftCompileraufruf f77 -o fsummef fsummef.f fsr.oprogram fsummef<strong>in</strong>teger a, b , s, fsrCCwrite (6, 100)read (5, *) a, bwrite (6, 102) a, bs = a + bwrite (6, 103) scall by value nicht moeglichcall by reference (<strong>de</strong>fault)s = fsr(a, b)write (6, 105) swrite (6, 102) a, b100 format (’Bitte die bei<strong>de</strong>n Summan<strong>de</strong>n e<strong>in</strong>geben!’)102 format (’Die Summan<strong>de</strong>n s<strong>in</strong>d: ’, 2I6)103 format (’Die Summe (direkt) ist: ’, I8)105 format (’Die Summe ist: ’, I8)endQuelle 1.43 : FORTRAN-Programm, das Parameter by referencean e<strong>in</strong>e FORTRAN-Funktion übergibtCCFORTRAN-Programm, das PASCAL-Funktionen aufruftCompileraufruf f77 -o fsummep fsummep.f psv.o psr.oprogram fsummep$ALIAS psv (%val, %val)<strong>in</strong>teger a, b, s, psv, psrexternal psv, psrwrite (6, 100)read (5, *) a, bwrite (6, 102) a, bs = a + b


146 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>CCwrite (6, 103) scall by values = psv(a, b)write (6, 104) swrite (6, 102) a, bcall by references = psr(a, b)write (6, 105) swrite (6, 102) a, b100 format (’Bitte die bei<strong>de</strong>n Summan<strong>de</strong>n e<strong>in</strong>geben!’)102 format (’Die Summan<strong>de</strong>n s<strong>in</strong>d: ’, 2I6)103 format (’Die Summe (direkt) ist: ’, I8)104 format (’Die Summe ist: ’, I8)105 format (’Die Summe ist: ’, I8)endQuelle 1.44 : FORTRAN-Programm, das Parameter by value undby reference an PASCAL-Funktionen übergibtDie FORTRAN-Compiler-Anweisung $ALIAS veranlaßt <strong>de</strong>nCompiler, <strong>de</strong>r jeweiligen Funktion die Parameter entgegen se<strong>in</strong>erGewohnheit by value zu übergeben. Zum guten Schluß diePASCAL-Hauptprogramme:{PASCAL-Programm, das C-Funktionen aufruft}{Compiler: pc -o psummec psummec.p csv.o csr.o}program psummec (<strong>in</strong>put, output);var a, b, s: <strong>in</strong>teger;function csv(x, y: <strong>in</strong>teger): <strong>in</strong>teger;external C;function csr(var x, y: <strong>in</strong>teger): <strong>in</strong>teger;external C;{call by value}{call by ref.}beg<strong>in</strong>writeln(’Bitte die bei<strong>de</strong>n Summan<strong>de</strong>n e<strong>in</strong>geben!’);readln(a); readln(b);write(’Die Summan<strong>de</strong>n s<strong>in</strong>d: ’); write(a); writeln(b);s := a + b;write(’Die Summe (direkt) ist: ’); writeln(s);s := csv(a, b);


1.4. FUNKTIONEN 147write(’Die Summe ist: ’); writeln(s);write(’Die Summan<strong>de</strong>n s<strong>in</strong>d: ’); write(a); writeln(b);s := csr(a, b);write(’Die Summe ist: ’); writeln(s);write(’Die Summan<strong>de</strong>n s<strong>in</strong>d: ’); write(a); writeln(b);end.Quelle 1.45 : PASCAL-Programm, das Parameter by value undby reference an C-Funktionen übergibt{PASCAL-Programm, das FORTRAN-Funktion aufruft}{Compiler: pc -o psummef psummef.p fsr.o}program psummef (<strong>in</strong>put, output);var a, b, s: <strong>in</strong>teger;function fsr(var x, y: <strong>in</strong>teger): <strong>in</strong>teger;external ftn77;{call by ref.}beg<strong>in</strong>writeln(’Bitte die bei<strong>de</strong>n Summan<strong>de</strong>n e<strong>in</strong>geben!’);readln(a); readln(b);write(’Die Summan<strong>de</strong>n s<strong>in</strong>d: ’); write(a); writeln(b);s := a + b;write(’Die Summe (direkt) ist: ’); writeln(s);s := fsr(a, b);write(’Die Summe ist: ’); writeln(s);write(’Die Summan<strong>de</strong>n s<strong>in</strong>d: ’); write(a); writeln(b);end.Quelle 1.46 : PASCAL-Programm, das Parameter by referencean e<strong>in</strong>e FORTRAN-Funktion übergibt{PASCAL-Programm, das PASCAL-Funktionen aufruft}{Compileraufruf pc -o psummep psummep.p psv.o psr.o}program psummep (<strong>in</strong>put, output);var a, b, s: <strong>in</strong>teger;function psv(x, y: <strong>in</strong>teger): <strong>in</strong>teger;external;function psr(var x, y: <strong>in</strong>teger): <strong>in</strong>teger;{call by value}{call by ref.}


148 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>external;beg<strong>in</strong>writeln(’Bitte die bei<strong>de</strong>n Summan<strong>de</strong>n e<strong>in</strong>geben!’);readln(a); readln(b);write(’Die Summan<strong>de</strong>n s<strong>in</strong>d: ’); write(a); writeln(b);s := a + b;write(’Die Summe (direkt) ist: ’); writeln(s);s := psv(a, b);write(’Die Summe ist: ’); writeln(s);write(’Die Summan<strong>de</strong>n s<strong>in</strong>d: ’); write(a); writeln(b);s := psr(a, b);write(’Die Summe ist: ’); writeln(s);write(’Die Summan<strong>de</strong>n s<strong>in</strong>d: ’); write(a); writeln(b);end.Quelle 1.47 : PASCAL-Programm, das Parameter by value undby reference an PASCAL-Funktionen übergibtSollten Sie die Beispiele nachvollzogen haben, müßteIhr L<strong>in</strong>ker <strong>in</strong> zwei Fällen mit e<strong>in</strong>er Fehlermeldungunsatisfied symbol: output (data) die Arbeit verweigerthaben. Die PASCAL-Funktionen psv() und psr() gebenetwas auf das Term<strong>in</strong>al aus. Bei getrennt kompilierten Modulenerfor<strong>de</strong>rt dies die Zeile:import StdOutput;Das importierte, vorgefertigte PASCAL-Modul StdOutputmacht von e<strong>in</strong>em Textfile output Gebrauch, das letzten En<strong>de</strong>s<strong>de</strong>r Bildschirm ist. Im PASCAL-Programm öffnet die Zeileprogram psummep (<strong>in</strong>put, output);dieses Textfile. In C-Programmen wird die Datei mit <strong>de</strong>m Dateipo<strong>in</strong>terstdout ebenso wie <strong>in</strong> FORTRAN-Programmen dieUnit 6 automatisch geöffnet. H<strong>in</strong>ter <strong>de</strong>m Dateipo<strong>in</strong>ter bzw. <strong>de</strong>rUnit steckt <strong>de</strong>r Bildschirm. Lei<strong>de</strong>r sehen wir – <strong>in</strong> Übere<strong>in</strong>stimmungmit unseren Handbüchern – ke<strong>in</strong>en Weg, die PASCAL-Datei output mit stdout von C o<strong>de</strong>r <strong>de</strong>r Unit 6 von FORT-RAN zu verb<strong>in</strong><strong>de</strong>n. Wollen wir PASCAL-Funktionen <strong>in</strong> e<strong>in</strong> C-o<strong>de</strong>r FORTRAN-Programm e<strong>in</strong>b<strong>in</strong><strong>de</strong>n, müssen die Funktionenauf Term<strong>in</strong>alausgabe verzichten (e<strong>in</strong>e Ausgabe <strong>in</strong> e<strong>in</strong>e Datei wäremöglich):


1.4. FUNKTIONEN 149{Pascal-Funktion (Summe) call by value, ohne Output}{Compileraufruf pc -c xpsv.p}module b;exportfunction psv(x, y: <strong>in</strong>teger): <strong>in</strong>teger;implementfunction psv;var z: <strong>in</strong>teger;beg<strong>in</strong>z := x + y;{ Aen<strong>de</strong>rung <strong>de</strong>r Summan<strong>de</strong>n }x := 77; y := 99;psv := z;end;end.Quelle 1.48 : PASCAL-Funktion, die Parameter by value übernimmt,ohne Ausgabe{Pascal-Funktion (Summe) call by reference}{ohne Output}{Compileraufruf pc -c xpsr.p}module a;exportfunction psr(var x, y: <strong>in</strong>teger): <strong>in</strong>teger;implementfunction psr;var z: <strong>in</strong>teger;beg<strong>in</strong>z := x + y;{ Aen<strong>de</strong>rung <strong>de</strong>r Summan<strong>de</strong>n }x := 66; y := 88;psr := z;end;end.Quelle 1.49 : PASCAL-Funktion, die Parameter by referenceübernimmt, ohne AusgabeDamit geht es. Der Compilerbauer weiß, wie die e<strong>in</strong>zelnenProgrammiersprachen ihre Ausgabe bewerkstelligen und kannÜbergänge <strong>in</strong> Form von Compiler-Anweisungen o<strong>de</strong>r Zwischenfunktionene<strong>in</strong>richten. So macht es Microsoft bei se<strong>in</strong>em großen


150 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>C-Compiler. Aber wenn nichts vorgesehen ist, muß <strong>de</strong>r gewöhnlicheProgrammierer solche Unverträglichkeiten h<strong>in</strong>nehmen.Auch Shellscripts können Funktionen aufrufen. Diese müssenselbständige Programme wie externe Kommandos se<strong>in</strong>, <strong>de</strong>rMechanismus sieht etwas an<strong>de</strong>rs aus. Hier das Shellscript:# Shellscript, das e<strong>in</strong>e C-Funktion aufruft. 28.01.1988# Filename shsummepr<strong>in</strong>t Bitte die bei<strong>de</strong>n Summan<strong>de</strong>n e<strong>in</strong>geben!read a; read bpr<strong>in</strong>t Die Summan<strong>de</strong>n s<strong>in</strong>d $a $bpr<strong>in</strong>t Die Shell-Summe ist ‘expr $a + $b‘pr<strong>in</strong>t Die Funktions-Summe ist ‘cssh $a $b‘pr<strong>in</strong>t Die Summan<strong>de</strong>n s<strong>in</strong>d $a $bexitQuelle 1.50 : Shellscript mit ParameterübergabeDie zugehörige C-Funktion ist e<strong>in</strong> Hauptprogramm:/* C-Programm zum Aufruf durch Shellskript, 29.01.1988 *//* Compileraufruf: cc -o cssh cssh.c */<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[]){<strong>in</strong>t x, y;sscanf(argv[1], "%d", &x);sscanf(argv[2], "%d", &y);pr<strong>in</strong>tf("%d", (x + y));return 0;}Quelle 1.51 : C-Programm, das Parameter von e<strong>in</strong>em ShellscriptübernimmtFerner können Shellscripts Shellfunktionen aufrufen, siehedas Shellscript ?? Türme von Hanoi auf Seite ??.Entschuldigen Sie bitte, daß dieser Abschnitt etwas breit geratenist. Die Parameterübergabe muß sitzen, wenn man mehrals Trivialprogramme schreibt, und man ist nicht immer <strong>in</strong> <strong>de</strong>rglücklichen Lage, re<strong>in</strong> <strong>in</strong> C programmieren zu können. Verwen<strong>de</strong>tman vorgegebene Bibliotheken, so s<strong>in</strong>d diese manchmal <strong>in</strong>e<strong>in</strong>er an<strong>de</strong>ren Programmiersprache verfaßt. Dann hat man sich


1.4. FUNKTIONEN 151mit e<strong>in</strong>er frem<strong>de</strong>n Syntax und <strong>de</strong>n kle<strong>in</strong>en, aber be<strong>de</strong>utsamenUnverträglichkeiten herumzuschlagen.1.4.4 Kommandozeilenargumente, ma<strong>in</strong>()Auch das Hauptprogramm ma<strong>in</strong>() ist e<strong>in</strong>e Funktion, die Parametero<strong>de</strong>r Argumente übernehmen kann, und zwar aus<strong>de</strong>r Kommandozeile beim Aufruf <strong>de</strong>s Programms. Sie kennendas von vielen UNIX-Kommandos, die nichts an<strong>de</strong>res als C-Programme s<strong>in</strong>d.Der Mechanismus ist stets <strong>de</strong>rselbe. Die Argumente, getrenntdurch Spaces o<strong>de</strong>r Ähnliches, wer<strong>de</strong>n <strong>in</strong> e<strong>in</strong> Array of Str<strong>in</strong>gsmit <strong>de</strong>m Namen argv (Argumentvektor) gestellt. Gleichzeitigzählt e<strong>in</strong> Argumentzähler argc die Anzahl <strong>de</strong>r übergebenenArgumente, wobei <strong>de</strong>r Funktionsname selbst das erste Argument(In<strong>de</strong>x 0) ist. Bei e<strong>in</strong>em Programmaufruf ohne Argumentesteht also <strong>de</strong>r Programmname <strong>in</strong> argv[0], <strong>de</strong>r Argumentzählerargc hat <strong>de</strong>n Wert 1. Das erste nichtbelegte Element <strong>de</strong>s Argumentvektorsenthält e<strong>in</strong>en leeren Str<strong>in</strong>g. Die Umwandlung <strong>de</strong>rArgumente vom Typ Str<strong>in</strong>g <strong>in</strong> <strong>de</strong>n gewünschten Typ besorgt dieFunktion sscanf(3).Der Anfang e<strong>in</strong>es Hauptprogrammes mit Kommandozeilenargumentensieht folgen<strong>de</strong>rmaßen aus:<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[]){char a; <strong>in</strong>t x;if (argc < 3) {puts("Zuwenige Parameter");exit(-1);}sscanf(argv[1], "%c", &a);sscanf(argv[2], "%d", &x);....Quelle 1.52 : C-Programm, das Argumente aus <strong>de</strong>r KommandozeileübernimmtDas erste Kommandozeilenargument (nach <strong>de</strong>m Kommando


152 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>selbst) wird als Zeichen verarbeitet, das zweite als ganze Zahl.Etwaige weitere Argumente fallen unter <strong>de</strong>n Tisch.Die Funktion ma<strong>in</strong>() ist immer vom Typ extern <strong>in</strong>t. Dadies <strong>de</strong>r Defaulttyp für Funktionen ist, könnte die Typ<strong>de</strong>klarationweggelassen wer<strong>de</strong>n. Sie kann Argumente übernehmen,braucht es aber nicht. Infolge<strong>de</strong>ssen s<strong>in</strong>d folgen<strong>de</strong> Deklarationengültig:ma<strong>in</strong>()<strong>in</strong>t ma<strong>in</strong>()extern <strong>in</strong>t ma<strong>in</strong>()ma<strong>in</strong>(void)<strong>in</strong>t ma<strong>in</strong>(void)extern <strong>in</strong>t ma<strong>in</strong>(void)ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[])<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[])extern <strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[])ma<strong>in</strong>(<strong>in</strong>t argc, char **argv)<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char **argv)extern <strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char **argv)und alle an<strong>de</strong>ren falsch. Die ersten sechs s<strong>in</strong>d <strong>in</strong> ihrer Be<strong>de</strong>utunggleich, die weiteren gelten bei Argumenten <strong>in</strong> <strong>de</strong>r Kommandozeile.Die Norm ISO/IEC 9899:1999 sieht für C-Programme, die untere<strong>in</strong>em Betriebssystem laufen (hosted environment), nur diebei<strong>de</strong>n folgen<strong>de</strong>n Formen vor:<strong>in</strong>t ma<strong>in</strong>(void)<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[])und das reicht auch. Unter POSIX-konformen Betriebssystemenkann e<strong>in</strong> drittes Argument h<strong>in</strong>zukommen, das die Umgebung(environment po<strong>in</strong>ter) enthält:<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[], char *envp[])Den Rückgabewert von ma<strong>in</strong>() sollte man nicht <strong>de</strong>m Zufallüberlassen, son<strong>de</strong>rn mit e<strong>in</strong>er return-Anweisung ausdrücklichfestlegen (0 bei Erfolg). Er wird von <strong>de</strong>r Shell übernommen.


1.4. FUNKTIONEN 1531.4.5 Funktionen mit wechseln<strong>de</strong>r ArgumentanzahlMit ma<strong>in</strong>() haben wir e<strong>in</strong>e Funktion kennengelernt, die e<strong>in</strong>ewechseln<strong>de</strong> Anzahl von Argumenten übernimmt. Auch für an<strong>de</strong>reFunktionen als ma<strong>in</strong>() gibt es e<strong>in</strong>en Mechanismus zu diesemZweck, schauen Sie bitte unter varargs(5) nach. Der Mechanismusist nicht übermäßig <strong>in</strong>telligent, son<strong>de</strong>rn an e<strong>in</strong>ige Voraussetzungengebun<strong>de</strong>n:• Es muß m<strong>in</strong><strong>de</strong>stens e<strong>in</strong> Argument vorhan<strong>de</strong>n se<strong>in</strong>,• <strong>de</strong>r Typ <strong>de</strong>s ersten Arguments muß bekannt se<strong>in</strong>,• es muß e<strong>in</strong> Kriterium für das En<strong>de</strong> <strong>de</strong>r Argumentliste bekanntse<strong>in</strong>.Die erfor<strong>de</strong>rlichen Makros stehen <strong>in</strong> <strong>de</strong>n <strong>in</strong>clu<strong>de</strong>-Dateien für UNIX System V o<strong>de</strong>r für ANSI-C. Wir erklären die Vorgehensweise an e<strong>in</strong>em Beispiel, das <strong>de</strong>rFunktion pr<strong>in</strong>tf(3) nachempfun<strong>de</strong>n ist (es ist damit nicht gesagt,daß pr<strong>in</strong>tf(3) tatsächlich so aussieht):/* Funktion pr<strong>in</strong>ti(), Ersatz fuer pr<strong>in</strong>tf(), nur fuer<strong>de</strong>zimale Ganzzahlen, Zeichen und Str<strong>in</strong>gs. SieheReferenz-Handbuch unter varargs(5), 22.02.91 *//* Returnwert 0 = ok, -1 = Fehler, sonst wie pr<strong>in</strong>tf() *//* Compileraufruf cc -c pr<strong>in</strong>ti.c */#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t fputc();void <strong>in</strong>t pr<strong>in</strong>t();/* Funktion pr<strong>in</strong>ti(), variable Anzahl von Argumenten */<strong>in</strong>t pr<strong>in</strong>ti(va alist)va dcl{va list pvar;unsigned long arg;<strong>in</strong>t field, sig;char *format, *str<strong>in</strong>g;long ivar;


154 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>/* Uebernahme und Auswertung <strong>de</strong>s Formatstr<strong>in</strong>gs */va start(pvar);format = va arg(pvar, char *);while (1) {/* Ausgabe von Literalen */while ((*format != ’%’) && (*format != ’\0’))fputc(*format++, stdout);/* En<strong>de</strong> <strong>de</strong>s Formatstr<strong>in</strong>gs */if (*format == ’\0’) {va end(pvar);return 0;}/* Prozentzeichen, Platzhalter */format++;field = 0;/* Auswertung Laengenangabe */while (*format >= ’0’ && *format


1.4. FUNKTIONEN 155}}sig = ((ivar = va arg(pvar, long)) < 0 ? 1arg = (unsigned long)(ivar < 0 ? -ivar : i<strong>in</strong>t pr<strong>in</strong>t(arg, sig, field);break;case ’u’:arg = va arg(pvar, unsigned long);<strong>in</strong>t pr<strong>in</strong>t(arg, 0, field);break;<strong>de</strong>fault:va end(pvar);return -1; /* unbekannter Typ */}format++;break;case ’%’:fputc(*format, stdout);break;case ’c’:fputc(va arg(pvar, char), stdout);break;case ’s’:str<strong>in</strong>g = va arg(pvar, char *);while ((fputc(*(str<strong>in</strong>g++), stdout)) != ’\0’) ;break;<strong>de</strong>fault:va end(pvar);return -1; /* unbekannter Typ */}format++;/* Funktion zur Ausgabe <strong>de</strong>r <strong>de</strong>zimalen Ganzzahl */void <strong>in</strong>t pr<strong>in</strong>t(unsigned long number,<strong>in</strong>t signum,<strong>in</strong>t field){<strong>in</strong>t i;char table[21];long radix = 10;for (i = 0; i < 21; i++)*(table + i) = ’ ’;/* Umwandlung Zahl nach ASCII-Zeichen */


156 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>for (i = 0; i < 20; i++) {*(table + i) = *("0123456789" + (number % radix));number /= radix;if (number == 0) break;}/* Vorzeichen */if (signum)*(table + ++i) = ’-’;/* Ausgabe */if ((field != 0) && (field < 20))i = field -1;}while (i >= 0)fputc(*(table + i-), stdout);/* En<strong>de</strong> */Quelle 1.53 : C-Funktion mit wechseln<strong>de</strong>r Anzahl von ArgumentenNach <strong>de</strong>r <strong>in</strong>clu<strong>de</strong>-Datei varargs.h folgt <strong>in</strong> gewohnter Weisedie Funktion, hier pr<strong>in</strong>ti(). Ihre Argumentenliste heißtva_alist und ist vom Typ va_dcl, ohne Semikolon! Innerhalb<strong>de</strong>r Funktion brauchen wir e<strong>in</strong>en Po<strong>in</strong>ter pvar auf die Argumente,dieser ist vom Typ va_list, nicht zu verwechseln mit <strong>de</strong>rArgumentenliste va_alist. Die weiteren Variablen s<strong>in</strong>d unverb<strong>in</strong>dlich.Zu Beg<strong>in</strong>n <strong>de</strong>r Arbeit muß das Makro va_start(pvar) aufgerufenwer<strong>de</strong>n. Es <strong>in</strong>itialisiert <strong>de</strong>n Po<strong>in</strong>ter pvar mit <strong>de</strong>m Anfang<strong>de</strong>r Argumentenliste. Am En<strong>de</strong> <strong>de</strong>r Arbeit muß entsprechendmit <strong>de</strong>m Makro va_end(pvar) aufgeräumt wer<strong>de</strong>n.Das Makro va_arg(pvar, type) gibt das Argument zurück,auf das <strong>de</strong>r Po<strong>in</strong>ter pvar zeigt, und zwar <strong>in</strong> <strong>de</strong>r Form <strong>de</strong>sangegebenen Typs, <strong>de</strong>n man also kennen muß. Gleichzeitig wird<strong>de</strong>r Po<strong>in</strong>ter pvar e<strong>in</strong>s weiter geschoben. Die Zeileformat = va_arg(pvar, char *);weist <strong>de</strong>m Po<strong>in</strong>ter auf char format die Adresse <strong>de</strong>s Formatstr<strong>in</strong>gs<strong>in</strong> <strong>de</strong>r Argumentenliste von pr<strong>in</strong>ti() zu. Damit ist <strong>de</strong>r


1.4. FUNKTIONEN 157Formatstr<strong>in</strong>g wie je<strong>de</strong>r an<strong>de</strong>re Str<strong>in</strong>g zugänglich. Zugleich wird<strong>de</strong>r Po<strong>in</strong>ter pvar auf das nächste Argument gestellt, üblicherweisee<strong>in</strong>e Konstante o<strong>de</strong>r Variable. Aus <strong>de</strong>r Auswertung <strong>de</strong>sFormatstr<strong>in</strong>gs ergeben sich Anzahl und Typen <strong>de</strong>r weiteren Argumente.Damit wird auch klar, was geschieht, wenn die Platzhalter(%d, %6u usw.) im Formatstr<strong>in</strong>g nicht mit <strong>de</strong>r Argumentenlisteübere<strong>in</strong>stimmen. Gibt es mehr Argumente als Platzhalter,wer<strong>de</strong>n sie nicht beachtet. Gibt es mehr Platzhalter als Argumente,wird irgen<strong>de</strong><strong>in</strong> un<strong>de</strong>f<strong>in</strong>ierter Speicher<strong>in</strong>halt gelesen, unterUmstän<strong>de</strong>n auch <strong>de</strong>r <strong>de</strong>m Programm zugewiesene Speicherbereichverlassen. Stimmen Platzhalter und Argumente im Typnicht übere<strong>in</strong>, wird <strong>de</strong>r Po<strong>in</strong>ter pvar falsch <strong>in</strong>krementiert, unddie Typumwandlung geht vermutlich auch daneben.Es gibt e<strong>in</strong>e Fallgrube bei <strong>de</strong>r Typangabe. Je nach Compilerwer<strong>de</strong>n die Typen char und short <strong>in</strong>tern als <strong>in</strong>t undfloat als double verarbeitet. In solchen Fällen muß <strong>de</strong>m Makrova_arg(pvar, type) <strong>de</strong>r <strong>in</strong>terne Typ mitgeteilt wer<strong>de</strong>n.Nachlesen o<strong>de</strong>r ausprobieren, am besten bei<strong>de</strong>s.1.4.6 Iterativer Aufruf e<strong>in</strong>er FunktionUnter e<strong>in</strong>er Iteration versteht man die Wie<strong>de</strong>rholung bestimmterProgrammschritte, wobei das Ergebnis e<strong>in</strong>es Schrittes alsE<strong>in</strong>gabe für die nächste Wie<strong>de</strong>rholung dient. Viele mathematischeNäherungsverfahren machen von Iterationen Gebrauch.Programmtechnisch führen Iterationen auf Schleifen. Entsprechendmuß e<strong>in</strong>e Bed<strong>in</strong>gung angegeben wer<strong>de</strong>n, die die Iterationbeen<strong>de</strong>t. Da auch bei e<strong>in</strong>em richtigen Programm e<strong>in</strong>e Iterationmanchmal aus mathematischen Grün<strong>de</strong>n nie zu e<strong>in</strong>em En<strong>de</strong>kommt, ist es zweckmäßig, e<strong>in</strong>en Test für solche Fälle e<strong>in</strong>zubauenwie <strong>in</strong> folgen<strong>de</strong>m Beispiel:/* Quadratwurzel, Halbierungsverfahren, 14.08.92 *//* Compileraufruf cc -o wurzel wurzel.c */#<strong>de</strong>f<strong>in</strong>e EPS 0.00001#<strong>de</strong>f<strong>in</strong>e MAX 100#<strong>in</strong>clu<strong>de</strong>


158 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>void exit();<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc,char *argv[]){<strong>in</strong>t i;double a, b, c, m;if (argc < 2) {puts("Radikand fehlt.");exit(-1);}/* Initialisierung */i = 0;sscanf(argv[1], "%lf", &c);sscanf(argv[1], "%lf", &c);a = 0;b = c + 1;/* Iteration */while (b - a > EPS) {m = (a + b) / 2;if (m * m - c MAX) {puts("Zuviele Iterationen! Ungenau!");break;}/* Ausgabe und En<strong>de</strong> */pr<strong>in</strong>tf("Die Wurzel aus %lf ist %lf\n", c, m);pr<strong>in</strong>tf("Anzahl <strong>de</strong>r Iterationen: %d\n", i);exit(0);}


1.4. FUNKTIONEN 159Quelle 1.54 : C-Programm zur iterativen Berechnung <strong>de</strong>r QuadratwurzelDie Funktion, die iterativ aufgerufen wird, ist die Mittelwertbildungvon a und b; es lohnt sich nicht, sie auch programmtechnischals selbständige Funktion zu <strong>de</strong>f<strong>in</strong>ieren, aber das kann <strong>in</strong>an<strong>de</strong>ren Aufgaben an<strong>de</strong>rs se<strong>in</strong>.1.4.7 Rekursiver Aufruf e<strong>in</strong>er FunktionBei e<strong>in</strong>er Rekursion ruft e<strong>in</strong>e Funktion sich selbst auf. Das istetwas schwierig vorzustellen und nicht <strong>in</strong> allen Programmiersprachenerlaubt. Die Nähe zum Zirkelschluß ist nicht geheuer.Es gibt aber Probleme, die ursprünglich rekursiv s<strong>in</strong>d undsich durch e<strong>in</strong>e Rekursion elegant programmieren lassen. E<strong>in</strong>eZirkel<strong>de</strong>f<strong>in</strong>ition ist e<strong>in</strong>e Def<strong>in</strong>ition e<strong>in</strong>es Begriffes, die diesenselbst <strong>in</strong> <strong>de</strong>r Def<strong>in</strong>ition enthält, damit es nicht sofort auffällt, gegebenenfallsum e<strong>in</strong>ige Ecken herum. E<strong>in</strong> Zirkelschluss ist e<strong>in</strong>eFolgerung, die Teile <strong>de</strong>r zu beweisen<strong>de</strong>n Aussage bereits zurVoraussetzung hat. Bei e<strong>in</strong>er Rekursion h<strong>in</strong>gegen• wie<strong>de</strong>rholt sich die Ausgangslage nie,• wird e<strong>in</strong>e Abbruchbed<strong>in</strong>gung nach endlich vielen Schrittenerfüllt, d. h. die Rekursionstiefe ist begrenzt.In <strong>de</strong>m Buch von ROBERT SEDGEWICK f<strong>in</strong><strong>de</strong>t sich Näheres zudiesem Thema, mit Programmbeispielen. Im ersten Band <strong>de</strong>r Informatikvon FRIEDRICH L. BAUER und GERHARD GOOS wirddie Rekursion allgeme<strong>in</strong>er abgehan<strong>de</strong>lt.Zwei Beispiele sollen die Rekursion veranschaulichen. Daserste Programm berechnet <strong>de</strong>n größten geme<strong>in</strong>samen Teiler(ggT) zweier ganzer Zahlen nach <strong>de</strong>m Algorithmus von EUKLID.Das zweite ermittelt rekursiv die Fakultät e<strong>in</strong>er Zahl, was manan<strong>de</strong>rs vielleicht e<strong>in</strong>facher erledigen könnte./* Groesster geme<strong>in</strong>samer Teiler, Euklid, rekursiv *//* Compileraufruf cc -o ggtr ggtr.c */#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ggt();<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc,char *argv[])


160 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>{<strong>in</strong>t x, y;sscanf(argv[1], "%d", &x); sscanf(argv[2], "%d", &y);pr<strong>in</strong>tf("Der GGT von %d und %d ist %d.\n", x, y, ggt(x, y));return 0;}/* Funktion ggt() */<strong>in</strong>t ggt(<strong>in</strong>t a,<strong>in</strong>t b){if (a == b) return a;else if (a > b) return(ggt(a - b, b));else return(ggt(a, b - a));}Quelle 1.55 : C-Programm Größter geme<strong>in</strong>samer Teiler (ggT)nach Euklid, rekursivIm folgen<strong>de</strong>n Programm ist außer <strong>de</strong>r Rekursivität die Verwendung<strong>de</strong>r Bed<strong>in</strong>gten Bewertung <strong>in</strong>teressant, die <strong>de</strong>n Co<strong>de</strong>verkürzt./* Rekursive Berechnung von Fakultaeten */#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t n;puts("\nWert e<strong>in</strong>geben, En<strong>de</strong> mit CTRL-D");while (scanf("%d", &n) != EOF)pr<strong>in</strong>tf("\n%d Fakultaet ist %d.\n\n", n, fak(n));return 0;}/* funktion fak() */<strong>in</strong>t fak(<strong>in</strong>t n){return(n


1.4. FUNKTIONEN 161Quelle 1.56 : C-Programm zur rekursiven Berechnung <strong>de</strong>r FakultätWeitere rekursiv lösbare Aufgaben s<strong>in</strong>d die Türme von Hanoiund Quicksort. Rekursive Probleme lassen sich auch iterativ lösen.Das kann sogar schneller gehen, aber die Eleganz bleibt auf<strong>de</strong>r Strecke.Da <strong>in</strong> C auch das Hauptprogramm ma<strong>in</strong>() e<strong>in</strong>e Funktion ist,die auf gleicher Stufe mit allen an<strong>de</strong>ren Funktionen steht, kannes sich selbst aufrufen:/* Experimentelles Programm mit Selbstaufruf von ma<strong>in</strong>() */#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){puts("Selbstaufruf von ma<strong>in</strong>()");ma<strong>in</strong>();return(13);}Quelle 1.57 : C-Programm, <strong>in</strong> <strong>de</strong>m ma<strong>in</strong>() sich selbst aufruftDas Programm wird von l<strong>in</strong>t(1) nicht beanstan<strong>de</strong>t, e<strong>in</strong>wandfreikompiliert und läuft, bis <strong>de</strong>r Speicher platzt, da die Rekursionstiefenicht begrenzt ist (Abbruch mit break). Allerd<strong>in</strong>gsist e<strong>in</strong> Selbstaufruf von ma<strong>in</strong>() ungebräuchlich.1.4.8 Assemblerrout<strong>in</strong>enAuf die Assemblerprogrammierung wur<strong>de</strong> <strong>in</strong> Abschnitt 1.1.4Programmiersprachen auf Seite 10 bereits e<strong>in</strong>gegangen. Da dasSchreiben von Programmen <strong>in</strong> Assembler mühsam ist und dieProgramme nicht portierbar s<strong>in</strong>d, läßt man nach Möglichkeit dieF<strong>in</strong>ger davon. Es kann jedoch zweckmäßig se<strong>in</strong>, e<strong>in</strong>fache, kurzeFunktionen auf Assembler umzustellen. E<strong>in</strong>mal kann man sounmittelbar auf die Hardware zugreifen, beispielsweise <strong>in</strong> Anwendungenzum Messen und Regeln, zum an<strong>de</strong>ren zur Beschleunigungoft wie<strong>de</strong>rholter Funktionen./* fakul.c Berechnung von Fakultaeten */


162 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>/* Die Grenze fuer END liegt <strong>in</strong> <strong>de</strong>r Segmentgroesse *//* bis 260 wer<strong>de</strong>n alle Werte <strong>in</strong> e<strong>in</strong>em Array gespeichert,darueber wird Wert fuer Wert berechnet und ausgegeben *//* Ziffern <strong>in</strong> Neunergruppen, nutzt long aus */#<strong>de</strong>f<strong>in</strong>e END 260#<strong>de</strong>f<strong>in</strong>e MAX 1023#<strong>de</strong>f<strong>in</strong>e DEF 16#<strong>de</strong>f<strong>in</strong>e GRP 58#<strong>de</strong>f<strong>in</strong>e GMX 245/* GRP muss <strong>in</strong> aadd.asm e<strong>in</strong>getragen wer<strong>de</strong>n *//* GMX muss <strong>in</strong> laadd.asm e<strong>in</strong>getragen wer<strong>de</strong>n */#<strong>in</strong>clu<strong>de</strong> unsigned long f[END + 1][GRP]; /* global */void add(unsigned long *, unsigned long *);void exit(<strong>in</strong>t);long time(long *);/* Assemblerfunktionen zur Beschleunigung &/extern void aadd(unsigned long *, unsigned long *);extern void lshift(unsigned long *);/* Hauptprogramm */<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[]){<strong>in</strong>t e, i, j, k, r, s, flag, en<strong>de</strong>, max = DEF;unsigned long x[GRP];unsigned long *z;long z1, z2, z3;/* Auswertung <strong>de</strong>r Kommandozeile */if (argc > 1) {sscanf(*(argv + 1), "%d", &max);max = (max < 0) ? -max : max;if (max > MAX) {pr<strong>in</strong>tf("\nZahl zu gross! Maximal %d\n", MAX);exit(1);}


1.4. FUNKTIONEN 163}en<strong>de</strong> = (max > END) ? END : max;time(&z1); /* Zeit holen *//* Rechnung */**f = (unsigned long)1;for (i = 1; i


164 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}}pr<strong>in</strong>tf("%09lu ", *(*(f + i) + j));/* falls wir weitermachen wollen, muessen wir das Arrayf[261][58] umfunktionieren <strong>in</strong> f[2][*].In f[0] steht vorige Fakultaet, <strong>in</strong> f[1] wird addiert. */if (max > END) {/* f[0] e<strong>in</strong>richten */e = GMX; /* kle<strong>in</strong>er 7296 */for (j = 0; j < e; j++)*(*f + j) = 0; /* f[0] nullsetzen */aadd(f[0], f[END]); /* vorige Fak. addieren *//* Rechnung wie gehabt */r = 0; s = e;for (i = END + 1; i


1.4. FUNKTIONEN 165}pr<strong>in</strong>tf("%09lu ", *(*(f + s) + j)}r = (r > 0) ? 0 : e; /* f[1] wird das naechste f[0s = (s > 0) ? 0 : e;}/* En<strong>de</strong> Weitermachen *//* Anzahl <strong>de</strong>r Stellen von max! */if (max > END) {en<strong>de</strong> = r; j = GMX - 1;}else {j = GRP - 1;}flag = 0;for (; j >= 0; j-) {if (!(*(*(f + en<strong>de</strong>) + j)) && !flag);elseif (!flag) {unsigned long z = 10;flag = 1;for (i = 1; i < 9; i++) {if (*(*(f + en<strong>de</strong>) + j) / z) {flag++;z *= 10;}elsebreak;}}elseflag += 9;}time(&z3); /* Zeit holen */pr<strong>in</strong>tf("\n\n\tZahl %4d ! hat %4d Stellen.\n", max, flag);if (max > END)pr<strong>in</strong>tf("\tRechnung+Ausgabe brauchten %4ld s.\n", z3 - z1else {


166 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}pr<strong>in</strong>tf("\tDie Rechnung brauchtepr<strong>in</strong>tf("\tDie Ausgabe brauchte%4ld s.\n", z2 - z1);%4ld s.\n", z3 - z2);return 0;}Quelle 1.58 : C-Programm zur Berechnung von FakultätenDas vorstehen<strong>de</strong> Beispiel mit Microsoft Quick C und QuickAssembler für <strong>de</strong>n IBM-PC bietet e<strong>in</strong>en e<strong>in</strong>fachen E<strong>in</strong>stieg <strong>in</strong> dieAssemblerprogrammierung, da das große Programm nach wievor <strong>in</strong> e<strong>in</strong>er höheren Sprache abgefaßt ist. Das Beispiel ist <strong>in</strong>e<strong>in</strong>er zweiten H<strong>in</strong>sicht <strong>in</strong>teressant. Auf e<strong>in</strong>er 32-Bit-Masch<strong>in</strong>eliegt die größte vorzeichenlose Ganzzahl etwas über 4 Milliar<strong>de</strong>n.Damit kommen wir nicht weit, <strong>de</strong>nn es ist bereits:13! = 6227020800 (1.3)Wir stellen unsere Ergebnisse dar durch e<strong>in</strong> Array von langenGanzzahlen, und zwar packen wir immer neun Dezimalstellen<strong>in</strong> e<strong>in</strong> Array-Element:unsigned long f[END + 1][GRP]Bei asymmetrischen Verschlüsselungsverfahren braucht mangroße Zahlen. Die Arithmetik zu diesem Datentyp müssen wirselbst schreiben. Dazu ersetzen wir die eigentlich bei <strong>de</strong>r Berechnungvon Fakultäten erfor<strong>de</strong>rliche Multiplikation durch dieAddition. Diese beschleunigen wir durch E<strong>in</strong>satz e<strong>in</strong>er Assemblerfunktionaadd():COMMENT +C-Funktion aadd() <strong>in</strong> MS-Assembler, die e<strong>in</strong>Array of unsigned long <strong>in</strong> e<strong>in</strong> zweites Arrayaddiert, Parameter Po<strong>in</strong>ter auf die Arrays.+.MODEL small,c.CODEgrp EQU 4 * 58 ; siehe C-Programmmilliar<strong>de</strong> DD 1000000000; fuer laadd() obige Zeile austauschen; grp EQU 4 * 245 ; siehe C-Programm


1.4. FUNKTIONEN 167aadd PROC USES SI, y:PTR DWORD, g:PTR DWORDsub cx,cxsub si,siclc; for-Schleife nachbil<strong>de</strong>nfor1:; aktuelles Element <strong>in</strong> <strong>de</strong>n Akku holen, long = 4 Bytes!mov bx,ymov ax,WORD PTR [bx+si][0]mov dx,WORD PTR [bx+si][2]; Uebertrag zu Akku addierenadd ax,cxadc dx,0; vorige Fakultaet zu Akku addieren, Uebertrag beachtenmov bx,gadd ax,WORD PTR [bx+si][0]adc dx,WORD PTR [bx+si][2]; Summe durch 10 hoch 9 dividieren, Quotient ergibt; Uebertrag <strong>in</strong>s naechste Element <strong>de</strong>s Arrays, Rest: ergibt aktuelles Element.; zweite for-Schleife:sub cx,cxfor2:cmp dx,WORD PTR milliar<strong>de</strong>[2]jl SHORT fertigsub ax,WORD PTR milliar<strong>de</strong>[0]sbb dx,WORD PTR milliar<strong>de</strong>[2]<strong>in</strong>c cxjmp SHORT for2fertig:; Rest zurueckschreiben <strong>in</strong> aktuelles Arraymov bx,ymov WORD PTR [bx+si][0],axmov WORD PTR [bx+si][2],dx; Schleifenzaehler um 4 (long!) erhoehenadd si,4; Ruecksprungbed<strong>in</strong>gungcmp si,grpje SHORT donejmp SHORT for1; En<strong>de</strong> <strong>de</strong>r Funktiondone:ret


168 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>aaddENDPENDQuelle 1.59 : Assemblerfunktion 1 zur Addition von Fel<strong>de</strong>rnDie Fakultäten wer<strong>de</strong>n berechnet, gespeichert und zumSchluß zusammen ausgegeben. So können wir die Rechenzeitvon <strong>de</strong>r Ausgabezeit trennen. Es zeigt sich, daß die Rechenzeitbei Ganzzahl-Arithmetik gegenüber <strong>de</strong>r Bildschirmausgabe ke<strong>in</strong>eRolle spielt.Auf diesem Weg kommen wir bis <strong>in</strong> die Gegend von 260!, dannist e<strong>in</strong> Speichersegement (64 KByte) unter PC-DOS voll. Wirkönnen nicht mehr alle Ergebnisse speichern, son<strong>de</strong>rn nur dievorangegangene und die laufen<strong>de</strong> Fakultät. Sowie e<strong>in</strong> Ergebnisvorliegt, wird es ausgegeben. Die Assemblerfunktion laadd()zur Addition unterschei<strong>de</strong>t sich <strong>in</strong> e<strong>in</strong>er Zeile am Anfang. Die imProgramm vorgesehene Grenze MAX = 1023 ist noch nicht diedurch das Speichersegment bestimmte Grenze, son<strong>de</strong>rn willkürlich.Irgendwann erheben sich Zweifel am S<strong>in</strong>n großer Zahlen.Selbst als Tapetenmuster wirken sie etwas e<strong>in</strong>tönig.1.4.9 Memo Funktionen• C-Programme s<strong>in</strong>d aus gleichberechtigten Funktionen aufgebaut.Zu diesen gehört auch ma<strong>in</strong>().• E<strong>in</strong>e Funktion übernimmt bei ihrem Aufruf e<strong>in</strong>en festgelegtenSatz von Parametern o<strong>de</strong>r Argumenten. Der Satzbeim Aufruf muß mit <strong>de</strong>m Satz bei <strong>de</strong>r Def<strong>in</strong>ition nachAnzahl, Typ und Reihenfolge übere<strong>in</strong>stimmen wie Steckerund Kupplung e<strong>in</strong>er elektrischen Steckverb<strong>in</strong>dung.• Bei <strong>de</strong>r Parameterübergabe by value arbeitet die Funktionmit Kopien <strong>de</strong>r übergebenen Parameter, kann also dieOrig<strong>in</strong>alwerte nicht verän<strong>de</strong>rn.• Bei <strong>de</strong>r Parameterübergabe by reference erfährt die Funktiondie Adressen (Po<strong>in</strong>ter) <strong>de</strong>r Orig<strong>in</strong>alwerte und kann dieseverän<strong>de</strong>rn. Das ist gefährlicher, aber manchmal gewollt.Beispiel: scanf().• Auch die Funktion ma<strong>in</strong>() kann Argumente übernehmen,und zwar aus <strong>de</strong>r Kommandozeile. Die Argumente stehen<strong>in</strong> e<strong>in</strong>em Array of Str<strong>in</strong>gs (Argumentvektor).


1.5. FUNKTIONS-BIBLIOTHEKEN 169• Es gibt auch Funktionen wie pr<strong>in</strong>tf(), die e<strong>in</strong>e von Aufrufzu Aufruf wechseln<strong>de</strong> Anzahl von Argumenten übernehmen.Der Mechanismus ist an e<strong>in</strong>ige Voraussetzungengebun<strong>de</strong>n.• E<strong>in</strong>e Funktion gibt ke<strong>in</strong>en o<strong>de</strong>r genau e<strong>in</strong>en Wert als Ergebnisan die aufrufen<strong>de</strong> Funktion zurück. Dieser Wertkann e<strong>in</strong> e<strong>in</strong> Po<strong>in</strong>ter se<strong>in</strong>.• In C darf e<strong>in</strong>e Funktion sich selbst aufrufen (rekursiverAufruf).• Assemblerfunktionen <strong>in</strong>nerhalb e<strong>in</strong>es C-Programms können<strong>de</strong>n Ablauf beschleunigen. E<strong>in</strong>facher wird das Programmdadurch nicht.1.4.10 Übung FunktionenJetzt verfügen Sie über die Kenntnisse, die zum Schreiben e<strong>in</strong>facherC-Programme notwendig s<strong>in</strong>d. Schreiben das Programmzur Weganalyse, aufbauend auf <strong>de</strong>r Aufgabenanalyse und <strong>de</strong>rDatenstruktur, die Sie bereits erarbeitet haben. Falls Sie sichan <strong>de</strong>n Vokabeltra<strong>in</strong>er wagen wollen, reduzieren Sie die Aufgabezunächst auf e<strong>in</strong> M<strong>in</strong>imum, sonst wer<strong>de</strong>n Sie nicht fertig damit.1.5 Funktions-Bibliotheken1.5.1 Zweck und AufbauE<strong>in</strong>e Funktion kann auf drei Wegen mit e<strong>in</strong>em C-Hauptprogramm ma<strong>in</strong>() verbun<strong>de</strong>n wer<strong>de</strong>n:• Die Funktion steht <strong>in</strong> <strong>de</strong>rselben Datei wie ma<strong>in</strong>() und wirddaher geme<strong>in</strong>sam kompiliert. Sie muss wie ma<strong>in</strong>() <strong>in</strong> Cgeschrieben se<strong>in</strong>, mehrsprachige Compiler gibt es nicht.• Die Funktion steht – unter Umstän<strong>de</strong>n mit weiteren Funktionen– <strong>in</strong> e<strong>in</strong>er eigenen Datei, das getrennt kompiliertund beim L<strong>in</strong>ken zu ma<strong>in</strong>() gebun<strong>de</strong>n wird. Dabei wer<strong>de</strong>nalle Funktionen dieser Datei zu ma<strong>in</strong>() gebun<strong>de</strong>n, ob siegebraucht wer<strong>de</strong>n o<strong>de</strong>r nicht. Wegen <strong>de</strong>r getrennten Compilierungdarf die Datei <strong>in</strong> e<strong>in</strong>er an<strong>de</strong>ren Programmierspra-


170 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>che geschrieben, muß aber für dieselbe Masch<strong>in</strong>e kompiliertse<strong>in</strong>.• Die getrennt kompilierte Funktion steht zusammen mitweiteren <strong>in</strong> e<strong>in</strong>er Bibliothek und wird beim L<strong>in</strong>ken zuma<strong>in</strong>() gebun<strong>de</strong>n. Dabei wählt <strong>de</strong>r L<strong>in</strong>ker nur die Funktionenaus <strong>de</strong>r Bibliothek aus, die <strong>in</strong> ma<strong>in</strong>() gebrauchtwer<strong>de</strong>n. Man kann also viele Funktionen <strong>in</strong> e<strong>in</strong>er Bibliothekzusammenfassen, ohne befürchten zu müssen, se<strong>in</strong>eProgramme mit Ballast zu befrachten. Die Bibliothek kannauf Quellfiles unterschiedlicher Programmiersprachen zurückgehen.Sie müssen nur für dasselbe System kompiliertwor<strong>de</strong>n se<strong>in</strong>; es macht ke<strong>in</strong>en S<strong>in</strong>n und ist auch nicht möglich,Funktionen für UNIX und PC-DOS <strong>in</strong> e<strong>in</strong>er Bibliothekzu vere<strong>in</strong>igen.Das Erzeugen e<strong>in</strong>er Bibliothek auf UNIX-Systemen wur<strong>de</strong>bereits im Abschnitt 1.2.6 Bibliotheken, Archive auf Seite 43 imRahmen <strong>de</strong>r Programmer’s Workbench erläutert. Im folgen<strong>de</strong>ngeht es um die Verwendung von Bibliotheken.1.5.2 Standardbibliothek1.5.2.1 ÜbersichtStandardfunktionen s<strong>in</strong>d die Funktionen, die als Standardbibliothekzusammen mit <strong>de</strong>m Compiler geliefert wer<strong>de</strong>n. Sies<strong>in</strong>d im strengen S<strong>in</strong>n nicht Bestandteil <strong>de</strong>r Programmiersprache– das be<strong>de</strong>utet, daß sie ersetzbar s<strong>in</strong>d – aber <strong>de</strong>r ANSI-Standard führt e<strong>in</strong>e m<strong>in</strong>imale Standardbibliothek auf. Ohne siekönnte man kaum e<strong>in</strong> Programm <strong>in</strong> C schreiben. Der Reichtum<strong>de</strong>r Standardbibliothek ist e<strong>in</strong>e Stärke von C; <strong>in</strong> ihr steckt vielArbeit, die an<strong>de</strong>re Programmierer vor und für uns erledigt haben.Die Systemaufrufe (Sektion 2) gehören dagegen nicht zurStandardbibliothek (Sektion 3), son<strong>de</strong>rn zum Betriebssystem.Und Shell-Kommandos s<strong>in</strong>d e<strong>in</strong>e Sache <strong>de</strong>r Shell (Sektion 1).Diese Unterscheidung spielt e<strong>in</strong>e Rolle, wenn Programme portiertwer<strong>de</strong>n. Soweit möglich s<strong>in</strong>d Standardfunktionen zu verwen<strong>de</strong>n,da sie Eigenheiten <strong>de</strong>s Systems ver<strong>de</strong>cken.Die mit <strong>de</strong>m C-Compiler e<strong>in</strong>es UNIX-Systems mitgelieferteStandardbibliothek wird im Referenz-Handbuch unter<strong>in</strong>tro(3) vorgestellt und umfaßt mehrere Teile:


1.5. FUNKTIONS-BIBLIOTHEKEN 171• die Standard-C-Bibliothek, meist gekoppelt mit <strong>de</strong>rStandard-Input-Output-Bibliothek, <strong>de</strong>n Netzfunktionenund <strong>de</strong>n Systemaufrufen (weil sie zusammen gebrauchtwer<strong>de</strong>n),• die mathematische Bibliothek,• gegebenenfalls e<strong>in</strong>e grafische Bibliothek,• gegebenenfalls e<strong>in</strong>e Bibliothek mit Funktionen zum Messenund Regeln,• gegebenenfalls Datenbankfunktionen und weitere Spezialitäten.Außer Funktionen enthält sie Inclu<strong>de</strong>-Dateien mit Def<strong>in</strong>itionenund Makros, die von <strong>de</strong>n Funktionen benötigt wer<strong>de</strong>n,im UNIX-Datei-System aber <strong>in</strong> e<strong>in</strong>em an<strong>de</strong>ren Verzeichnis(/usr/<strong>in</strong>clu<strong>de</strong>) liegen als die Funktions-Bibliotheken (/libund /usr/lib).1.5.2.2 Standard-C-BibliothekDie Standard-C-Bibliothek /lib/libc.a wird vom C-Compilertreiber cc(1) e<strong>in</strong>es UNIX-Systems aufgerufen undbraucht daher nicht als Option mitgegeben zu wer<strong>de</strong>n. Füre<strong>in</strong>en getrennten L<strong>in</strong>ker-Aufruf lautet die Option -lc. Mit <strong>de</strong>mKommando:ar -t /lib/libc.aschauen Sie sich das Inhaltsverzeichnis <strong>de</strong>r Bibliothek an. Außerbekannten Funktionen wie pr<strong>in</strong>tf() und Systemaufrufen wiestat(2) wer<strong>de</strong>n Sie viele Unbekannte treffen. Auskunft überdiese erhalten Sie mittels <strong>de</strong>r man-Seiten, beispielsweise:man ruserokman <strong>in</strong>squesofern die Funktionen zum Gebrauch durch Programmierer undnicht etwa nur für <strong>in</strong>terne Zwecke bestimmt s<strong>in</strong>d.


172 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Input/Output Für die E<strong>in</strong>- und Ausgabe stehen <strong>in</strong> C ke<strong>in</strong>eOperatoren zur Verfügung, son<strong>de</strong>rn nur die Systemaufrufe <strong>de</strong>sBetriebssystems (unter UNIX open(2), write(2), read(2)usw.) und die Standardfunktionen aus <strong>de</strong>r zum Compiler gehören<strong>de</strong>nBibliothek. In <strong>de</strong>r Regel s<strong>in</strong>d die Funktionen vorzuziehen,da die Programme dann leichter auf an<strong>de</strong>re Systeme übertragenwer<strong>de</strong>n können. Die Eigenheiten <strong>de</strong>r Systeme wer<strong>de</strong>ndurch die Bibliothek ver<strong>de</strong>ckt. In diesem Fall ist im Programmkopfstets die Inclu<strong>de</strong>-Datei stdio.h e<strong>in</strong>zub<strong>in</strong><strong>de</strong>n:#<strong>in</strong>clu<strong>de</strong> Diese Zeile ist fast <strong>in</strong> je<strong>de</strong>m C-Programm zu f<strong>in</strong><strong>de</strong>n. In <strong>de</strong>r Standardbibliothekstehen rund 40 Funktionen zur E<strong>in</strong>- und Ausgabebereit, von <strong>de</strong>nen die bekanntesten pr<strong>in</strong>tf(3) zur formatiertenAusgabe nach stdout und scanf(3) zur formatierten E<strong>in</strong>gabevon std<strong>in</strong> s<strong>in</strong>d.Str<strong>in</strong>gfunktionen Str<strong>in</strong>gs s<strong>in</strong>d <strong>in</strong> C Arrays of Characters, abgeschlossenmit <strong>de</strong>m ASCII-Zeichen Nr. 0, also nichts Beson<strong>de</strong>res.Trotz<strong>de</strong>m machen sie – wie <strong>in</strong> vielen Programmiersprachen– Schwierigkeiten, wenn man ihre Syntax nicht beachtet. In<strong>de</strong>r Standard-C-Bibliothek steht e<strong>in</strong>e reiche Auswahl von Str<strong>in</strong>gfunktionenbereit. Gewarnt wird vor <strong>de</strong>r Funktion gets(3), diee<strong>in</strong>en Str<strong>in</strong>g von std<strong>in</strong> <strong>in</strong> e<strong>in</strong> Array e<strong>in</strong>liest und dabei e<strong>in</strong>enÜberlauf verursachen kann. Grundsätzlich soll man beim Arbeitenmit Str<strong>in</strong>gs <strong>de</strong>n Fall berücksichtigen, dass e<strong>in</strong> Str<strong>in</strong>g gelegentlichlänger ist als <strong>de</strong>r Puffer, <strong>in</strong> <strong>de</strong>n er geschrieben wer<strong>de</strong>nsoll.Da e<strong>in</strong> Str<strong>in</strong>g – wie je<strong>de</strong>s Array – ke<strong>in</strong>en Wert hat, kanner nicht per Zuweisung e<strong>in</strong>er Str<strong>in</strong>gvariablen zugewiesen wer<strong>de</strong>n.Man muß vielmehr mit <strong>de</strong>n Standard-Str<strong>in</strong>gfunktionenarbeiten o<strong>de</strong>r sich selbst um die e<strong>in</strong>zelnen Elemente <strong>de</strong>s Arrayskümmern. Die Str<strong>in</strong>gfunktionen erwarten die Inclu<strong>de</strong>-Dateistr<strong>in</strong>g.h. Hier e<strong>in</strong> kurzes C-Programm zur Str<strong>in</strong>gmanipulationmittels Systemaufrufen und Standardfunktionen:/* Programm fuer Str<strong>in</strong>gmanipulation */#<strong>de</strong>f<strong>in</strong>e TEXT "textfile"


1.5. FUNKTIONS-BIBLIOTHEKEN 173#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> char buffer[80] = "Dies ist e<strong>in</strong> langer Teststr<strong>in</strong>g. Hallo!"<strong>in</strong>t ma<strong>in</strong>(){char x, zeile[80];<strong>in</strong>t i;<strong>in</strong>t fil<strong>de</strong>s;FILE * fp;/* Systemaufrufe und File<strong>de</strong>skriptoren */fil<strong>de</strong>s = open(TEXT, O RDWR);if (fil<strong>de</strong>s == -1)puts("open schiefgegangen.");write(fil<strong>de</strong>s, buffer, 20);lseek(fil<strong>de</strong>s, (long)0, SEEK SET);read(fil<strong>de</strong>s, zeile, 12);write(1, zeile, 12);close(fil<strong>de</strong>s);/* Standardfunktionen und Filepo<strong>in</strong>ter */fp = fopen(TEXT, "w");for (i = 0; i < 30; i++)fputc(buffer[i], fp);fclose(fp);fp = fopen(TEXT, "r");for (i = 0; i < 30; i++)zeile[i] = fgetc(fp);putchar(’\n’);for (i = 0; i < 30; i++)putchar(zeile[i]);/* Str<strong>in</strong>gfunktionen */strcpy(zeile, buffer);pr<strong>in</strong>tf("\n%s", zeile);putstf("\n\nBitte e<strong>in</strong>e Zeile e<strong>in</strong>geben:");gets(zeile);puts(zeile);


174 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}strcat(zeile, " Prima!");puts(zeile);pr<strong>in</strong>tf(zeile);Quelle 1.60 : C-Programm zur Str<strong>in</strong>gverarbeitungInternet-Funktionen E<strong>in</strong>e Übersicht über diese Funktionenf<strong>in</strong><strong>de</strong>t sich <strong>in</strong> <strong>in</strong>tro(3N). Beispiele s<strong>in</strong>d Funktionen zur Verarbeitungvon Netzadressen, Protokolle<strong>in</strong>trägen, Remote ProcedureCalls, zum Mounten ferner Datei-Systeme, zur Verwaltungvon Benutzern und Passwörtern im Netz. Geht über <strong>de</strong>n Rahmendieses Textes h<strong>in</strong>aus. Falls Sie sich e<strong>in</strong> eigenes Programmtelnet o<strong>de</strong>r ftp schreiben wollten, müßten Sie hier tiefer e<strong>in</strong>steigen.1.5.2.3 Standard-Mathematik-BibliothekDie Standard-Mathematik-Bibliothek wird vom C-Compilertreiber nicht automatisch aufgerufen – an<strong>de</strong>rs als<strong>in</strong> FORTRAN. Für C ist die Option -lm h<strong>in</strong>zuzufügen:cc -o myprogram myprogram.c -lmFerner muß im Programmkopf die Zeile#<strong>in</strong>clu<strong>de</strong> stehen. Dann verfügt man über Logarithmus, Wurzel, Potenz,trigonometrische und hyperbolische Funktionen. Weiteres siehemath(5).Eigentlich sollte man bei diesen Funktionen <strong>de</strong>n zugrun<strong>de</strong>liegen<strong>de</strong>n Algorithmus und se<strong>in</strong>e Programmierung kennen, daje<strong>de</strong>s numerische Verfahren und erst recht se<strong>in</strong>e Umsetzung <strong>in</strong>e<strong>in</strong> Programm Grenzen haben, aber das Referenz-Handbuch beschränktsich unter trig(3) usw. auf die Syntax <strong>de</strong>r Funktionen.E<strong>in</strong> Beispiel für die Verwendung <strong>de</strong>r mathematischenBibliothek:/* Potenz x hoch y; mathematische Funktionen; 22.12.92 *//* zu compilieren mit cc -o potenz potenz.c -lm *//* Aufruf: potenz x y */


1.5. FUNKTIONS-BIBLIOTHEKEN 175#<strong>de</strong>f<strong>in</strong>e EPSILON 0.00001#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> double pow(), floor();<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc,char *argv[]){double x, y, z;if (argc < 3) {puts("Zuwenig Argumente");return(-1);}/* Umwandlung Kommandozeilenargumente */sscanf(argv[1], "%lf", &x);sscanf(argv[2], "%lf", &y);/* Aufruf Funktionen pow(), floor(), Sektion 3M *//* wegen Fallunterscheidungen nachlesen! */if ((x < 0 ? -x : x) < EPSILON) {if (y > 0) x = 0;else {puts("Bei x = 0 muss y positiv se<strong>in</strong>.");return(-1);}}else {if (x < 0) y = floor(y);}z = pow(x, y);/* Ausgabe */pr<strong>in</strong>tf("%lf hoch %lf = %lf\n", x, y, z);return 0;}Quelle 1.61 : C-Programm mit mathematischen Funktionen


176 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Der l<strong>in</strong>t(1) gibt bei diesem Programm e<strong>in</strong>e längere Listevon Warnungen aus, die daher rühren, daß <strong>in</strong> vieleFunktionen <strong>de</strong>klariert wer<strong>de</strong>n, die im Programm nicht auftauchen.Das geht aber <strong>in</strong> Ordnung.1.5.2.4 Standard-Grafik-BibliothekZu manchen Compilern gehört auch e<strong>in</strong>e Sammlung von Grafikfunktionen.Da es hierfür noch ke<strong>in</strong>en Standard gibt undGrafik eng an die Hardware gebun<strong>de</strong>n ist, verzichten wir aufe<strong>in</strong>e Darstellung. Auf e<strong>in</strong>er UNIX-Anlage f<strong>in</strong><strong>de</strong>t man sie <strong>in</strong>/usr/lib/plot. Die Bibliothek enthält Funktionen zum Setzenvon Punkten, Ziehen von L<strong>in</strong>ien, zur Umwandlung von Koord<strong>in</strong>atenund ähnliche D<strong>in</strong>ge. Lei<strong>de</strong>r nicht standardisiert, sonstgäbe es nicht Starbase, GKS, OpenGL, PHIGS, Uniras ...1.5.2.5 Weitere Teile <strong>de</strong>r StandardbibliothekDie nicht zur Standard-C-Bibliothek gehören<strong>de</strong>n curses(3)-Funktionen aus /usr/lib/libcurses.a ermöglichen die weitergehen<strong>de</strong>Gestaltung e<strong>in</strong>es alphanumerischen Bildschirms. Indiesem Fall ist die curses(3)-Bibliothek beim Compileraufrufzu nennen:cc .... -lcursesVergißt man die Nennung, weiß <strong>de</strong>r Compiler mit <strong>de</strong>n Namen<strong>de</strong>r curses(3)-Funktionen nichts anzufangen und mel<strong>de</strong>t sichmit <strong>de</strong>r Fehleranzeige unsatisfied symbols.Bei Verwendung von curses(3)-Funktionen ist die Inclu<strong>de</strong>-Datei curses.h <strong>in</strong> das Programm aufzunehmen, das stdio.he<strong>in</strong>schließt.1.5.3 Xlib, Xt und Xm (X W<strong>in</strong>dow System)Programme, die von <strong>de</strong>m X W<strong>in</strong>dow System Gebrauch machenwollen, greifen auf unterster Ebene auf Funktionen <strong>de</strong>r Xlib-Bibliothek zurück. Die Xlib stellt für je<strong>de</strong> Möglichkeit <strong>de</strong>s X-Protokolls e<strong>in</strong>e C-Funktion bereit; sie ist die Schnittstelle zwischenC-Programmen und <strong>de</strong>m X-Protokoll.


1.5. FUNKTIONS-BIBLIOTHEKEN 177Auf nächsthöherer Ebene wer<strong>de</strong>n Funktionen e<strong>in</strong>er Toolboxwie <strong>de</strong>r Xt-Bibliothek <strong>de</strong>f<strong>in</strong>iert, die ihrerseits auf <strong>de</strong>r Xlib aufsetzt.Die Xt-Funktionen wer<strong>de</strong>n auch als Intr<strong>in</strong>sics bezeichnet.Sie kennen z. B. Widgets, das s<strong>in</strong>d W<strong>in</strong>dow Gadgets 32 o<strong>de</strong>r Objekte(im S<strong>in</strong>ne von <strong>C++</strong>) <strong>de</strong>s Client-Programms. Zu e<strong>in</strong>em Widgetgehören se<strong>in</strong> Fenster, se<strong>in</strong> Aussehen (look), se<strong>in</strong> Verhalten(feel) und e<strong>in</strong> Satz von Metho<strong>de</strong>n, die se<strong>in</strong> Verhalten realisieren.E<strong>in</strong> Menü o<strong>de</strong>r e<strong>in</strong> anklickbarer Druckknopf ist e<strong>in</strong> Widget.Die dritte Schicht bil<strong>de</strong>n Bibliotheken wie <strong>de</strong>r Motif ToolkitXm, <strong>de</strong>r e<strong>in</strong>e Menge nach e<strong>in</strong>heitlichen Regeln gebauter Widgetszur Verfügung stellt. Während Xt nur abstrakte Fensterund Menus kennt, legt Xm fest, wie e<strong>in</strong> (Motif-)Fenster o<strong>de</strong>r -Menü aussieht und wie es sich verhält. Während <strong>de</strong>r Quellco<strong>de</strong>von Xlib und Xt veröffentlicht ist, kostet die Xm e<strong>in</strong>e Kle<strong>in</strong>igkeit.E<strong>in</strong> Programmierer versucht immer, mit <strong>de</strong>r höchsten Bibliothekzu arbeiten, weil er sich dabei am wenigsten um E<strong>in</strong>zelheiten zukümmern braucht.1.5.4 NAG-BibliothekDie NAG-Bibliothek <strong>de</strong>r Numerical Algorithms Group, Oxfordsoll hier als e<strong>in</strong> Beispiel für e<strong>in</strong>e umfangreiche kommerzielleBibliothek stehen, die bei vielen numerischen Aufgaben dieArbeit erleichtert. Die FORTRAN-Bibliothek umfaßt etwa 1200Subrout<strong>in</strong>en, die C-Bibliothek etwa 250 Funktionen. Sie stammenaus folgen<strong>de</strong>n Gebieten:• Nullstellen, Extremwerte,• Differential- und Integralgleichungen,• Fourier-Transformation,• L<strong>in</strong>eare Algebra,• nichtl<strong>in</strong>eare Gleichungen,• Statistik,• Näherungen, Interpolation, Ausgleichsrechnung,• Zufallszahlen usw.Näheres unter http://www.nag.co.uk:80/numeric.html.32 E<strong>in</strong> Gadget ist laut Wörterbuch e<strong>in</strong> geniales D<strong>in</strong>gsbums.


178 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.5.5 Eigene BibliothekenWir haben bereits <strong>in</strong> Abschnitt 1.2.6 Bibliotheken, Archive aufSeite 43 gelernt, e<strong>in</strong>e eigene Programmbibliothek mittels <strong>de</strong>sUNIX-Kommandos ar(1) herzustellen. Zunächst macht es Arbeit,se<strong>in</strong>e Programmierergebnisse <strong>in</strong> e<strong>in</strong>e Bibliothek e<strong>in</strong>zuordnen,aber wenn man e<strong>in</strong>mal e<strong>in</strong>en Grundstock hat, zahlt es sichaus.1.5.6 Speichermo<strong>de</strong>lle (PC-DOS)Unter UNIX gibt es ke<strong>in</strong>e Speichermo<strong>de</strong>lle, <strong>in</strong>folge<strong>de</strong>ssen auchnur e<strong>in</strong>e Standardbibliothek. Unter PC-DOS h<strong>in</strong>gegen ist dieSpeichersegmentierung zu beachten, d. h. die Unterteilung <strong>de</strong>sArbeitsspeichers <strong>in</strong> Segmente zu je 64 kByte, e<strong>in</strong> lästiges Überbleibselaus uralten Zeiten. Die Adressierung <strong>de</strong>r Speicherplätzeist unterschiedlich, je nach<strong>de</strong>m ob man sich nur <strong>in</strong>nerhalb e<strong>in</strong>esSegmentes o<strong>de</strong>r im ganzen Arbeitsspeicher bewegt. Für je<strong>de</strong>sSpeichermo<strong>de</strong>ll ist e<strong>in</strong>e eigene Standardbibliothek vorhan<strong>de</strong>n.Das Speichermo<strong>de</strong>ll wird gewählt durch:• die Angabe e<strong>in</strong>er Compiler-Option o<strong>de</strong>r• die Schlüsselwörter near, far o<strong>de</strong>r huge im C-Programm(was unter UNIX-C zu e<strong>in</strong>em Fehler führt)Wird ke<strong>in</strong>e <strong>de</strong>r bei<strong>de</strong>n Möglichkeiten genutzt, nimmt <strong>de</strong>r Compilere<strong>in</strong>en Default an, MS-Quick-C (qcl) beispielsweise das Mo<strong>de</strong>llsmall.Das Mo<strong>de</strong>ll t<strong>in</strong>y (nicht von allen Compilern unterstützt)packt Co<strong>de</strong>, Daten und Stack <strong>in</strong> e<strong>in</strong> Segment; für die Adressen(Po<strong>in</strong>ter) reichen 2 Bytes. Das gibt die schnellsten Programme,aber h<strong>in</strong>sichtlich <strong>de</strong>s Umfangs von Programm und Daten ist manbeschränkt.Das Mo<strong>de</strong>ll small packt Co<strong>de</strong> und Daten <strong>in</strong> je e<strong>in</strong> Segmentvon 64 kByte. Damit lassen sich viele Aufgaben aus <strong>de</strong>r PC-DOS-Welt bewältigen.Das Mo<strong>de</strong>ll medium stellt e<strong>in</strong> Segment für Daten und mehrereSegmente für Programmco<strong>de</strong> zur Verfügung, bis zur Grenze<strong>de</strong>s freien Arbeitsspeichers. Typische Anwendungen s<strong>in</strong>d längereProgramme mit wenigen Daten.


1.5. FUNKTIONS-BIBLIOTHEKEN 179Das Mo<strong>de</strong>ll compact verhält sich umgekehrt wie medium: e<strong>in</strong>Segment für <strong>de</strong>n Co<strong>de</strong>, mehrere Segmente für die Daten. Geeignetfür kurze Programme mit vielen Daten. E<strong>in</strong> e<strong>in</strong>zelnes Datenelement– e<strong>in</strong> Array beispielsweise – darf nicht größer als e<strong>in</strong>Segment se<strong>in</strong>.Das Mo<strong>de</strong>ll large läßt jeweils mehrere Segmente für Co<strong>de</strong>und Daten zu, wobei wie<strong>de</strong>r e<strong>in</strong> e<strong>in</strong>zelnes Datenelement nichtgrößer als e<strong>in</strong> Segment se<strong>in</strong> darf.Das Mo<strong>de</strong>ll huge schließlich hebt auch diese letzte Beschränkungauf, aber die Beschränkung auf die Größe <strong>de</strong>s freien Arbeitsspeichersbleibt, PC-DOS schwoppt nicht.Die Schlüsselwörter near, far und huge <strong>in</strong> Verb<strong>in</strong>dung mitPo<strong>in</strong>tern o<strong>de</strong>r Funktionen haben Vorrang vor <strong>de</strong>m vom Compilerbenutzten Speichermo<strong>de</strong>ll. Bei near s<strong>in</strong>d alle Adressen 16 Bitslang, bei far s<strong>in</strong>d die Adressen 32 Bits lang, die Po<strong>in</strong>terarithmetikgeht jedoch von 16 Bits aus, und bei huge schließlich läuftalles mit 32 Bits und entsprechend langsam ab. Falls Ihnen daszu kompliziert ersche<strong>in</strong>t, steigen Sie e<strong>in</strong>fach um auf UNIX.1.5.7 Memo Bibliotheken• E<strong>in</strong>e Bibliothek vere<strong>in</strong>t e<strong>in</strong>e Menge von Funktionen <strong>in</strong> e<strong>in</strong>ere<strong>in</strong>zigen Datei.• E<strong>in</strong>e Bibliothek hat nichts mit Verschlüsseln o<strong>de</strong>r Komprimierenzu tun.• Beim E<strong>in</strong>b<strong>in</strong><strong>de</strong>n e<strong>in</strong>er Bibliothek <strong>in</strong> <strong>de</strong>n Kompiliervorgangwer<strong>de</strong>n genau die benötigten Funktionen ausgewählt und<strong>in</strong>s Programm e<strong>in</strong>gebun<strong>de</strong>n.• Es gibt Standardbibliotheken, die zum Compiler gehörenund von diesem automatisch herangezogen wer<strong>de</strong>n.• Weiter gibt es Standardbibliotheken, die zum Compiler gehören,aber eigens über e<strong>in</strong>e Option herangezogen wer<strong>de</strong>nmüssen. Hierzu zählt die C-Standard-Mathematik-Bibliothek, die die Option -lm beim Compiler-Aufruf erfor<strong>de</strong>rt.• Auf <strong>de</strong>m Markt o<strong>de</strong>r im Netz f<strong>in</strong><strong>de</strong>t sich e<strong>in</strong>e Vielzahl vonBibliotheken, beispielsweise für numerische Aufgaben o<strong>de</strong>rdas X W<strong>in</strong>dow System.


180 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>• Man kann auch eigene Funktionen <strong>in</strong> Privatbibliothekenzusammenfassen. Das lohnt sich, wenn man längere Zeitfür e<strong>in</strong> bestimmtes Thema programmiert.1.5.8 Übung BibliothekenFassen Sie die Funktionen <strong>de</strong>s Weganalyse-Projektes außerma<strong>in</strong>() <strong>in</strong> e<strong>in</strong>er Privatbibliothek zusammen und b<strong>in</strong><strong>de</strong>n sie diesebeim Kompiliervorgang dazu.1.6 Klassen1.6.1 Warum C mit Klassen?Objektorientiert o<strong>de</strong>r prozedural ist nicht die Programmiersprache,son<strong>de</strong>rn die Aufgabenanalyse. Sie führt auf Programmbauste<strong>in</strong>e(Module), die entwe<strong>de</strong>r Objekte o<strong>de</strong>r Prozeduren (Funktionen,Prozeduren, Subrout<strong>in</strong>en) s<strong>in</strong>d. Erst an zweiter Stellekommen dann die Programmiersprachen, die die e<strong>in</strong>e o<strong>de</strong>r an<strong>de</strong>reDenkweise unterstützen. Man kann mit objektorientiertenSprachen prozedural aufgebaute Programme schreiben undmit prozeduralen Sprachen objektorientierte Programme. Da <strong>de</strong>rAusgangspunkt die Aufgabenanalyse ist, macht sich die Objektorientierungbei kle<strong>in</strong>en Programmen (wo es nichts zu analysierengibt) nicht bemerkbar. <strong>C++</strong> und Objective-C wur<strong>de</strong>n entwickelt,um• e<strong>in</strong> besseres C zu se<strong>in</strong> (dasselbe Ziel wie ANSI-C),• die Datenabstraktion zu unterstützen,• das objektorientierte Programmieren zu unterstützen.Als erstes e<strong>in</strong> Hallo-Programm <strong>in</strong> <strong>C++</strong> (mit Objektorientierungund Klassen ist da noch nichts zu machen):/* Hallo, Welt; <strong>in</strong> <strong>C++</strong> */#<strong>in</strong>clu<strong>de</strong> // anstelle stdio.h<strong>in</strong>t ma<strong>in</strong>(){char v[20];


1.6. KLASSEN 181cout « "Bitte Vornamen e<strong>in</strong>geben: ";c<strong>in</strong> » v;cout « "Hallo, " « v « ’\n’;return 0;}Quelle 1.62 : <strong>C++</strong>-Programm Hallo, WeltE<strong>in</strong>e zweite Art <strong>de</strong>s Kommentars (Zeilenkommentar) ist h<strong>in</strong>zugekommen.Der Operator > schreibt se<strong>in</strong> erstes Argument, <strong>de</strong>n Standard InputStream, auf das zweite, <strong>de</strong>n Str<strong>in</strong>g v. Das Stream-Konzeptzur E<strong>in</strong>- und Ausgabe ist flexibler als das herkömmliche Datei-Konzept; für <strong>de</strong>n Programmierer ist die an<strong>de</strong>re Syntax wichtig(beachte: ke<strong>in</strong> Formatstr<strong>in</strong>g! Der Operator weiß aufgrund <strong>de</strong>rTypen, was er vor sich hat). In <strong>C++</strong> gibt es e<strong>in</strong>e Vielzahl solcherVerbesserungen o<strong>de</strong>r Erweiterungen von C, aber sie s<strong>in</strong>d nichtsgrundsätzlich Neues; sie erfor<strong>de</strong>rn ke<strong>in</strong> Um<strong>de</strong>nken, son<strong>de</strong>rn nurdas Lesen <strong>de</strong>s Referenzmaterials.Obiges Programm hallo.cpp ist mit <strong>de</strong>m GNU gcc kompiliert96 kB groß. E<strong>in</strong> Assemblerprogramm, das dasselbe tut, belegt120 Bytes. Die Speicherhersteller profitieren mit Sicherheitvon <strong>de</strong>r Objektorientierung.1.6.2 Datenabstraktion, KlassenbegriffIn C ebenso wie <strong>in</strong> FORTRAN o<strong>de</strong>r PASCAL beschreibt e<strong>in</strong> Datentype<strong>in</strong>e Menge von Werten samt <strong>de</strong>n zugehörigen Operationen.Die Datentypen s<strong>in</strong>d durch <strong>de</strong>n Compiler festgelegt, <strong>de</strong>r Benutzerkann ke<strong>in</strong>e neuen Datentypen <strong>de</strong>f<strong>in</strong>ieren.E<strong>in</strong> abstrakter Datentyp ist e<strong>in</strong> vom Benutzer <strong>de</strong>f<strong>in</strong>ierterTyp, <strong>de</strong>ssen Schnittstelle (Interface, Außenseite, Verb<strong>in</strong>dungzum übrigen Programm) von se<strong>in</strong>er Implementierung (Implementation,<strong>in</strong>terne Programmierung, Innenleben) getrennt ist,e<strong>in</strong>e Black Box mit bestimmten nach außen sichtbaren Eigenschaften.Klassen s<strong>in</strong>d <strong>in</strong> e<strong>in</strong>er Programmiersprache formulierteBeschreibungen abstrakter Datentypen. Objekte s<strong>in</strong>d Vertreter(Exemplare, Instanzen, Verwirklichungen) von Klassen. C-Typen und <strong>C++</strong>-Klassen sowie C-Variable und <strong>C++</strong>-Objekte ent-


182 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>sprechen sich. Aus Klassen lassen sich untergeordnete Klassenableiten. E<strong>in</strong>e Klasse o<strong>de</strong>r e<strong>in</strong> Objekt enthält Daten (data member)und Operationen auf diesen Daten. Die Operationen, die <strong>in</strong><strong>de</strong>n Klassen o<strong>de</strong>r Objekten verwirklicht s<strong>in</strong>d, heißen Metho<strong>de</strong>n(member function, method). Objekte verkehren untere<strong>in</strong>an<strong>de</strong>rmittels Botschaften. E<strong>in</strong>e Botschaft (message, member functioncall) ist die Auffor<strong>de</strong>rung an e<strong>in</strong> Objekt, e<strong>in</strong>e se<strong>in</strong>er Metho<strong>de</strong>nauszuführen, vergleichbar e<strong>in</strong>em Funktionsaufruf <strong>in</strong> C.Beispielsweise können wir e<strong>in</strong>e Klasse Komplexe Zahl <strong>de</strong>f<strong>in</strong>ieren,die als Daten zwei reelle Zahlenwerte (Realteil und Imag<strong>in</strong>rrteil)sowie als Metho<strong>de</strong>n die Grundrechenarten für komplexeZahlen enthält:Klasse KOMPLEX{Daten: double realteil, imag<strong>in</strong>aerteil;Metho<strong>de</strong>n:KOMPLEX Addiere(a: KOMPLEX, b: KOMPLEX);KOMPLEX Subtrahiere(a: KOMPLEX, b:KOMPLEX);KOMPLEX Multipliziere(a: KOMPLEX, b: KOMPLEX);KOMPLEX Dividiere(a: KOMPLEX, b: KOMPLEX);}Mitglie<strong>de</strong>r (Daten, Metho<strong>de</strong>n) s<strong>in</strong>d öffentlich (public) o<strong>de</strong>r privat.Public Members s<strong>in</strong>d vom übrigen Programm her zugänglich,sie bil<strong>de</strong>n die Schnittstelle <strong>de</strong>r Klasse und ihrer Objekte zurUmwelt. Private Members s<strong>in</strong>d nur <strong>de</strong>n Metho<strong>de</strong>n <strong>de</strong>r Klassezugänglich. Public und private wer<strong>de</strong>n als Member AccessSpecifier bezeichnet. Meist s<strong>in</strong>d die Daten privat, die Metho<strong>de</strong>nteils privat, teils öffentlich. M<strong>in</strong><strong>de</strong>stens e<strong>in</strong>e Metho<strong>de</strong> mußöffentlich se<strong>in</strong> (warum?). E<strong>in</strong>e beson<strong>de</strong>re Metho<strong>de</strong> - mit <strong>de</strong>mselbenNamen wie die Klasse - ist <strong>de</strong>r Constructor, <strong>de</strong>r zur Initialisierungdient. Diese Metho<strong>de</strong> wird automatisch aufgerufen,wenn e<strong>in</strong> Objekt <strong>de</strong>r Klasse erzeugt wird. E<strong>in</strong> Constructor kannpublic, protected o<strong>de</strong>r private se<strong>in</strong>; er hat niemals e<strong>in</strong>en Rückgabewerte<strong>in</strong>es bestimmten Typs, auch nicht <strong>de</strong>s Typs void.Nun e<strong>in</strong> funktionsfähiges (wenn auch simples) Beispiel. Esrechnet die Zeiten von UTC nach MEZ um:/* mez.cpp, Beispiel fuer <strong>de</strong>n Gebrauch e<strong>in</strong>er Klasse<strong>in</strong> Anlehnung an Deitel + Deitel, S. 601 */


1.6. KLASSEN 183#<strong>in</strong>clu<strong>de</strong> class TIME {public:TIME();void Settime(<strong>in</strong>t, <strong>in</strong>t);void Gettime();void Pr<strong>in</strong>tmez();// fuer E<strong>in</strong>- und Ausgabe// Def<strong>in</strong>ition e<strong>in</strong>er Klasse// nach aussen sichtbar,// Metho<strong>de</strong>n// Default Constructor,// Initialisierung// h, m <strong>in</strong> UTC setzen// UTC e<strong>in</strong>lesen von std<strong>in</strong>// MEZ ausgebenprivate:// nicht nach aussen sichtba// Daten<strong>in</strong>t hour; // 0 - 23<strong>in</strong>t m<strong>in</strong>ute; // 0 - 59<strong>in</strong>t h<strong>in</strong>, m<strong>in</strong>;// E<strong>in</strong>gabe von std<strong>in</strong>};// Def<strong>in</strong>ition <strong>de</strong>r Metho<strong>de</strong>n// Initialisierung mittels ConstructorTIME::TIME() { hour = m<strong>in</strong>ute = 0; }// Zeit <strong>in</strong> UTC e<strong>in</strong>geben, pruefenvoid TIME::Settime(<strong>in</strong>t h, <strong>in</strong>t m){hour = (h >= 0 && h < 23) ? h + 1 : 0;// UTC nach MEZm<strong>in</strong>ute = (m >= 0 && m < 60) ? m : 0;}// Zeit <strong>in</strong> UTC von std<strong>in</strong> e<strong>in</strong>lesenvoid TIME::Gettime(){cout « "Stun<strong>de</strong> e<strong>in</strong>geben: ";c<strong>in</strong> » h<strong>in</strong>;cout « "M<strong>in</strong>uten e<strong>in</strong>geben: ";c<strong>in</strong> » m<strong>in</strong>;cout » "Vielen Dank" » endl;}TIME::Settime(h<strong>in</strong>, m<strong>in</strong>);// Umrechnung


184 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>// MEZ ausgebenvoid TIME::Pr<strong>in</strong>tmez(){cout « (hour < 10 ? "0" : "") « hour« ’:’« (m<strong>in</strong>ute < 10 ? "0" : "") « m<strong>in</strong>ute« endl;}// Hauptprogramm (Rahmen- o<strong>de</strong>r Treiberprogramm)<strong>in</strong>t ma<strong>in</strong>(){TIME t;// Erzeugung <strong>de</strong>s Objektes tcout « "\nDie Anfangszeit ist ";t.Pr<strong>in</strong>tmez(); // Aufruf e<strong>in</strong>er oeff. Metho<strong>de</strong>t.Settime(13, 27);cout « "Neue Zeit ist ";t.Pr<strong>in</strong>tmez();t.Gettime();cout « "Ihre Zeit ist: ";t.Pr<strong>in</strong>tmez();t.Settime(99, 99); // ungueltige Wertecout « "Fehlerhafte E<strong>in</strong>gabe fuehrt zu ";t.Pr<strong>in</strong>tmez();}cout « endl;return 0;// endl<strong>in</strong>e stream manipulatorQuelle 1.63 : <strong>C++</strong>-Programm zur Umrechnung von UTC nachMEZ1.6.3 Klassenhierarchie, abstrakte Klassen,VererbungObjektorientiertes Programmieren besteht im Programmierene<strong>in</strong>er Menge von Klassen, <strong>de</strong>ren zughörige Objekte <strong>de</strong>n Program-


1.6. KLASSEN 185mablauf verwirklichen. Das folgen<strong>de</strong> Programm zeigt, wie ause<strong>in</strong>er Basisklasse weitere Klassen abgeleitet wer<strong>de</strong>n, die die publicund protected members erben. Von e<strong>in</strong>er abstrakten Klassekönnen nur weitere Klassen abgeleitet, jedoch ke<strong>in</strong>e Objektegebil<strong>de</strong>t wer<strong>de</strong>n. E<strong>in</strong>e abstrakte Klasse muß m<strong>in</strong><strong>de</strong>stens e<strong>in</strong>ere<strong>in</strong> virtuelle Funktion enthalten, die nirgends <strong>de</strong>f<strong>in</strong>iert wird.Sie ist e<strong>in</strong> Platzhalter, <strong>de</strong>r erst <strong>in</strong> e<strong>in</strong>er abgeleiteten Klasse e<strong>in</strong>enInhalt bekommt./* geof.C, Beispiel fuer Klassen und Vererbung- geometrische Formen -Compileraufruf (HP): CC -o geof geof.C*/#<strong>de</strong>f<strong>in</strong>e PI 3.14159#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> void exit(<strong>in</strong>t);class Form {public:virtual void lesen() = 0;virtual void schreiben() = 0;protected:private:};class Flaeche : public Form {// symbolische Konstante// fuer E<strong>in</strong>- und Ausgabe// wegen strcmp()// wegen exit()// Prototyp Systemaufruf// abstrakte Basisklasse// nach aussen sichtbar// re<strong>in</strong>e virt. Funktione// public fuer abg. Klas// ansonsten private// nach aussen unsichtba// abgel. abstr. Klassepublic:Flaeche() {u = i = 0;} // Constructorvoid schreiben(){cout « "Umfang = " « u « endl;cout « "Inhalt = " « i « endl;}protected:double u, i;virtual double umfang(double, double) = 0;// re<strong>in</strong> virtuelle Fkt.


186 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>private:};virtual double <strong>in</strong>halt(double, double) = 0;class Koerper : public Form {// abgel. abstr. Klassepublic:Koerper() {f = v = 0;} // Constructorvoid schreiben(){cout « "Oberflaeche = " « f « endl;cout « "Volumen = " « v « endl;}protected:double f, v;virtual double flaeche(double, double, double) = 0;// re<strong>in</strong> virtuelle Fkt.virtual double volumen(double, double, double) = 0;private:};class Kreis : public Flaeche {// abgel. konkr. Klassepublic:Kreis() {a = x = y = 0;} // Constructorvoid lesen(){cout « "Radius: "; c<strong>in</strong> » a;u = umfang(a, a);i = <strong>in</strong>halt(a, a);}protected:private:double a, x, y;double umfang(double x, double y) {return(PI * (x + y));}double <strong>in</strong>halt(double x, double y) {return(PI * x * y);}};class Rechteck : public Flaeche { // abgel. konkr. Klassepublic:Rechteck() {a = b = x = y = 0;}void lesen() {cout « "Laenge: "; c<strong>in</strong> » a;cout « "Breite: "; c<strong>in</strong> » b;


1.6. KLASSEN 187u = umfang(a, b);i = <strong>in</strong>halt(a, b);}protected:double umfang(double x, double y) {return(2 * (x + y))double <strong>in</strong>halt(double x, double y) {return(x * y);}private:double a, b, x, y;};class Quadrat : public Rechteck { // abgel. konkr. Klassepublic:Quadrat() {a = 0;}// Constructorvoid lesen() {cout « "Laenge: "; c<strong>in</strong> » a;u = umfang(a, a);i = <strong>in</strong>halt(a, a);}protected:private:double a;};class Kugel : public Koerper {// abgel. konkr. Klassepublic:Kugel() {a = x = y = z = 0;} // Constructorvoid lesen(){cout « "Radius: "; c<strong>in</strong> » a;f = flaeche(a, a, a);v = volumen(a, a, a);}protected:private:double a, x, y, z;double flaeche(double x, double y, double z){return(2 * PI * x * (y + z));}double volumen(double x, double y, double z){return(4 * PI * x * y * z / 3);}};class Qua<strong>de</strong>r : public Koerper {// abgel. konkr. Klasse


188 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>public:Qua<strong>de</strong>r() {a = b = c = x = y = z = 0;} // Constructorvoid lesen(){cout « "Laenge: "; c<strong>in</strong> » a;cout « "Breite: "; c<strong>in</strong> » b;cout « "Hoehe: "; c<strong>in</strong> » c;f = flaeche(a, b, c);v = volumen(a, b, c);}protected:double flaeche(double x, double y, double z){return(2 * (x * y + x * z + y * z));}double volumen(double x, double y, double z){return(x * y * z);}private:double a, b, c, x, y, z;};class Wuerfel : public Qua<strong>de</strong>r {// abgel. konkr. Klassepublic:Wuerfel() {a = 0;}// Constructorvoid lesen(){cout « "Laenge: "; c<strong>in</strong> » a;f = flaeche(a, a, a);v = volumen(a, a, a);}protected:private:double a;};// Hauptprogramm<strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t x = 0;char figur[32];cout « "\nFlaechen- und Koerperberechnung\n\n";cout « "Welche Figur? ";c<strong>in</strong> » figur;cout « "\nFigur: " « figur « endl;


1.6. KLASSEN 189// Str<strong>in</strong>gvergleiche, erfor<strong>de</strong>rlich, weil <strong>in</strong> <strong>de</strong>r// switch-Anweisung nur e<strong>in</strong>e <strong>in</strong>t-Variable stehen kann.if (!(strcmp(figur, "Kreis"))) x = 21;if (!(strcmp(figur, "Rechteck"))) x = 22;if (!(strcmp(figur, "Quadrat"))) x = 23;if (!(strcmp(figur, "Kugel"))) x = 31;if (!(strcmp(figur, "Qua<strong>de</strong>r"))) x = 32;if (!(strcmp(figur, "Wuerfel"))) x = 33;// Erzeugen <strong>de</strong>s passen<strong>de</strong>n Objektes f. Gilt wie// je<strong>de</strong> Deklaration nur <strong>in</strong>nerhalb <strong>de</strong>s Blockes {},// weshalb die Metho<strong>de</strong>n lesen() und schreiben()// <strong>in</strong> je<strong>de</strong>m Block vorkommen muessen.switch (x){case 21: {Kreis f;f.lesen();f.schreiben();break;}case 22: {Rechteck f;f.lesen();f.schreiben();break;}case 23: {Quadrat f;f.lesen();f.schreiben();break;}case 31: {Kugel f;f.lesen();f.schreiben();break;}case 32: {Qua<strong>de</strong>r f;f.lesen();// Erzeugen <strong>de</strong>s Objektes f


190 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}return 0;}f.schreiben();break;}case 33: {Wuerfel f;f.lesen();f.schreiben();break;}<strong>de</strong>fault:cout « "Ke<strong>in</strong>e gueltige Figur." « endl;exit(-1);Quelle 1.64 : <strong>C++</strong>-Programm zur Berechnung geometrischer FormenGeometrische Formen legen e<strong>in</strong>e objektorientierte Programmierungnahe, da sie e<strong>in</strong>e Hierarchie bil<strong>de</strong>n, ähnlich wie Pflanzeno<strong>de</strong>r Tiere. Im Beispiel wird als erstes e<strong>in</strong>e abstrakte BasisklasseForm <strong>de</strong>f<strong>in</strong>iert, die das enthält, was allen Formen geme<strong>in</strong>samist. Das ist nicht viel und steht <strong>in</strong> <strong>de</strong>n bei<strong>de</strong>n re<strong>in</strong> virtuellenFunktionen lesen() und schreiben.Aus <strong>de</strong>r Klasse Form wer<strong>de</strong>n die bei<strong>de</strong>n immer noch abstraktenKlassen Flaeche und Koerper abgeleitet. Von Flächenläßt sich sagen, dass sie e<strong>in</strong>en Umfang und e<strong>in</strong>en Inhalthaben, ausgedrückt durch die bei<strong>de</strong>n re<strong>in</strong> virtuellen Funktionenumfang() und <strong>in</strong>halt(). Für Körper haben wir entsprechenddie abstrakte Klasse Koerper mit <strong>de</strong>n re<strong>in</strong> virtuellen Funktionenflaeche() (Oberfläche) und volumen().Im nächsten Schritt gelangen wir endlich zu konkreten Klassen.Aus <strong>de</strong>r Klasse flaeche wer<strong>de</strong>n die Klassen Kreis undRechteck abgeleitet, aus <strong>de</strong>r Klasse Rechteck noch die KlasseQuadrat. Während aus abstrakten Klassen nur weitere, abstrakteo<strong>de</strong>r konkrete Klassen abgeleitet wer<strong>de</strong>n können, lassensich aus konkreten Klassen weitere konkrete Klassen ableiteno<strong>de</strong>r Objekte bil<strong>de</strong>n.Bei <strong>de</strong>n Körpern leiten wir analog aus <strong>de</strong>r abstrakten KlasseKoerper die konkreten Klassen Kugel und Qua<strong>de</strong>r ab, ausQua<strong>de</strong>r nochmals Wuerfel.


1.6. KLASSEN 191In <strong>de</strong>n konkreten Klassen erhalten die virtuellen Funktionenauch e<strong>in</strong>en konkreten Inhalt, das heißt, die Platzhalter wer<strong>de</strong>nmit <strong>de</strong>n Formeln für <strong>de</strong>n Flächen<strong>in</strong>halt e<strong>in</strong>es Kreises o<strong>de</strong>r Rechtecksbesetzt usw. Diese Formeln sehen für je<strong>de</strong> konkrete geometrischeForm an<strong>de</strong>rs aus.Bei e<strong>in</strong>er Klassenableitung wie:class Kreis : public Flaeche { }be<strong>de</strong>utet das Schlüsselwort public, dass von <strong>de</strong>r zugrun<strong>de</strong> liegen<strong>de</strong>nKlasse (Basisklasse) die public members als public unddie protected members als protected geerbt wer<strong>de</strong>n. Die privatemembers wer<strong>de</strong>n <strong>in</strong> ke<strong>in</strong>em Fall vererbt. Hätten wir dagegendas Wort private gebraucht, so wären die vererbten members<strong>in</strong> <strong>de</strong>r abgeleiteten Klasse privat gewor<strong>de</strong>n.Das Erbrecht zwischen Klassen ist noch differenzierter, auchFreun<strong>de</strong> können erben, und e<strong>in</strong>e Klasse kann aus zwei Basisklassenabgeleitet wer<strong>de</strong>n, aber erstmal muß Obiges verstan<strong>de</strong>nund geübt wer<strong>de</strong>n. Die ausgefeilte Klassenhierarchie hat <strong>de</strong>nVorteil, dass man auf je<strong>de</strong>r Stufe genau das festlegt, was sichdort festlegen läßt, nicht mehr und nicht weniger. Kontrollenund Än<strong>de</strong>rungen wer<strong>de</strong>n stets <strong>in</strong> e<strong>in</strong>er bestimmten Stufe vorgenommen.Das Hauptprogramm ma<strong>in</strong>() ist vergleichsweise trivial.Nach e<strong>in</strong> bißchen Benutzerdialog wer<strong>de</strong>n <strong>in</strong> e<strong>in</strong>er switch-Anweisung die ausgewählten Objekte erzeugt und <strong>de</strong>ren Metho<strong>de</strong>naufgerufen, nämlich die ursprünglich virtuellenund <strong>in</strong><strong>de</strong>n konkreten Klassen <strong>de</strong>f<strong>in</strong>ierten Funktionen lesen() undschreiben(). Die wesentliche Arbeit steckt <strong>in</strong> <strong>de</strong>n Klassen.1.6.4 Memo Klassen• Bei e<strong>in</strong>em abstrakten Datentyp ist das Innenleben von <strong>de</strong>rAußenseite streng getrennt (Black Box).• Klassen s<strong>in</strong>d <strong>in</strong> e<strong>in</strong>er Programmiersprache formulierte Beschreibungenabstrakter Datentypen.• Objekte s<strong>in</strong>d Verwirklichungen von Klassen, so wie VariableVerwirklichungen von Typen s<strong>in</strong>d.• E<strong>in</strong>e Klasse o<strong>de</strong>r e<strong>in</strong> Objekt enthält Daten (data members)und Metho<strong>de</strong>n (member functions).


192 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>• Daten und Metho<strong>de</strong>n s<strong>in</strong>d öffentlich (public), geschützt(protected) o<strong>de</strong>r privat. Die Daten s<strong>in</strong>d meist privat. M<strong>in</strong><strong>de</strong>stense<strong>in</strong>e Metho<strong>de</strong> muß öffentlich se<strong>in</strong>, sonst nützt dieKlasse nicht viel.• Aus Klassen können Unterklassen abgeleitet wer<strong>de</strong>n, diedie öffentlichen und geschützten (protected) Daten und Metho<strong>de</strong>nerben. Die Klassen bil<strong>de</strong>n Hierarchien.• Von e<strong>in</strong>er abstrakten Klasse können nur Unterklassen,aber ke<strong>in</strong>e Objekte abgeleitet wer<strong>de</strong>n. Meist <strong>in</strong> <strong>de</strong>n oberenEtagen <strong>de</strong>r Hierarchie anzutreffen.1.6.5 Übung KlassenEs gibt Aufgaben, <strong>de</strong>ren Struktur e<strong>in</strong>e Mo<strong>de</strong>llierung durch e<strong>in</strong>eKlassenhierarchie nahelegt. Bei an<strong>de</strong>ren h<strong>in</strong>wie<strong>de</strong>rum wirkt dieObjektorientierung verkrampft. Mit C/<strong>C++</strong> s<strong>in</strong>d alle Wege offen.Überlegen Sie, welche Klassen und Objekte man bei <strong>de</strong>r Aufgabezur Weganalyse zweckmäßig e<strong>in</strong>richtet. S<strong>in</strong>d die Wegstreckeno<strong>de</strong>r die Fahrzeuge/Personen als Objekte anzusehen? SkizzierenSie – ohne genau auf die Syntax zu achten – e<strong>in</strong>e Klassenhierarchiesamt Daten und Metho<strong>de</strong>n.In <strong>de</strong>m Beispielprogramm zur Befeuerung von B<strong>in</strong>nenschiffenkann man sich gut e<strong>in</strong>e Hierarchie von Fahrzeugen und entsprechen<strong>de</strong>nKlassen vorstellen, wobei an <strong>de</strong>r Spitze die Klasse<strong>de</strong>r Hohlkörper von nicht ganz unbe<strong>de</strong>uten<strong>de</strong>r Größe steht.Auch bei <strong>de</strong>m Beispiel <strong>de</strong>s Vokabeltra<strong>in</strong>ers ist e<strong>in</strong>e Hierarchie<strong>de</strong>nkbar. Wie könnten die Klassen, Daten und Metho<strong>de</strong>n aussehen?Welche Vorteile hätte hier die Objektorientierung vor <strong>de</strong>rprozeduralen Denkweise?1.7 Klassen-Bibliotheken1.7.1 <strong>C++</strong>-StandardbibliothekStandardbibliotheken s<strong>in</strong>d e<strong>in</strong>e Ergänzung <strong>de</strong>r Compiler, ohnedie man nicht weit kommt. Die Benutzer betrachten sie als festenBestandteil <strong>de</strong>r Compiler, obwohl sie im strengen S<strong>in</strong>n nichtBestandteil <strong>de</strong>r Sprache s<strong>in</strong>d. Zu <strong>C++</strong> gehört ebenso wie zu C e<strong>in</strong>eStandardbibliothek, <strong>de</strong>ren Umfang und Funktionalität durch


1.7. KLASSEN-BIBLIOTHEKEN 193e<strong>in</strong>e ISO/ANSI-Norm festgelegt ist. Im wesentlichen gehören dazu:• die C-Standardbibliothek (damit man sie nicht extra zunennen braucht),• Input/Output-Klassen wie basic_ios,• Str<strong>in</strong>g-Klassen wie basic_str<strong>in</strong>g,• numerisches Klassen wie complex,• Klassen zur Ausnahmebehandlung wie exception,• sonstige Klassen wie pair und Klassen zur Lokalisation(Anpassung an örtliche Gegebenheiten),• die Standard Template Library (STL)Die <strong>C++</strong>-Standardbibliothek ist wesentlich umfangreicher alsdie C-Standardbibliothek, sie erfor<strong>de</strong>rt mehr Zeit zum E<strong>in</strong>arbeiten,aber sie spart viel Mühe. Es ist Zeitverschwendung, dieKlasse Rad neu zu erf<strong>in</strong><strong>de</strong>n. Die Standard Template Libraryspielt e<strong>in</strong>e beson<strong>de</strong>re Rolle, weil sie e<strong>in</strong>ige neue Begriffe <strong>in</strong> <strong>C++</strong>e<strong>in</strong>br<strong>in</strong>gt.1.7.2 Standard Template Library (STL)E<strong>in</strong> wichtiger Schritt vorwärts <strong>in</strong> <strong>de</strong>r Standardisierung von<strong>C++</strong> war die Annahme <strong>de</strong>r Standard Template Library (STL)als Erweiterung <strong>de</strong>r <strong>C++</strong>-Standard-Bibliothek durch das ANSI-Komitee im Jahr 1993. Die STL enthält fünf Gruppen von Komponenten:• Allgeme<strong>in</strong>e Algorithmen,• Iteratoren,• Conta<strong>in</strong>er,• Funktionen,• Adaptoren.Wenn man <strong>in</strong> e<strong>in</strong>em C-Programm e<strong>in</strong> Array l<strong>in</strong>ear (sequentiell)nach e<strong>in</strong>em bestimmten Wert durchsuchen will, sieht dieFunktion für Ganzzahlen an<strong>de</strong>rs aus als für Str<strong>in</strong>gs, obwohl<strong>de</strong>r Suchalgorithmus <strong>de</strong>rselbe ist. Die Algorithmen <strong>de</strong>r STL s<strong>in</strong>ddagegen allgeme<strong>in</strong> gültig, <strong>in</strong><strong>de</strong>m sie mit Hilfe von Templates


194 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong><strong>de</strong>n Algorithmus vom Datentyp trennen. E<strong>in</strong> Template (Vorlage,Muster, Schablone) ist e<strong>in</strong>e allgeme<strong>in</strong>e Vorstufe zu e<strong>in</strong>er Funktiono<strong>de</strong>r e<strong>in</strong>er Klasse, <strong>de</strong>r die Typen <strong>de</strong>r verwen<strong>de</strong>ten Daten alsParameter mitgegeben wer<strong>de</strong>n – ähnlich wie bei e<strong>in</strong>em Funktionsaufrufdie Typen <strong>de</strong>r Argumente. Der Compiler erzeugt dannaus <strong>de</strong>m Template die gewünschte Klasse o<strong>de</strong>r Funktion undnimmt so <strong>de</strong>m Programmierer Arbeit ab.Iteratoren s<strong>in</strong>d e<strong>in</strong>e Verallgeme<strong>in</strong>erung <strong>de</strong>r Po<strong>in</strong>ter. Sie wer<strong>de</strong>ne<strong>in</strong>gesetzt, um auf Elemente von Conta<strong>in</strong>ern zuzgreifen, sowie man mittels Po<strong>in</strong>terarithmetik auf die Elemente e<strong>in</strong>es Arrayszugreift. Im Gegensatz zu Po<strong>in</strong>tern br<strong>in</strong>gen sie jedoch e<strong>in</strong>egewisse eigene Intelligenz mit, so daß <strong>de</strong>r Programmierer –wenn er erst e<strong>in</strong>mal ihre Funktionsweise begriffen hat – wenigerArbeit aufzuwen<strong>de</strong>n braucht.Unter Conta<strong>in</strong>ern, auch Collection genannt, wer<strong>de</strong>n Datenstrukturen(Klassen) verstan<strong>de</strong>n, die an<strong>de</strong>re Datenstruktureno<strong>de</strong>r Objekte enthalten. Damit lässt sich e<strong>in</strong>e Gruppe von Objektenunter e<strong>in</strong>em Namen geme<strong>in</strong>sam handhaben. SequentielleConta<strong>in</strong>er speichern ihre Objekte <strong>in</strong> e<strong>in</strong>er Reihe (l<strong>in</strong>ear),auf sie kann entwe<strong>de</strong>r <strong>de</strong>r Reihe nach o<strong>de</strong>r wahlfrei zugegriffenwer<strong>de</strong>n. Daneben gibt es die assoziativen Conta<strong>in</strong>er, <strong>de</strong>renObjekte über e<strong>in</strong>en Schlüssel o<strong>de</strong>r In<strong>de</strong>x zugänglich s<strong>in</strong>d. Dere<strong>in</strong>fachste sequentielle Conta<strong>in</strong>er ist <strong>de</strong>r Vektor, e<strong>in</strong> Array variablerGröße. Der e<strong>in</strong>fachste assoziative Conta<strong>in</strong>er ist die Menge(Set), <strong>in</strong> <strong>de</strong>r je<strong>de</strong>r Schlüssel nur e<strong>in</strong>mal vorkommen darf. Zu je<strong>de</strong>rArt von Conta<strong>in</strong>ern gehört e<strong>in</strong> Satz von Metho<strong>de</strong>n. Auch hierbraucht sich <strong>de</strong>r Programmierer nicht um die E<strong>in</strong>zelheiten <strong>de</strong>rSpeicherung und <strong>de</strong>r Zugriffe zu kümmern, das hat die Bibliothekbereits erledigt.E<strong>in</strong> Adaptor schließlich macht das, was auch an<strong>de</strong>re Adaptermachen: er paßt das Aussehen e<strong>in</strong>er Schnittstelle an neueErfor<strong>de</strong>rnisse an, er verpackt e<strong>in</strong>en Iterator o<strong>de</strong>r e<strong>in</strong>en Conta<strong>in</strong>er<strong>in</strong> e<strong>in</strong>e neue Umhüllung. Damit wird nicht e<strong>in</strong> neues Objektgeschaffen, son<strong>de</strong>rn nur se<strong>in</strong>e Außenseite verän<strong>de</strong>rt. Das ist oftmalseffektiver, als e<strong>in</strong> neues Objekt zu schreiben.Um die STL ganz zu verstehen, muß man sie benutzen. Dasie auf e<strong>in</strong>er hohen Abstraktionsebene zu Hause ist, machen sichihre Vorteile erst bei umfangreicheren Aufgaben bemerkbar. FürHallo-Welt-Programme ist sie e<strong>in</strong>ige Nummern zu groß. Wir ver-


1.7. KLASSEN-BIBLIOTHEKEN 195weisen daher auf das Buch von ROBERT ROBSON und auf unsereTechnik-Seite im WWW.1.7.3 C-XSC1.7.3.1 Was ist C-XSC?Für numerische Aufgaben wur<strong>de</strong> im Institut für AngewandteMathematik <strong>de</strong>r Universität Karlsruhe e<strong>in</strong>e KlassenbibliothekC-XSC als Ergänzung e<strong>in</strong>es <strong>C++</strong>-Compilers entwickelt 33 .Das Kürzel XSC ist als Exten<strong>de</strong>d Scientific Comput<strong>in</strong>g zu <strong>de</strong>uten.Die wichtigsten Bestandteile von C-XSC s<strong>in</strong>d:• Arithmetik reeller und komplexer Zahlen sowie Intervallarithmetikmit mathematisch bestimmten Eigenschaften,• dynamische Vektoren und Matrizen mit zur Laufzeit verän<strong>de</strong>rbarerGröße,• Teilfel<strong>de</strong>r (Subarrays) aus Vektoren und Matrizen,• arithmetische Operatoren und mathematische Standardfunktionenvon hoher, bekannter Genauigkeit,• dynamische Langzahlarithmetik mit zughörigen Standardfunktionen,• Rundungskontrolle bei <strong>de</strong>r E<strong>in</strong>- und Ausgabe,• Behandlung bestimmter Fehler (z. B. Überschreiten <strong>de</strong>r In<strong>de</strong>xgrenzen),• Bibliothek mit Rout<strong>in</strong>en zur Lösung von Standardproblemen<strong>de</strong>r numerischen Analysis.Zusammen mit <strong>de</strong>r Klassenbibliothek C-XSC geht <strong>C++</strong> <strong>in</strong> <strong>de</strong>rBehandlung numerischer Aufgaben über FORTRAN und an<strong>de</strong>reProgrammiersprachen h<strong>in</strong>aus.33 Dieser Abschnitt ist die gekürzte Übersetzung e<strong>in</strong>esAufsatzes (1992) von Dipl.-Math. ANDREAS WIET-HOFF, Mitarbeiter <strong>de</strong>s genannten Institutes, siehewww.uni-karlsruhe.<strong>de</strong>/˜iam/html/language/cxsc/cxsc.html.


196 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.7.3.2 Datentypen, Operatoren und FunktionenC-XSC stellt folgen<strong>de</strong> e<strong>in</strong>fache numerische Datentypen zur Verfügung:real, <strong>in</strong>terval, complex, c<strong>in</strong>terval (=complex <strong>in</strong>terval)samt <strong>de</strong>n zugehörigen arithmetischen und relationalen Operatorenund <strong>de</strong>n mathematischen Standardfunktionen. Alle vor<strong>de</strong>f<strong>in</strong>iertenarithmetischen Operatoren liefern Ergebnisse mit e<strong>in</strong>erGenauigkeit von wenigstens e<strong>in</strong>er E<strong>in</strong>heit <strong>de</strong>r letzten Stelle.Auf diese Weise s<strong>in</strong>d sie maximal genau im S<strong>in</strong>ne <strong>de</strong>s wissenschaftlichenRechnens. Die von <strong>de</strong>n arithmetischen Operatorenvorgenommenen Rundungen lassen sich durch <strong>de</strong>n Gebrauch <strong>de</strong>rDatentypen <strong>in</strong>terval und c<strong>in</strong>terval steuern. Funktionen zurTypumwandlung s<strong>in</strong>d für alle mathematisch s<strong>in</strong>nvollen Komb<strong>in</strong>ationenverfügbar. Alle mathematischen Standardfunktionenfür e<strong>in</strong>fache numerische Datentypen können mit ihrem gewohntenNamen aufgerufen wer<strong>de</strong>n und liefern Ergebnisse von garantierterhoher Genauigkeit für beliebige Argumente aus <strong>de</strong>mDef<strong>in</strong>itosnbereich. Die Standardfunktionen für die Datentypen<strong>in</strong>terval und c<strong>in</strong>terval liefern scharfe E<strong>in</strong>schlüsse <strong>de</strong>r Wertebereiche.Zu <strong>de</strong>n oben genannten e<strong>in</strong>fachen Datentypen kommen dieentsprechen<strong>de</strong>n Felddatentypen (Vektoren und Matrizen):rvector, ivector, cvector, civector,rmatrix, imatrix, cmatrix, cimatrixDer Anwen<strong>de</strong>r kann Speicherplatz für diese Arrays zur Laufzeitzuordnen und freigeben. Auf diese Weise kann dasselbe Programmfür Arrays unterschiedlicher Größe benutzt wer<strong>de</strong>n, begrenztnur durch <strong>de</strong>n Arbeitsspeicher. Es wird nicht mehr Speichervon <strong>de</strong>n Daten belegt, als wirklich benötigt wird. Beim Zugriffauf Arrays wird <strong>de</strong>r In<strong>de</strong>xbereich zur Laufzeit geprüft, umProgrammabstürze durch unzulässige Speicherzugriffe (memoryfaults) zu verh<strong>in</strong><strong>de</strong>rn.Hier e<strong>in</strong> Beispiel für die dynamische Größenän<strong>de</strong>rung e<strong>in</strong>erMatrix:...<strong>in</strong>t n, m;


1.7. KLASSEN-BIBLIOTHEKEN 197cout > n >> m;imatrix B, C, A(n,m); /* A[1][1] ... A[n][m] */Resize(B,m,n); /* B[1][1] ... B[m][n] */...C = A * B; /* C[1][1] ... C[n][n] */Mit Hilfe <strong>de</strong>s <strong>C++</strong>-ostream-Objektes cout wird e<strong>in</strong> Str<strong>in</strong>g nachstdout geschrieben, dann wer<strong>de</strong>n mit c<strong>in</strong> die bei<strong>de</strong>n In<strong>de</strong>xgrenzenn und m von std<strong>in</strong> e<strong>in</strong>gelesen. Die Vere<strong>in</strong>barung e<strong>in</strong>esVektors o<strong>de</strong>r e<strong>in</strong>er Matrix ohne Angabe <strong>de</strong>r In<strong>de</strong>xgrenzen lieferte<strong>in</strong>en Vektor mit e<strong>in</strong>er Komponente o<strong>de</strong>r e<strong>in</strong>e Matrix mitje e<strong>in</strong>er Zeile und Spalte. Speicher für diese Objekte wird erstan e<strong>in</strong>er späteren Stelle im Programm zur Laufzeit zugewiesen.Die Matrix A wird gleich <strong>in</strong> <strong>de</strong>r richtigen Größe angelegt. DieResize-Anweisung br<strong>in</strong>gt die Matrix B zur Laufzeit an dieserProgrammstelle auf die erfor<strong>de</strong>rliche Größe.Die Belegung von Speicherplatz für e<strong>in</strong>en Vektor o<strong>de</strong>r e<strong>in</strong>eMatrix kann auch implizit – ohne e<strong>in</strong>e ausdrückliche Anweisungwie Resize – durch e<strong>in</strong>e Zuweisung erfolgen. Falls die In<strong>de</strong>xgrenzen<strong>de</strong>s Objektes auf <strong>de</strong>r rechten Seite e<strong>in</strong>er Zuweisungnicht mit <strong>de</strong>n In<strong>de</strong>xgrenzen <strong>de</strong>s Objektes auf <strong>de</strong>r l<strong>in</strong>ken Seiteübere<strong>in</strong>stimmen, wird das l<strong>in</strong>ke Objekt angepaßt, wie es hier mit<strong>de</strong>r Matrix C geschieht.Der dynamisch zugewiesene Speicherplatz e<strong>in</strong>es lokal vere<strong>in</strong>bartenArrays wird automatisch beim Verlassen <strong>de</strong>s Gültigkeitsbereichesfreigegeben. H<strong>in</strong>sichtlich Lebensdauer und Gültigkeitsbereichbesteht ke<strong>in</strong> Unterschied zu <strong>de</strong>n aus C gewohntenArrays.Die Größe e<strong>in</strong>es Vektors o<strong>de</strong>r e<strong>in</strong>er Matrix kann je<strong>de</strong>rzeitdurch Aufrufen <strong>de</strong>r Funktionen Lb() und Ub() für die unterebzw. obere In<strong>de</strong>xgrenze ermittelt wer<strong>de</strong>n.1.7.3.3 Teilfel<strong>de</strong>r von Vektoren und MatrizenC-XSC stellt e<strong>in</strong>e eigene Schreibweise für die Handhabung vonTeilfel<strong>de</strong>rn (Subarrays) von Vektoren und Matrizen zur Verfügung.Subarrays s<strong>in</strong>d beliebige rechteckige Ausschnitte aus Arrays.Alle vor<strong>de</strong>f<strong>in</strong>ierten Operatoren nehmen auch Subarrays alsOperan<strong>de</strong>n an. E<strong>in</strong> Subarray e<strong>in</strong>er Matrix o<strong>de</strong>r e<strong>in</strong>es Vektors


198 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>wird über <strong>de</strong>n ()-Operator o<strong>de</strong>r über <strong>de</strong>n []-Operator angesprochen.Der ()-Operator bezeichnet e<strong>in</strong> Subarray e<strong>in</strong>es Objektesvom selben Typ wie das ursprüngliche Objekt. Ist beispielsweiseA e<strong>in</strong>e reelle n x n-Matrix, dann ist A(i,i) die l<strong>in</strong>ke obere i x i-Submatrix. Man beachte, daß die Klammern <strong>in</strong> <strong>de</strong>r Deklaratione<strong>in</strong>es dynamischen Vektors o<strong>de</strong>r e<strong>in</strong>er ebensolchen Matrix ke<strong>in</strong>Subarray bezeichnen, son<strong>de</strong>rn <strong>de</strong>n In<strong>de</strong>xbereich <strong>de</strong>s anzulegen<strong>de</strong>nObjektes e<strong>in</strong>schließen. Der []-Operator erzeugt e<strong>in</strong> Subarraye<strong>in</strong>es niedrigeren Typs. Wenn A e<strong>in</strong>e Matrix vom Typ n xn-rmatrix ist, dann ist A[i] die i-te Zeile von A mit <strong>de</strong>m Typrvector, und A[i][j] ist das (i,j)-te Element von A mit <strong>de</strong>m Typreal.Bei<strong>de</strong> Arten <strong>de</strong>s Zugriffs auf Subarrays können auch verbun<strong>de</strong>nwer<strong>de</strong>n, beispielsweise ist A[k](i,j) e<strong>in</strong> Subvektor von In<strong>de</strong>xi bis In<strong>de</strong>x j <strong>de</strong>s k-ten Zeilenvektors <strong>de</strong>r Matrix A.Den Gebrauch von Subarrays zeigt das folgen<strong>de</strong>n Beispiel,das die LU-Faktorisierung e<strong>in</strong>er n * n-Matrix A beschreibt:for (j = 1; j


1.7. KLASSEN-BIBLIOTHEKEN 199die numerische Ausdrücke mit hoher und auf mathematischemWege garantierter Genauigkeit auswerten.E<strong>in</strong>e beson<strong>de</strong>re Art solcher Ausdrücke s<strong>in</strong>d die sogenanntenSkalarproduktausdrücke. Sie s<strong>in</strong>d als e<strong>in</strong>e Summe e<strong>in</strong>facherAusdrücke <strong>de</strong>f<strong>in</strong>iert. E<strong>in</strong> e<strong>in</strong>facher Ausdruck ist entwe<strong>de</strong>re<strong>in</strong>e Variable, e<strong>in</strong>e Konstante o<strong>de</strong>r e<strong>in</strong> e<strong>in</strong>zelnes Produktvon zweien solcher Objekte. Die Variablen dürfen vom Typ Skalar,Vektor o<strong>de</strong>r Matrix se<strong>in</strong>. Nur die mathematisch s<strong>in</strong>nvollenOperationen s<strong>in</strong>d für die Addition und die Multiplikation zugelassen.Das Ergebnis <strong>de</strong>r Auswertung e<strong>in</strong>es solchen Ausdrucksist entwe<strong>de</strong>r e<strong>in</strong> Skalar, e<strong>in</strong> Vektor o<strong>de</strong>r e<strong>in</strong>e Matrix. In <strong>de</strong>rnumerischen Analysis s<strong>in</strong>d Skalarprodukte von entschei<strong>de</strong>n<strong>de</strong>rBe<strong>de</strong>utung. Beispielsweise grün<strong>de</strong>n sich Verfahren zur Fehlerkorrekturo<strong>de</strong>r zur iterativen Verbesserung bei l<strong>in</strong>earen o<strong>de</strong>rnichtl<strong>in</strong>earen Aufgaben auf Skalarprodukte. E<strong>in</strong>e Auswertungdieser Ausdrücke mit maximaler Genauigkeit vermei<strong>de</strong>t Fehlerdurch Auslöschung. Für e<strong>in</strong>e Auswertung mit e<strong>in</strong>er Genauigkeitvon e<strong>in</strong>er E<strong>in</strong>heit <strong>de</strong>r letzten Stelle stellt C-XSC die folgen<strong>de</strong>nDotprecision-Datentypen zur Verfügung:dotprecision, cdotprecision, idotprecision, cidotprecisionZwischenergebnisse e<strong>in</strong>es Skalarproduktes können ohne je<strong>de</strong>nRundungsfehler <strong>in</strong> e<strong>in</strong>er Dotprecision-Variablen errechnet undgespeichert wer<strong>de</strong>n. Die folgen<strong>de</strong> Funktion berechnet e<strong>in</strong>e maximalgenaue E<strong>in</strong>schließung <strong>de</strong>s Defektes b - Ax e<strong>in</strong>es l<strong>in</strong>earenGleichungssystems Ax = b :ivector <strong>de</strong>fect (rvector b, rmatrix A, rvector x){idotprecision accu;ivector INCL (Lb(x), Ub(x));}for (<strong>in</strong>t i = Lb(x); i


200 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Quelle 1.65 : C-XSC-Funktion <strong>de</strong>fect() zur Defekte<strong>in</strong>schließungIn obigem Beispiel berechnet die Funktion accumulate()die Summe:n∑−A ij · x jj=1und addiert das Ergebnis zu <strong>de</strong>m Dotprecision-Akkumulatoraccu ohne Rundungsfehler. Die idotprecision-Variable accuwird mit b[i] <strong>in</strong>itialisiert. Schließlich wird <strong>de</strong>r Wert im Akkumulatormaximal genau auf das Standard-Intervall INCL[i] gerun<strong>de</strong>t.Auf diese Weise s<strong>in</strong>d die Grenzen von INCL[i] entwe<strong>de</strong>rgleich o<strong>de</strong>r zwei beanchbarte Gleitkommazahlen.Für alle Dotprecision-Datentypen steht e<strong>in</strong> verr<strong>in</strong>gerter Satzvor<strong>de</strong>f<strong>in</strong>ierter Operatoren zur Verfügung, um fehlerfreie Ergebnissezu berechnen. Die überla<strong>de</strong>ne Skalarprodukt-Funktionaccumulate() und die Rundungsfunktion rnd() s<strong>in</strong>d für alles<strong>in</strong>nvollen Typkomb<strong>in</strong>ationen verfügbar.1.7.3.5 Dynamische Langzahl-ArithmetikNeben <strong>de</strong>n Klassen real und <strong>in</strong>terval gibt es die dynamischenKlassen l_real (long real) und l_<strong>in</strong>terval (long <strong>in</strong>terval)ebenso wie die entsprechen<strong>de</strong>n dynamischen Vektorenund Matrizen samt allen arithmetischen und relationalen Operatorenund allen Standardfunktionen mit mehrfacher Genauigkeit.Die Rechengenauigkeit läßt sich vom Benutzer während<strong>de</strong>r Laufzeit kontrollieren. Mittels Ersetzen <strong>de</strong>r Typen real und<strong>in</strong>terval durch l_real und l_<strong>in</strong>terval <strong>in</strong> <strong>de</strong>n Deklarationenwird e<strong>in</strong> Anwendungsprogramm zu e<strong>in</strong>em Programm mitmehrfacher Genauigkeit. Dieses Konzept gibt <strong>de</strong>m Benutzer e<strong>in</strong>mächtiges und e<strong>in</strong>fach zu handhaben<strong>de</strong>s Werkzeug zur Fehleranalyse<strong>in</strong> die Hand. Weiterh<strong>in</strong> ist es möglich Programme zuschreiben, die numerische Ergebnisse mit e<strong>in</strong>er vom Benutzervorgegebenen Genauigkeit liefern, <strong>in</strong><strong>de</strong>m man <strong>in</strong>tern die Rechengenauigkeitzur Laufzeit <strong>in</strong> Abhängigkeit von <strong>de</strong>n Fehlerschranken<strong>de</strong>r Zwischenergebnisse anpaßt.Alle vor<strong>de</strong>f<strong>in</strong>ierten Operatoren für die Typen real und<strong>in</strong>terval s<strong>in</strong>d auch für die Typen l_real und l_<strong>in</strong>tervalverfügbar. Zusätzlich s<strong>in</strong>d auch alle möglichen Komb<strong>in</strong>ationen


1.7. KLASSEN-BIBLIOTHEKEN 201von Operatoren für Typen e<strong>in</strong>facher und mehrfacher Genauigkeitvorhan<strong>de</strong>n. Im folgen<strong>de</strong>n wird e<strong>in</strong> Programm mit e<strong>in</strong>facherGenauigkeit und sie entsprechen<strong>de</strong> Version mit mehrfacher Genauigkeitgezeigt:ma<strong>in</strong>(){<strong>in</strong>terval a, b; /* Standard-Intervall */a = 1.0; /* a = [1.0, 1.0] */b = 3.0; /* b = [3.0, 3.0] */cout


202 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>sonstigen Funktionen <strong>de</strong>r Langzahl-Arithmetik berechnen numerischeErgebnisse mit e<strong>in</strong>er Genauigkeit, die durch <strong>de</strong>n augenblicklichenWert von stagprec bestimmt ist. Speicherzuweisung,das Än<strong>de</strong>rn <strong>de</strong>r Größe von Arrays und das Arbeiten mitSubarrays verlaufen ähnlich wie bei <strong>de</strong>n entsprechen<strong>de</strong>n Datentypene<strong>in</strong>facher Genauigkeit.1.7.3.6 E<strong>in</strong>- und Ausgabe <strong>in</strong> C-XSCUnter Verwendung <strong>de</strong>s Stream-Konzeptes und <strong>de</strong>r überladbarenOperatoren > von <strong>C++</strong> ermöglicht C-XSC das Run<strong>de</strong>nund Formatieren aller se<strong>in</strong>er Datentypen während <strong>de</strong>r E<strong>in</strong>- undAusgabe, auch für die Dotprecision- und Langzahldatentypen.E<strong>in</strong>-/Ausgabe-Parameter wie die Richtung <strong>de</strong>r Rundung, Feldbreiteusw. benutzen auch die überla<strong>de</strong>nen I/O-Operatoren zumFormatieren <strong>de</strong>r E<strong>in</strong>- und Ausgabe. Falls e<strong>in</strong> neuer Satz von I/O-Parametern verwen<strong>de</strong>t wer<strong>de</strong>n soll, kann <strong>de</strong>r alte auf e<strong>in</strong>em <strong>in</strong>ternenStack gespeichert und bei Bedarf zurückgeholt wer<strong>de</strong>n.Das folgen<strong>de</strong> Beispiel zeigt die Möglichkeiten von C-XSC zurE<strong>in</strong>- und Ausgabe:ma<strong>in</strong>(){real a, b; <strong>in</strong>terval c;}cout a; /* lies a abwaerts gerun<strong>de</strong>cout > b; /* lies b aufwaerts gerund"[0.11, 0.22]" >> c; /* Str<strong>in</strong>g nach Intervall *cout


1.7. KLASSEN-BIBLIOTHEKEN 2031.7.3.7 C-XSC-NumerikbibliothekDie C-XSC-Numerikbibliothek ist e<strong>in</strong>e Sammlung von Funktionenund Programmen zur Lösung von Standardaufgaben <strong>de</strong>r numerischenAnalysis mit garantierter Genauigkeit <strong>de</strong>r Ergebnisse.Folgen<strong>de</strong> Bereiche wer<strong>de</strong>n abge<strong>de</strong>ckt:• Auswertung und Nullstellen von Polynomen,• L<strong>in</strong>eare Systeme, Matrizen<strong>in</strong>vertierung,• Eigenwerte, Eigenvektoren,• Schnelle Fourier-Transformation,• Nullstellen nichtl<strong>in</strong>earer Gleichungen,• Anfangswertprobleme bei gewöhnlichen Differentialgleichungen.1.7.3.8 Beispiel Intervall-Newton-VerfahrenZu bestimmen sei <strong>de</strong>r E<strong>in</strong>schluß e<strong>in</strong>er Nullstelle e<strong>in</strong>er reellenFunktion f(x). Die erste Ableitung f ′ (x) sei stetig im Intervall[a, b] und es gelte:0 /∈ {f ′ (x), x ∈ [a, b]} und f(a) · f(b) < 0.Falls X n e<strong>in</strong>e E<strong>in</strong>schließung <strong>de</strong>r Nullstelle ist, dann wird e<strong>in</strong>everbesserte E<strong>in</strong>schließung X n+1 mittels <strong>de</strong>r Formel:(X n+1 := m(X n ) − f(m(X )n))∩ Xf ′ n(X n )berechnet, wobei m(X) e<strong>in</strong> Punkt im Intervall X ist, üblicherweisedie Mitte. Die Funktion sei <strong>in</strong> diesem Beispiel:Nun das Programm:f(x) = √ x + (x + 1) · cos x/* C-XSC-Programm Newton-Verfahren mit IntervallenFunktion f(x) = sqrt(x) + (x + 1) cos(x)Inst. Angewandte Mathematik, Universitaet Karlsruhe */#<strong>in</strong>clu<strong>de</strong> "<strong>in</strong>terval.hpp"// Interval arithmetic package


204 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>#<strong>in</strong>clu<strong>de</strong> "imath.hpp"// Interval standard functions<strong>in</strong>terval f(real& x)// Function f(){<strong>in</strong>terval y;y = x;// Use <strong>in</strong>terval arithmeticreturn (sqrt(y) + (y + 1.0) * cos(y));}<strong>in</strong>terval <strong>de</strong>riv(<strong>in</strong>terval& x) // Derived function f’(){return (1.0 / (2.0 * sqrt(x)) + cos(x) - (x + 1.0) * s<strong>in</strong>(x));}<strong>in</strong>t criter(<strong>in</strong>terval& x) // Function test<strong>in</strong>g f(a)*f(b) < 0{<strong>in</strong>terval Fa, Fb;Fa = f(Inf(x));Fb = f(Sup(x));return (Sup(Fa * Fb) < 0.0 && !(0.0


1.7. KLASSEN-BIBLIOTHEKEN 205Quelle 1.69 : C-XSC-Programm Intervall-Newton-VerfahrenWeitere Beispiele f<strong>in</strong><strong>de</strong>n sich <strong>in</strong> <strong>de</strong>m Buch von RUDI KLATTEund an<strong>de</strong>ren, siehe Anhang H Zum Weiterlesen auf Seite 377.1.7.4 X11-Programmierung mit <strong>de</strong>m Qt-ToolkitDer Quasar-Toolkit (Qt) ist e<strong>in</strong>e Widget-Bibliothek <strong>de</strong>r FirmaTroll Tech (www.troll.no), die sowohl für das X W<strong>in</strong>dow System(X11) als auch für Microsoft W<strong>in</strong>dows erhältlich ist. Für dieEntwicklung freier UNIX-Software ist die Nutzung <strong>de</strong>r Bibliothekkostenlos; vor e<strong>in</strong>iger Zeit hat Troll Tech die Bibliothekunter e<strong>in</strong>e OpenSource-Lizenz (www.opensource.org) gestellt,so daß auch Än<strong>de</strong>rungen an <strong>de</strong>n Quellen erlaubt s<strong>in</strong>d. Bekanntwur<strong>de</strong> Qt als Basis <strong>de</strong>r Arbeitsumgebung KDE (www.k<strong>de</strong>.org).Die X11-Programmierung gestaltet sich mit Qt <strong>de</strong>utlich e<strong>in</strong>facherals mit an<strong>de</strong>ren Bibliotheken (Motif) und ist geprägt e<strong>in</strong>erseitsdurch die Verwendung von <strong>C++</strong>, an<strong>de</strong>rerseits durch <strong>de</strong>nMechanismus von Signalen und Slots; bei<strong>de</strong>s trägt wesentlichzur effizienteren und weniger fehleranfälligen Programmierungbei.Die libQt eignet sich auch hervorragend, um das Konzept <strong>de</strong>robjektorientierten Programmierung besser zu verstehen: Benötigtman beispielsweise e<strong>in</strong>e neue Art von Knopf, entwickelt manauf <strong>de</strong>r Basis <strong>de</strong>r abstrakten Klasse QButton e<strong>in</strong>e neue Klasse,die damit alle Grun<strong>de</strong>igenschaften von Knöpfen erbt (abstraktbe<strong>de</strong>utet hier, daß die Klasse e<strong>in</strong>ige Funktionen enthält, die implementiertwer<strong>de</strong>n müssen, bevor die Klasse verwen<strong>de</strong>t wer<strong>de</strong>nkann); neu schreiben muß man nur noch die FunktionendrawButton() und drawButtonLabel(), die für die eigentlicheDarstellung <strong>de</strong>s Knopfes verantwortlich zeichnen. Diese Vorgehensweiseläßt sich verallgeme<strong>in</strong>ern: Um e<strong>in</strong> neues Widget zuentwickeln, geht man von e<strong>in</strong>em <strong>in</strong> <strong>de</strong>r Bibliothek bereits vorhan<strong>de</strong>nenaus, das <strong>in</strong> se<strong>in</strong>en Eigenschaften <strong>de</strong>m gewünschtenErgebnis möglichst nahe kommt, und schreibt nur diejenigenFunktionen neu, die sich unterschei<strong>de</strong>n beziehungsweise dazukommen.Signale und Slots gestalten die Kommunikation zwischenverschie<strong>de</strong>nen Programmteilen. E<strong>in</strong> Widget (z. B. e<strong>in</strong> Knopf)sen<strong>de</strong>t bei e<strong>in</strong>em bestimmten Ereignis (<strong>de</strong>r Knopf wird vom


206 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Benutzer betätigt) e<strong>in</strong> Signal aus (<strong>in</strong> diesem Fall das Signalclicked()), das vorher mit e<strong>in</strong>em Slot <strong>in</strong> e<strong>in</strong>em an<strong>de</strong>ren Programmteilverbun<strong>de</strong>n wur<strong>de</strong>. Viele Widgets be<strong>in</strong>halten <strong>de</strong>arartigeSlots; selbstverständlich kann man auch <strong>in</strong> se<strong>in</strong>en eigenenKlassen Funktionen als Slots <strong>de</strong>klarieren.Um eigene Klassen mit Slots zu implementieren, ist die Verwendung<strong>de</strong>s Meta Object Compilers moc vonnöten, <strong>de</strong>r, aufdie Klassen<strong>de</strong>klaration angewandt, e<strong>in</strong>ige Makros ersetzt; dieserSchritt ist notwendig, da das Konzept von Signalen und Slotsnicht <strong>in</strong> <strong>C++</strong> enthalten ist. Üblicherweise wird man die Klassen<strong>de</strong>klarationen<strong>in</strong> e<strong>in</strong>er Inclu<strong>de</strong>-Datei unterbr<strong>in</strong>gen, auf das dann<strong>de</strong>r Meta Object Compiler angewandt wird. Die Ausgabe von mocleitet man <strong>in</strong> e<strong>in</strong>e Datei mit <strong>de</strong>r Kennung .moc um, die anstelle<strong>de</strong>r Inclu<strong>de</strong>-Datei mit <strong>de</strong>n Klassen<strong>de</strong>klarationen e<strong>in</strong>gebun<strong>de</strong>nwird.Das folgen<strong>de</strong> Beispiel besteht aus e<strong>in</strong>em Makefile, e<strong>in</strong>erInclu<strong>de</strong>-Datei und <strong>de</strong>m eigentlichen Programm. Das Programmöffnet e<strong>in</strong> Fenster und br<strong>in</strong>gt <strong>in</strong> <strong>de</strong>ssen Mitte e<strong>in</strong>e Beschriftung<strong>in</strong> Form e<strong>in</strong>es für <strong>de</strong>rartige Zwecke klassischen Textes sowie an<strong>de</strong>r Fensterunterseite e<strong>in</strong>en Knopf an. Wird <strong>de</strong>r Knopf betätigt,än<strong>de</strong>rt sich die Beschriftung, und nach 1500 ms been<strong>de</strong>t sich dasProgramm.# Makefile fuer qhello# es wer<strong>de</strong>n die Inclu<strong>de</strong>-Files von X11 und Qt benoetigtINC = -I/usr/X11R6/<strong>in</strong>clu<strong>de</strong> -I/usr/lib/qt/<strong>in</strong>clu<strong>de</strong># gel<strong>in</strong>kt wird gegen die libX11 (<strong>in</strong> /usr/X11R6/lib)# und die libqt (<strong>in</strong> /usr/lib, dort automatisch gesucht)LIB = -L/usr/X11R6/lib -lX11 -lqt# <strong>de</strong>r verwen<strong>de</strong>te <strong>C++</strong>-Compiler - hier GNU <strong>C++</strong>CPP = g++# benoetigt wird neben <strong>de</strong>m Source-Co<strong>de</strong> das moc-Fileall: qhello.cpp qhello.moc$(CPP) -o qhello qhello.cpp $(INC) $(LIB)# moc-File wird aus qhello.h gewonnnen;# moc muss im PATH stehenqhello.moc: qhello.hmoc qhello.h > qhello.moc


1.7. KLASSEN-BIBLIOTHEKEN 207Quelle 1.70 : Makefile zu qhello.cpp/* Inclu<strong>de</strong>-File fuer qhello */// Die Klasse HelloWidget erbt ihre Eigenschaften// von <strong>de</strong>r Klasse QWidgetclass HelloWidget: public QWidget{// Q OBJECT; muss <strong>in</strong> je<strong>de</strong>r Klasse, die Signals o<strong>de</strong>r// Slots implementiert, stehenQ OBJECT;// die Konstruktor-Funktion (ohne void)public:HelloWidget(QWidget *parent = 0, const char *name =// e<strong>in</strong> Signal, das diese Klasse aussen<strong>de</strong>tsignals:void neuerText( const char * );// Po<strong>in</strong>ter fuer verwen<strong>de</strong>te Widgetsprivate:QLabel *helloLabel;QPushButton *quitButton;QTimer *quitTimer;};// e<strong>in</strong> Slot, <strong>de</strong>r spaeter mit quitButton verbun<strong>de</strong>n wirdprivate slots:void tschuess();Quelle 1.71 : Inclu<strong>de</strong>-Datei zu qhello.cpp/* qhello.cpp - Beispiel fuer die Programmierung mit Qt */#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> // benoetigt je<strong>de</strong>s Qt-Programm// fuer unser Hauptfenster// fuer die Beschriftung// fuer <strong>de</strong>n Quit-Button// fuer zeitverzoegertes Been<strong>de</strong>// an dieser Stelle wird das moc-File e<strong>in</strong>gebun<strong>de</strong>n;// es enthaelt die Prototypen fuer unsere Klasse


208 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>#<strong>in</strong>clu<strong>de</strong> "qhello.moc"// die Konstruktorfunktion unserer KlasseHelloWidget::HelloWidget(QWidget *parent, const char *name): QWidget( parent, name ){// die Groesse <strong>de</strong>s Hauptfensters setzenresize( 200, 100 );// e<strong>in</strong>e Beschriftung wird erzeugt und plazierthelloLabel = new QLabel( "hello, world!", this );helloLabel->move( 60, 30 );// Signal neuerText()// dieses Objekts wird mit helloLabel verbun<strong>de</strong>n// setText() ist Slot zum Setzen <strong>de</strong>s Beschriftungstextesconnect(this, SIGNAL(neuerText(const char *)), helloLabel,SLOT( setText( const char * ) ) );// quitButton wird erzeugt und plaziert...quitButton = new QPushButton( "Quit", this );quitButton->move( 0, 80 );quitButton->resize( 200, 20 );}// ... und verbun<strong>de</strong>n mit unserem Slot tschuess()connect(quitButton, SIGNAL(clicked()), this, \SLOT(tschuess()));// unser Slot tschuess(), <strong>de</strong>r mit quitButton verbun<strong>de</strong>n istvoid HelloWidget::tschuess(){// Signal neuerText() aussen<strong>de</strong>n (an helloLabel)emit( neuerText( "Tschuess!!!" ) );// e<strong>in</strong>en Timer e<strong>in</strong>richten und starten, Laufzeit 1500 msquitTimer = new QTimer( this );quitTimer->start( 1500 );}// bei Ablauf <strong>de</strong>s Timers wird Slot quit() <strong>de</strong>r Haupt-// applikation ausgefuehrt, <strong>de</strong>r das Programm been<strong>de</strong>tconnect(quitTimer, SIGNAL(timeout()), qApp, \SLOT(quit()));// Hauptprogramm


1.7. KLASSEN-BIBLIOTHEKEN 209<strong>in</strong>t ma<strong>in</strong>( <strong>in</strong>t argc, char **argv ){// QApplication ist die Klasse fuer die Hauptapplikation// argc und argv muessen uebergeben wer<strong>de</strong>n, um z. B.// geometry-Informationen auszuwertenQApplication Me<strong>in</strong>eAnwendung( argc, argv );// unser HauptwidgetHelloWidget Me<strong>in</strong>Widget;// setzen als Ma<strong>in</strong>Widget <strong>de</strong>r ApplikationMe<strong>in</strong>eAnwendung.setMa<strong>in</strong>Widget( &Me<strong>in</strong>Widget );// und darstellenMe<strong>in</strong>Widget.show();// hiermit wird die Hauptapplikation ausgefuehrtreturn Me<strong>in</strong>eAnwendung.exec();}Quelle 1.72 : <strong>C++</strong>-Programm qhello.cpp mit Verwendung <strong>de</strong>s Qt-ToolkitFür das Hauptfenster wer<strong>de</strong>n e<strong>in</strong> neues Widget von <strong>de</strong>rWidget-Oberklasse QWidget abgeleitet, das Beschriftung undKnopf erzeugt und das Signal clicked(), welches <strong>de</strong>r Knopf beiBetätigung aussen<strong>de</strong>t, mit <strong>de</strong>m klasseneigenen Slot tschuess()verbun<strong>de</strong>n. Dieser Slot sen<strong>de</strong>t das ebenfalls klasseneigene SignalneuerText() aus, das vorher mit <strong>de</strong>m Slot setText() <strong>de</strong>sBeschriftungsfel<strong>de</strong>s verbun<strong>de</strong>n wur<strong>de</strong>. Dieser Slot setzt, se<strong>in</strong>emNamen gemäß, <strong>de</strong>n Text <strong>de</strong>s Beschriftungsfel<strong>de</strong>s neu. Gleichzeitigwird e<strong>in</strong> Timer erzeugt und gestartet, <strong>de</strong>r nach 1500 msdas Signal timeout() aussen<strong>de</strong>t, welches wie<strong>de</strong>rum mit <strong>de</strong>mSlot quit() <strong>de</strong>r Hauptapplikation verbun<strong>de</strong>n wird. Die Funktiondieses Slots ergibt sich ebenfalls aus se<strong>in</strong>em Namen.Dieses Basisprogramm läßt sich unter Zuhilfename <strong>de</strong>r exzellentenOnl<strong>in</strong>e-Dokumentation zu Qt, die sich auf <strong>de</strong>m Webservervon Troll Tech (www.troll.no) f<strong>in</strong><strong>de</strong>t, schnell erweitern. ProbierenSie es aus: Die Programmierung mit Qt ist auch für <strong>C++</strong>-E<strong>in</strong>steiger und Anfänger <strong>in</strong> <strong>de</strong>r X11-Programmierung e<strong>in</strong>fach zuerlernen und zeitigt schnell Erfolgserlebnisse.


210 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.8 Überla<strong>de</strong>n von OperatorenDie arithmetischen Operationen auf Ganzzahlen unterschei<strong>de</strong>nsich von <strong>de</strong>nen auf Gleitkommazahlen, <strong>in</strong>sbeson<strong>de</strong>re die Division.Dennoch verwen<strong>de</strong>n wir dieselben Operatoren. Das Programmerkennt aus <strong>de</strong>m Zusammenhang, welche Art von Operationgefragt ist. Diese Möglichkeit, e<strong>in</strong>em Operator je nachZusammenhang verschie<strong>de</strong>ne Be<strong>de</strong>utungen (Def<strong>in</strong>itionen) zu geben,ist <strong>in</strong> <strong>C++</strong> verallgeme<strong>in</strong>ert wor<strong>de</strong>n und läßt sich auf fastje<strong>de</strong>n Operator und je<strong>de</strong> Funktion aus<strong>de</strong>hnen.Wir sehen uns am Beispiel e<strong>in</strong>es <strong>C++</strong>-Programmes zur Berechnungvon Primzahlen nach <strong>de</strong>m Divisionsverfahren an, wiee<strong>in</strong> Operator überla<strong>de</strong>n wird:/* prim.C, <strong>C++</strong>-Programm zur Berechnung von Primzahlenzu compilieren mit CC -o prim prim.C *//* $Hea<strong>de</strong>r: /home/<strong>de</strong>bian/prog/quellen/primplus.tex,v 1.1.1.1#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> /***********//* Klassen *//***********/class PRIM {// Def<strong>in</strong>ition <strong>de</strong>r Klasse PRIMpublic:PRIM(<strong>in</strong>t, <strong>in</strong>t);PRIM& operator++();<strong>in</strong>t get count();<strong>in</strong>t get prim();// nach aussen sichtbar,// Metho<strong>de</strong>n// Default Constructor// Ueberla<strong>de</strong>n von ++ (Praefix)// Zugriff auf Anzahlen// Zugriff auf Primzahlenprivate:<strong>in</strong>t prim count;<strong>in</strong>t prim number;// nicht nach aussen sichtbar,// Daten// Anzahl <strong>de</strong>r Primzahlen// aktuelle Primzahl};/************//* Metho<strong>de</strong>n */


1.8. ÜBERLADEN VON OPERATOREN 211/************/PRIM::PRIM(<strong>in</strong>t anzahl = 1, <strong>in</strong>t primzahl = 2) // Constructo{prim count = anzahl;prim number = primzahl;}// Folgen<strong>de</strong> (triviale) Zugriffsmetho<strong>de</strong>n s<strong>in</strong>d erfor<strong>de</strong>rlich,// da die Variablen prim count und prim number privat s<strong>in</strong>d<strong>in</strong>t PRIM::get count(){return(prim count);}<strong>in</strong>t PRIM::get prim(){return(prim number);}/***************************************//* Ueberla<strong>de</strong>n <strong>de</strong>s ++ Praefix-Operators *//***************************************/PRIM& PRIM::operator++(){if (prim number == 2) { // Test auf 2prim number++; // 2 + 1 = 3, naechste Primzahl++prim count; // Inkrementierung <strong>de</strong>r Anzahlreturn(*this); // aktuelles Objekt zurueckgeben}for ( ; ; ) {// ewige Schleife, bis breakprim number += 2; // naechste ungera<strong>de</strong> Zahl<strong>in</strong>t prim flag = 1; // true<strong>in</strong>t haelfte = (prim number / 2);for (<strong>in</strong>t i = 3; i < haelfte; i += 2) {if (((prim number / i) * i) == prim number) {prim flag = 0; // false, teilbarbreak;}}if (prim flag) break; // Verlassen <strong>de</strong>r e. S.}++prim count;// Inkrementierung <strong>de</strong>r Anzahl


212 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}return(*this);// aktuelles Objekt zurueckgeben/*****************//* Hauptprogramm *//*****************/<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[]){<strong>in</strong>t max;PRIM pzahl;// Obergrenze// Erzeugung <strong>de</strong>s Objektes pzahl// Obergrenze ermittelnif (argc > 1) {sscanf(*(argv + 1), "%d", &max);}else {cout « "Obergrenze e<strong>in</strong>geben: ";c<strong>in</strong> » max;}// Ueberschrift ausgebencout « "\nPrimzahlen bis " « max « " <strong>in</strong>kl.: \n\n";// Primzahlen berechnen und ausgebenwhile (pzahl.get prim()


1.9. PRÄPROZESSOR 213Schleife. Offenbar wird die jeweils nächste Primzahl durch <strong>de</strong>nPräfix-Operator ++ erreicht, mit <strong>de</strong>m man vor <strong>de</strong>r Überladungnur Ganzzahlen um jeweils 1 <strong>in</strong>krementieren konnte. H<strong>in</strong>ter<strong>de</strong>m überla<strong>de</strong>nen Operator versteckt sich <strong>de</strong>r Algorithmus zurBerechnung <strong>de</strong>r nächsten Primzahl. Hier wird die Teilbarkeit<strong>de</strong>r aktuellen Zahl prime_number dadurch ermittelt, daß siedurch die kle<strong>in</strong>eren ungera<strong>de</strong>n Zahlen i ganzzahlig dividiertund gleich wie<strong>de</strong>r mit <strong>de</strong>m Divisor multipliziert wird. Ergibt sich<strong>de</strong>r alte Divi<strong>de</strong>nd, so verlief die Division ohne Rest, die aktuelleZahl war teilbar und somit ke<strong>in</strong>e Primzahl. So geht es auch, wirwer<strong>de</strong>n im Programm 1.89 auf Seite 251 <strong>de</strong>n modulo-Operatorverwen<strong>de</strong>n.Die Überladung bewirkt, daß <strong>de</strong>r Präfix-Operator ++, angewandtauf e<strong>in</strong> Objekt <strong>de</strong>r Klasse PRIM, die jeweils nächste Primzahlerzeugt. Man hätte auch e<strong>in</strong>en an<strong>de</strong>ren Operator nehmenkönnen. Die für Klassen <strong>de</strong>f<strong>in</strong>ierten Operatoren wie :: dürfennicht überla<strong>de</strong>n wer<strong>de</strong>n, da sie gebraucht wer<strong>de</strong>n. Bei Operatorenwie <strong>de</strong>r Bed<strong>in</strong>gten Bewertung ?: ist schwer vorstellbar,welche neue Be<strong>de</strong>utung sie erhalten sollten.1.9 PräprozessorBeim Aufruf <strong>de</strong>s Compilers wird <strong>de</strong>r Quelltext als erstes von e<strong>in</strong>emPräprozessor bearbeitet. Dieser führt die <strong>de</strong>f<strong>in</strong>e- und<strong>in</strong>clu<strong>de</strong>-Anweisungen aus und entfernt Kommentare sowieZeichenpaare Backslash-Zeilenwechsel (verb<strong>in</strong><strong>de</strong>t Fortsetzungszeilen,<strong>de</strong>r Zeilenwechsel muss unmittelbar auf <strong>de</strong>n Backslashfolgen).1.9.1 <strong>de</strong>f<strong>in</strong>e-AnweisungenDie <strong>de</strong>f<strong>in</strong>e-Anweisung dient zwei Zwecken: Sie <strong>de</strong>f<strong>in</strong>iert symbolischeKonstanten sowie Makros. E<strong>in</strong>e symbolische Konstanteist e<strong>in</strong> konstanter Operand (auch e<strong>in</strong> Str<strong>in</strong>g), <strong>de</strong>r mit <strong>de</strong>r<strong>de</strong>f<strong>in</strong>e-Anweisung Namen und Wert erhält und im weiterenProgramm nur noch mit se<strong>in</strong>em Namen aufgerufen wird:#<strong>de</strong>f<strong>in</strong>e MWST 1.15....brutto = netto * MWST;


214 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Damit erleichtert man Än<strong>de</strong>rungen, die sich so auf e<strong>in</strong>e Stellebeschränken, und vermei<strong>de</strong>t das Auftauchen rätselhafter Zahlen(magic numbers) mitten im Programm. Bei Str<strong>in</strong>gs s<strong>in</strong>d dieGänsefüßchen mit <strong>in</strong> die Def<strong>in</strong>ition zu nehmen und beim Aufrufnicht zu wie<strong>de</strong>rholen.E<strong>in</strong> Makro ist e<strong>in</strong>e nicht zu lange Folge von Ausdrücken undAnweisungen, alternativ zu e<strong>in</strong>er kurzen Funktion. Das Makrowird zu <strong>in</strong>-l<strong>in</strong>e-Co<strong>de</strong> und damit etwas schneller als die Funktion,die Parameterübergabe entfällt. An<strong>de</strong>rerseits wird <strong>de</strong>r ausführbareCo<strong>de</strong> etwas länger. E<strong>in</strong> Beispiel:#<strong>de</strong>f<strong>in</strong>e NEWFILE fpr<strong>in</strong>tf(st<strong>de</strong>rr, "Datei?\n");if (gets(name) == NULL) done()....if (argc < 2) NEWFILE;Der Präprozessor ersetzt je<strong>de</strong>s NEWFILE im Programm buchstäblichdurch die <strong>de</strong>f<strong>in</strong>ierte Folge. Das spart Tipperei und verbessertdie Übersichtlichkeit. Zeichenfolgen <strong>in</strong> Str<strong>in</strong>gkonstanten(<strong>in</strong> Gänsefüßchen) wer<strong>de</strong>n nicht ersetzt; das Progrämmchen:#<strong>de</strong>f<strong>in</strong>e PI 3.14159<strong>in</strong>t ma<strong>in</strong>(){pr<strong>in</strong>tf("Die Zahl PI ist %f\n", PI);}schreibt wie erhofft auf <strong>de</strong>n Bildschirm:Die Zahl PI ist 3.141590Bei arithmetischen Makros muß man aufpassen, damit sie nicht<strong>in</strong>folge von Vorrangregeln <strong>in</strong> unbeabsichtigter Weise ausgeführtwer<strong>de</strong>n; am besten setzt man <strong>de</strong>utliche Klammern:#<strong>de</strong>f<strong>in</strong>e DELTA(a, b) ((a) - (b))Hier können die Ausdrücke a und b aussehen, wie sie wollen,und <strong>in</strong> e<strong>in</strong>e beliebige Umgebung e<strong>in</strong>gebettet se<strong>in</strong>, das Makrowird immer als Differenz <strong>de</strong>r bei<strong>de</strong>n Ausdrücke aufgefaßt. ImGegensatz dazu wür<strong>de</strong> e<strong>in</strong>e Def<strong>in</strong>ition ohne Klammern wie:


1.9. PRÄPROZESSOR 215PROD(a, b) a * b<strong>in</strong> e<strong>in</strong>em Zusammenhang wie:x = n * PROD(r - s, t + u);zu folgen<strong>de</strong>r Ersetzung führen:x = n * r - s * t + u;wie man durch manuelles E<strong>in</strong>setzen leicht nachvollzieht, unddas ist vermutlich nicht das Gewünschte.Mittels <strong>de</strong>r un<strong>de</strong>f-Anweisung wi<strong>de</strong>rruft man e<strong>in</strong>e vorhergehen<strong>de</strong><strong>de</strong>f<strong>in</strong>e-Anweisung. Das kommt selten vor. Hat man e<strong>in</strong>Makro und e<strong>in</strong>e Funktion <strong>de</strong>sselben Namens und will unbed<strong>in</strong>gtdie Funktion haben, so un<strong>de</strong>f<strong>in</strong>iert man das Makro.1.9.2 <strong>in</strong>clu<strong>de</strong>-AnweisungenDie <strong>in</strong>clu<strong>de</strong>-Anweisung führt dazu, dass <strong>de</strong>r Präprozessor dieanschließend genannte Datei (Inclu<strong>de</strong>-Datei, Hea<strong>de</strong>r-Datei, Def<strong>in</strong>itionsdatei)mit zu <strong>de</strong>m Programmtext lädt, bevor dieser zumeigentlichen Compiler gelangt. Die Inclu<strong>de</strong>-Dateien ihrerseitsenthalten symbolische Konstanten und Makros. Grundsätzlichjedoch dürfen sie alles enthalten, was nicht gegen die Regeln vonC/<strong>C++</strong> verstößt, also auch Kommentar o<strong>de</strong>r Programmteile.Die Namen <strong>de</strong>r Standard-Inclu<strong>de</strong>-Dateien s<strong>in</strong>d <strong>in</strong> e<strong>in</strong>zuschließen,die Namen eigener Inclu<strong>de</strong>-Dateien <strong>in</strong> Gänsefüßchen.Letztere wer<strong>de</strong>n zuerst <strong>in</strong> <strong>de</strong>m Verzeichnis gesucht, <strong>in</strong> <strong>de</strong>m auchdas Quellprogramm steht. Falls <strong>de</strong>r Präprozessor dort nicht fündigwird, o<strong>de</strong>r falls <strong>de</strong>r Name <strong>in</strong> spitzen Klammern e<strong>in</strong>geschlossenist, wird <strong>in</strong> vorgegebenen Verzeichnissen wie /usr/<strong>in</strong>clu<strong>de</strong>gesucht. Durch Compileroptionen (siehe man cpp) läßt sich dieSuche steuern.Die Inclu<strong>de</strong>-Dateien s<strong>in</strong>d lesbar und f<strong>in</strong><strong>de</strong>n sich im Verzeichnis/usr/<strong>in</strong>clu<strong>de</strong>, vom Benutzer erstellte Inclu<strong>de</strong>-Dateien imselben Verzeichnis wie die Programmquelle. Die Datei-Kennung.h ist üblich, aber nicht notwendig. Als Beispiel sehen wir unsdie häufig gebrauchte Datei <strong>in</strong> gekürzter Form an:/* @(#) $Revision: 1.1.1.1 $ */


216 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>#ifn<strong>de</strong>f _NFILE#<strong>de</strong>f<strong>in</strong>e _NFILE 60#<strong>de</strong>f<strong>in</strong>e BUFSIZ 1024/** buffer size for multi-character output to* unbuffered files*/#<strong>de</strong>f<strong>in</strong>e _SBFSIZ 8type<strong>de</strong>f struct {<strong>in</strong>t _cnt;unsigned char *_ptr;unsigned char *_base;short _flag;char _file;} FILE;/** _IOLBF means that a file’s output will be buffered* l<strong>in</strong>e by l<strong>in</strong>e.* In addition to be<strong>in</strong>g flags, _IONBF, _IOLBF and _IOFBF* are possible values for "type" <strong>in</strong> setvbuf.*/#<strong>de</strong>f<strong>in</strong>e _IOFBF 0000#<strong>de</strong>f<strong>in</strong>e _IOREAD 0001#<strong>de</strong>f<strong>in</strong>e _IOWRT 0002#<strong>de</strong>f<strong>in</strong>e _IONBF 0004#<strong>de</strong>f<strong>in</strong>e _IOMYBUF 0010#<strong>de</strong>f<strong>in</strong>e _IOEOF 0020#<strong>de</strong>f<strong>in</strong>e _IOERR 0040#<strong>de</strong>f<strong>in</strong>e _IOLBF 0200#<strong>de</strong>f<strong>in</strong>e _IORW 0400#ifn<strong>de</strong>f NULL#<strong>de</strong>f<strong>in</strong>e NULL 0#endif#ifn<strong>de</strong>f EOF#<strong>de</strong>f<strong>in</strong>e EOF (-1)


1.9. PRÄPROZESSOR 217#endif#<strong>de</strong>f<strong>in</strong>e std<strong>in</strong> (&_iob[0])#<strong>de</strong>f<strong>in</strong>e stdout (&_iob[1])#<strong>de</strong>f<strong>in</strong>e st<strong>de</strong>rr (&_iob[2])#ifn<strong>de</strong>f l<strong>in</strong>t#<strong>de</strong>f<strong>in</strong>e get(p) ->_cnt < 0 ? _filbuf(p) : (<strong>in</strong>t) *(p)->_ptr#<strong>de</strong>f<strong>in</strong>e putc(x, p) (--(p)->_cnt < 0 ? \_flsbuf((unsigned char) (x), (p)) : \(<strong>in</strong>t) (*(p)->_ptr++ = (unsigned char) (x)))#<strong>de</strong>f<strong>in</strong>e getchar() getc(std<strong>in</strong>)#<strong>de</strong>f<strong>in</strong>e putchar(x) putc((x), stdout)#<strong>de</strong>f<strong>in</strong>e clearerr(p) ((void) ((p)->_flag &= \~(_IOERR | _IOEOF)))#<strong>de</strong>f<strong>in</strong>e feof(p) ((p)->_flag & _IOEOF)#<strong>de</strong>f<strong>in</strong>e ferror(p) ((p)->_flag & _IOERR)#<strong>de</strong>f<strong>in</strong>e fileno(p) (p)->_file#elsevoid clearerr();#endif not l<strong>in</strong>textern FILE _iob[_NFILE];extern FILE *fopen(), *fdopen(), *freopen(), *popen();extern FILE *tmpfile();extern long ftell();extern void rew<strong>in</strong>d(), setbuf();extern char *ctermid(), *cuserid(), *fgets(), *gets();extern char *tmpnam();extern unsigned char *_bufendtab[];#endif NFILEQuelle 1.74 : Inclu<strong>de</strong>-Datei /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h, gekürztDie Standard-Inclu<strong>de</strong>-Dateien wie stdio.h dürfen <strong>in</strong> beliebigerReihenfolge im Programm aufgeführt wer<strong>de</strong>n, auch mehrmals.Es dürfen auch zwei Standard-Inclu<strong>de</strong>-Dateien aufgeführtwer<strong>de</strong>n, die bei<strong>de</strong> dasselbe Makro <strong>de</strong>f<strong>in</strong>ieren. E<strong>in</strong>e Standard-Inclu<strong>de</strong>-Datei schließt niemals e<strong>in</strong>e an<strong>de</strong>re Standard-Inclu<strong>de</strong>-


218 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Datei e<strong>in</strong>. Wie sich Nichtstandard-Inclu<strong>de</strong>-Dateien verhalten, istoffen.1.9.3 Bed<strong>in</strong>gte Kompilation (#if<strong>de</strong>f)Bei <strong>de</strong>r Programmentwicklung möchte man gelegentlich leichtvone<strong>in</strong>an<strong>de</strong>r abweichen<strong>de</strong> Fassungen e<strong>in</strong>es ausführbaren Programmserzeugen, ohne dafür verschie<strong>de</strong>ne Quellfiles schreibenzu müssen. Unser C-Programm 1.89 auf Seite 251 zur Berechnungvon Primzahlen hat verschie<strong>de</strong>ne Obergrenzen, je nach<strong>de</strong>mob es unter PC-DOS o<strong>de</strong>r UNIX läuft. Im Programmkopfvor ma<strong>in</strong>() stehen daher folgen<strong>de</strong> Zeilen 34 :#if<strong>de</strong>f UNIX#<strong>de</strong>f<strong>in</strong>e MAX (unsigned long)1000000#else#<strong>de</strong>f<strong>in</strong>e MAX (unsigned long)100000#endifDie symbolische (benamte) Konstante MAX soll offenbar aufUNIX-Systemen e<strong>in</strong>en höheren Wert haben als auf PC-DOS-Systemen. Das hängt mit <strong>de</strong>r Speichersegmentierung unter PC-DOS zusammen. Ruft man <strong>de</strong>n Compiler mit e<strong>in</strong>er entsprechen<strong>de</strong>nOption auf:cc -o prim prim.c -DUNIXso wird e<strong>in</strong>e Konstante namens UNIX <strong>de</strong>f<strong>in</strong>iert und <strong>in</strong>folge<strong>de</strong>ssen<strong>de</strong>r if-Zweig vom Präprozessor ausgewertet mit <strong>de</strong>r Folge, daßdie Konstante MAX, die <strong>de</strong>n untersuchten Zahlenbereich nachoben begrenzt, auf e<strong>in</strong>e Million gesetzt wird. Beim Kompilierenunter PC-DOS entfällt die Option -DUNIX.E<strong>in</strong>e zweite Anwendung ist die Erzeugung von Programmversionen,die zwecks Fehlersuche etwas gesprächiger s<strong>in</strong>d als dieEndfassung. Man gibt beispielsweise Zwischenwerte folgen<strong>de</strong>rmaßenaus:#<strong>de</strong>f<strong>in</strong>e DEBUG 134 Manche Compiler verlangen, daß das Doppelkreuz <strong>in</strong> je<strong>de</strong>mFall am Beg<strong>in</strong>n <strong>de</strong>r Zeile steht.


1.9. PRÄPROZESSOR 219<strong>in</strong>t ma<strong>in</strong>(){...#if DEBUGpr<strong>in</strong>tf("Variable x hat <strong>de</strong>n Wert %d\n", x);#endif...}Hier <strong>de</strong>f<strong>in</strong>ieren wir <strong>in</strong> <strong>de</strong>r Programmquelle e<strong>in</strong> symbolische KonstanteDEBUG zu 1 (= true) und veranlassen damit <strong>de</strong>n Präprozessor,die pr<strong>in</strong>tf()-Zeile e<strong>in</strong>zubeziehen. Läuft das Programmfehlerfrei, setzt man im Quellco<strong>de</strong> DEBUG auf null. E<strong>in</strong> an<strong>de</strong>res,im folgen<strong>de</strong>n Programm angewen<strong>de</strong>tes Verfahren fragt nur danach,ob die Konstante DEBUG <strong>de</strong>f<strong>in</strong>iert ist o<strong>de</strong>r nicht./* Programm itox zum Umrechnen von positiven ganzen Zahlenzur Basis 10 auf e<strong>in</strong>e an<strong>de</strong>re Basis, z. B. 16 */#<strong>de</strong>f<strong>in</strong>e DEBUG /* falls gewuenscht */#<strong>de</strong>f<strong>in</strong>e MAX 8 /* max. Stellen Ergebnis */#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t umwan<strong>de</strong>ln(<strong>in</strong>t, <strong>in</strong>t, <strong>in</strong>t *); /* Prototyp */<strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t b; /* neue Basis, als Dezimalzahl */<strong>in</strong>t x; /* umzurechnen<strong>de</strong> Dezimalzahl */<strong>in</strong>t i; /* Schleifenzaehler */<strong>in</strong>t r[MAX]; /* Array <strong>de</strong>s Ergebnisses */while (1) {pr<strong>in</strong>tf("\n\nNeue Basis: "); /* e<strong>in</strong>lesen */scanf("%d", &b);pr<strong>in</strong>tf("Dezimalzahl: ");scanf("%d", &x);if (b < 2) {puts("Basis muss > 1 se<strong>in</strong>.");cont<strong>in</strong>ue;}if (x < 1) {puts("Dezimalzahl muss > 0 se<strong>in</strong>.");


220 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}#if<strong>de</strong>f DEBUGpr<strong>in</strong>tf("\nb = %d#endifcont<strong>in</strong>ue;x = %d\n\n", b, x);for (i = 0; i < MAX; i++) { /* Array nullen */r[i] = 0;}umwan<strong>de</strong>ln(b, x, r); /* rechnen *//*ausgeben */pr<strong>in</strong>tf("Die Dezimalzahl %d lautet zur Basis %d: ", x,for (i = MAX - 1; i >= 0; i-) {pr<strong>in</strong>tf("%d ", r[i]);}} /* En<strong>de</strong> while, Schleife mit control-c verlassen */return 0;}/* Funktion umwan<strong>de</strong>ln() */<strong>in</strong>t umwan<strong>de</strong>ln(<strong>in</strong>t b, <strong>in</strong>t z, <strong>in</strong>t *r){<strong>in</strong>t i, j, y;while (z >= 1) {y = 1;for (i = 0; y


1.10. DOKUMENTATION 221r[i] = j; /* Ausgabe <strong>in</strong> Array */} /* En<strong>de</strong> while */return 0;}Quelle 1.75 : C-Programm itox.c zur Umrechnung von Dezimalzahlenauf e<strong>in</strong>e an<strong>de</strong>re Basis1.9.4 Memo Präprozessor• Im ersten Schritt <strong>de</strong>s Kompiliervorgangs durchläuft dieProgrammquelle <strong>de</strong>n Präprozessor.• Der Präprozessor entfernt Kommentar, ersetzt symbolischeKonstanten und Makros zeichengetreu, fügt <strong>de</strong>n Inhalt vonInclu<strong>de</strong>-Dateien e<strong>in</strong> und berücksichtigt bzw. verwirft Programmzeilen,die bed<strong>in</strong>gt zu kompilieren s<strong>in</strong>d.1.9.5 Übung PräprozessorErgänzen Sie das Programm zur Weganalyse dah<strong>in</strong>gehend, daßes <strong>in</strong> <strong>de</strong>r DEBUG-Version nach je<strong>de</strong>r Teilstrecke die Zwischenergebnisseauf <strong>de</strong>m Bildschirm ausgibt, <strong>in</strong> <strong>de</strong>r Endversion nur dasGesamtergebnis.Schreiben Sie ferner alle Str<strong>in</strong>gkonstanten <strong>in</strong> e<strong>in</strong>e Inclu<strong>de</strong>-Datei, von <strong>de</strong>r Sie e<strong>in</strong>e <strong>de</strong>utsche und e<strong>in</strong>e englische o<strong>de</strong>r französischeFassung herstellen. Beim Compiler-Aufruf soll mittelse<strong>in</strong>er Option die Sprache ausgewählt wer<strong>de</strong>n.1.10 Dokumentation1.10.1 ZweckDie Dokumentation dient dazu, e<strong>in</strong> Programm im Quellco<strong>de</strong> e<strong>in</strong>emmenschlichen Leser verständlich zu machen. Längere undokumentierteProgramme s<strong>in</strong>d nicht nachzuvollziehen. E<strong>in</strong>e Dokumentation35 gehört zu je<strong>de</strong>m Programm, das länger als e<strong>in</strong>eSeite ist und länger als e<strong>in</strong>en Tag benutzt wer<strong>de</strong>n soll.35 Real programmers write programs, not documentation.


222 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>An<strong>de</strong>rerseits zählt das Schreiben von Dokumentationen nichtzu <strong>de</strong>n Liebl<strong>in</strong>gsbeschäftigungen <strong>de</strong>r Programmierer, das Erfolgserlebnisfehlt. Wir stellen hier e<strong>in</strong>ige Regeln auf, die fürProgramme zum Eigengebrauch gelten; bei kommerziellen Programmengehen die For<strong>de</strong>rungen weiter.Die erste Gelegenheit zum Dokumentieren ist <strong>de</strong>r Kommentarim Programm. Man soll reichlich kommentieren, aber ke<strong>in</strong>enichtssagen<strong>de</strong>n Bemerkungen e<strong>in</strong>flechten. Wenn <strong>de</strong>r Kommentaretwa die Hälfte <strong>de</strong>s ganzen Programms ausmacht, ist dasnoch nicht übertrieben.1.10.2 Anfor<strong>de</strong>rungen (DIN 66 230)Zur Dokumentation legt die Norm DIN 66 230 ProgrammdokumentationBegriffe und Regeln fest. E<strong>in</strong>e weitere Norm ist<strong>de</strong>r ANSI/IEEE Std 1063-1987 Standard for Software User Documentation<strong>in</strong> Verb<strong>in</strong>dung mit e<strong>in</strong>er Reihe weiterer IEEE-Standards. Wir verwen<strong>de</strong>n folgen<strong>de</strong> vere<strong>in</strong>fachte Glie<strong>de</strong>rung:1. Allgeme<strong>in</strong>es• Name <strong>de</strong>s Programms, Programmart (Vollprogramm,Funktion)• Zweck <strong>de</strong>s Programms• Programmiersprache• Computertyp, Betriebssystem• Geräte (Drucker, Plotter, Maus)• Struktur als Grafik, Fließbild• externe Unterprogramme, soweit verwen<strong>de</strong>t2. Anwendung• Aufruf• Konstante, Variable• E<strong>in</strong>gabe (von Tastatur, aus Dateien)• Ausgabe (zum Bildschirm, Drucker, <strong>in</strong> Dateien)• E<strong>in</strong>schränkungen• Fehlermeldungen


1.10. DOKUMENTATION 223• Beispiel• Speicherbedarf• Zeitbedarf3. Verfahren• Algorithmus• Genauigkeit• Gültigkeitsbereich• Literatur zum Verfahren4. Bearbeiter• Name, Datum <strong>de</strong>r Erstellung• Name, Datum von Än<strong>de</strong>rungenDas sieht nach Arbeit aus. Man braucht nicht <strong>in</strong> allen Fällenalle Punkte zu berücksichtigen, aber ohne e<strong>in</strong>e solche Dokumentationläßt sich e<strong>in</strong> Programm nicht zuverlässig benutzen undweiterentwickeln. Im Netz f<strong>in</strong><strong>de</strong>n sich Werkzeuge, die <strong>in</strong> Verb<strong>in</strong>dungmit <strong>de</strong>m Kommentar und <strong>de</strong>r Struktur e<strong>in</strong>es Programmeshalbautomatisch e<strong>in</strong>e Dokumentation erstellen. E<strong>in</strong> Beispiel istDoxygen:http://www.doxygen.org/Zweckmäßig beschäftigt man sich mit solchen Werkzeugen frühzeitig,nicht erst, wenn <strong>de</strong>r Co<strong>de</strong> fast fertig ist.1.10.3 Erstellen e<strong>in</strong>er man-SeiteDie <strong>in</strong>haltliche Glie<strong>de</strong>rung e<strong>in</strong>er man-Seite wur<strong>de</strong> bereits im Abschnitt?? Wo schlägt man nach? auf Seite ?? erläutert. Hier gehtes um die technische Herstellung. Hilfreich s<strong>in</strong>d die man-Seitenzu man(1) und man(5).Das Kommando man(1) sucht die Dokumentationen <strong>in</strong> <strong>de</strong>ndurch die Umgebungs-Variable MANPATH bekannten Verzeichnissen.Das ist heute e<strong>in</strong>e lange Aufzählung, oft länger als dieunter PATH. Vom Benutzer e<strong>in</strong>gerichtete o<strong>de</strong>r erstellte man-Seiten liegen vor allem unter:


224 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>• /usr/local/man/• /usr/share/man/• /opt/*/man/In diesen Verzeichnissen f<strong>in</strong><strong>de</strong>n sich für je<strong>de</strong> Sektion von 1 bis 9bis zu vier Arten von Unterverzeichnissen:• catx• catx.Z• manx• manx.Zwobei für x die Sektionsnummer e<strong>in</strong>zusetzen ist. Die Z-Verzeichnisse enthalten die Dokumentationen komprimiertmit compress(1) (unter LINUX mit GNU-zip), die bei<strong>de</strong>nan<strong>de</strong>ren Verzeichnisse die unkomprimierten Texte.Die man-Verzeichnisse enthalten nroff(1)-Quelltexte, diecat-Verzeichnisse die formatierten, druckfertigen Texte.Im Verzeichnis /usr/share/man/man1.Z/ f<strong>in</strong><strong>de</strong>t sich beispielsweisedie Datei ls.1 mit <strong>de</strong>r komprimierten nroff-Quelle <strong>de</strong>r man-Seite zum Kommando ls(1). Gegebenenfallsliegt unter /usr/share/man/man1/ die entkomprimiertenroff-Quelle. Unter /usr/share/man/cat1.Z und/usr/share/man/cat1/ liegen die formatierten Seiten.Mittels:cat /usr/share/man/cat1.Z/ls.1 | uncompress | morekönnte man sich e<strong>in</strong>e man-Seite anschauen, mit man(1) geht ese<strong>in</strong>facher.Will man selbst e<strong>in</strong>e man-Seite schreiben, kopiert man sicham besten e<strong>in</strong>e ähnliche man-Seite:cat /usr/share/man/man1.Z/pwd.1 | uncompress > mycommand.1und editiert diese. Vermutlich muß man sich vorher etwasmit <strong>de</strong>m nroff-Format ause<strong>in</strong>an<strong>de</strong>rsetzen und mit <strong>de</strong>n unterman(5) beschriebenen Makros. Die so erzeugte unkomprimiertenroff(1)-Quelle gehört <strong>in</strong> e<strong>in</strong> man-Verzeichnis. Die mittelscompress(1) verdichtete Qelle kommt ohne die Kennung .Znach man.Z/. Dann formatiert man die Quelle:


1.11. WEITERE C-PROGRAMME 225nroff mycommand.1 > mycommand.1.catund kopiert sie unter <strong>de</strong>m Namen mycommand.1 <strong>in</strong> e<strong>in</strong> cat-Verzeichnis. Schließlich ist die formatierte Datei zu komprimierenund <strong>in</strong> e<strong>in</strong> cat.Z-Verzeichnis zu stellen. Die Datei heißt <strong>in</strong>je<strong>de</strong>r Fassung immer nur mycommand.1, das Format ergibt sichaus <strong>de</strong>m jeweiligen Verzeichnis. Man braucht nicht alle Formatezu erzeugen, e<strong>in</strong>es reicht.Im WWW hat die Open Group unter <strong>de</strong>m URL:http://www.opengroup.org/common_access/e<strong>in</strong> umfangreiche Zusammenstellung von man-Seiten samtSuchmasch<strong>in</strong>e veröffentlicht. E<strong>in</strong>e Suche nach <strong>de</strong>m Begriff timeergab 43 Seiten, von at(1) bis xshrealtime(). Die Zusammenstellunggehört zur S<strong>in</strong>gle UNIX Specification un<strong>de</strong>nthält nicht die Seiten von zusätzlichen Programmen wiesendmail(1).In <strong>de</strong>r GNU-Welt ist für onl<strong>in</strong>e-Hilfen das Tex<strong>in</strong>fo-Format gebräuchlich,das mittels <strong>de</strong>s Kommandos <strong>in</strong>fo(1) gelesen wird.E<strong>in</strong>zelheiten am besten im WWW. Damit kommen wir zu e<strong>in</strong>emdritten Weg für onl<strong>in</strong>e-Dokumentationen, nämlich HTML-Seiten, die mit e<strong>in</strong>em WWW-Browser gelesen wer<strong>de</strong>n. Trotz <strong>de</strong>rerweiterten Möglichkeiten (Unterteilung e<strong>in</strong>es umfangreichenThemas, Hyperl<strong>in</strong>ks, Grafik) dieser neueren Formate s<strong>in</strong>d diedürren man-Seiten immer noch am weitesten verbreitet. Inhaltlichs<strong>in</strong>d sie <strong>de</strong>n Hilfen an<strong>de</strong>rer Betriebssysteme ohneh<strong>in</strong> haushochüberlegen.1.11 Weitere C-Programme1.11.1 NameObwohl es aus <strong>de</strong>n bisherigen Beispielen klar gewor<strong>de</strong>n se<strong>in</strong>müßte, weisen wir nochmals darauf h<strong>in</strong>: Je<strong>de</strong>s selbständige C-Programm heißt im Quellco<strong>de</strong> ma<strong>in</strong>(), e<strong>in</strong> an<strong>de</strong>rer Programmnamekommt – außer im Kommentar – nirgends im Quelltextvor (<strong>in</strong> FORTRAN o<strong>de</strong>r PASCAL sieht die Sache an<strong>de</strong>rs aus).Der Name <strong>de</strong>r Datei, <strong>in</strong> <strong>de</strong>r <strong>de</strong>r kompilierte Co<strong>de</strong> steht, ist <strong>de</strong>rName, unter <strong>de</strong>m das Programm aufgerufen wird.


226 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Der Name <strong>de</strong>r Datei, <strong>in</strong> <strong>de</strong>r <strong>de</strong>r Quellco<strong>de</strong> zu f<strong>in</strong><strong>de</strong>n ist, hatdie Kennung .c; die meisten Programmierwerkzeuge erwartendas. Die UNIX-Compiler schreiben standardmäßig das kompilierteProgramm <strong>in</strong> e<strong>in</strong>e Datei namens a.out; Microsoft Quick-C nimmt <strong>de</strong>n Namen <strong>de</strong>s Quellfiles ohne die Kennung. In bei<strong>de</strong>nFällen kann man mit <strong>de</strong>r Compiler-Option -o für das Ausgabefilee<strong>in</strong>en beliebigen an<strong>de</strong>ren Namen vere<strong>in</strong>baren.1.11.2 AufbauWir kennen nun die Bauste<strong>in</strong>e, aus <strong>de</strong>nen sich e<strong>in</strong> Programmzusammensetzt. Wie sieht e<strong>in</strong> vollständiges Programm aus? Zunächste<strong>in</strong>ige Begriffe zum Aufbau von Programmen.Die kle<strong>in</strong>ste E<strong>in</strong>heit, die etwas bewirkt, ist die Anweisung.Mehrere Anweisungen können zu e<strong>in</strong>em durch geschweifteKlammern zusammengefaßten Block vere<strong>in</strong>igt wer<strong>de</strong>n. Nachaußen wirkt dieser Block wie e<strong>in</strong>e e<strong>in</strong>zige Anweisung. Der Blockist zugleich die kle<strong>in</strong>ste E<strong>in</strong>heit für <strong>de</strong>n Geltungsbereich von Variablen.Mehrere Anweisungen o<strong>de</strong>r Blöcke wer<strong>de</strong>n zu e<strong>in</strong>er Funktionzusammengefaßt. Die Funktion ist die kle<strong>in</strong>ste kompilierbareE<strong>in</strong>heit. E<strong>in</strong>e o<strong>de</strong>r mehrere Funktionen können <strong>in</strong> e<strong>in</strong>er Dateiabgelegt se<strong>in</strong>. Dem Compiler übergibt man im M<strong>in</strong>imum e<strong>in</strong>eDatei, die e<strong>in</strong>e Funktion enthält. Mehrere Dateien h<strong>in</strong>wie<strong>de</strong>rumkönnen e<strong>in</strong> vollständiges, nach <strong>de</strong>m Kompilieren lauffähigesProgramm bil<strong>de</strong>n. Er<strong>in</strong>nern Sie sich an das Werkzeugmake(1)?Das M<strong>in</strong>imalprogramm <strong>in</strong> C und <strong>C++</strong> besteht aus e<strong>in</strong>er Funktion– nämlich ma<strong>in</strong>() – <strong>de</strong>ren Rumpf leer ist, <strong>in</strong> e<strong>in</strong>er Datei:ma<strong>in</strong>(){}Quelle 1.76 : M<strong>in</strong>imales C-ProgrammDer Name ma<strong>in</strong>() ist für das Hauptprogramm vorgeschrieben.ma<strong>in</strong>() ist e<strong>in</strong>e Funktion, daher die bei<strong>de</strong>n run<strong>de</strong>nKlammern. Der durch die geschweiften Klammern umschlosseneBlock ist leer, ma<strong>in</strong>() tut nichts. Der Syntaxprüfer l<strong>in</strong>t(1)beanstan<strong>de</strong>t, daß <strong>de</strong>r Rückgabewert von ma<strong>in</strong>() un<strong>de</strong>f<strong>in</strong>iert ist,


1.11. WEITERE C-PROGRAMME 227was stimmt, uns aber nicht weiter stört. Der Compiler erzeugtaus diesem Quellco<strong>de</strong> etwa 16 kB ausführbaren Co<strong>de</strong>. H<strong>in</strong>terma<strong>in</strong>() steckt e<strong>in</strong>iges, was <strong>de</strong>m Programmierer verborgen ist.Als nächstes wollen wir ma<strong>in</strong>() als ganzzahlig <strong>de</strong>klarieren,für e<strong>in</strong>en <strong>de</strong>f<strong>in</strong>ierten Rückgabewert sorgen und – wie es sichgehört – mittels e<strong>in</strong>es Kommentars das Verständnis erleichtern:/* Dies ist e<strong>in</strong> e<strong>in</strong>faches C-Programm von hohempaedagogischen, aber sonst ke<strong>in</strong>em Wert. */<strong>in</strong>t ma<strong>in</strong>(){return 255; /* 255 groesster zulaessiger Wert */}Quelle 1.77 : C-Programm, e<strong>in</strong>fachstDieses Programm wird vom l<strong>in</strong>t(1) gutgeheißen. Die Deklarationvon ma<strong>in</strong>() als <strong>in</strong>t könnte entfallen, da sie unabän<strong>de</strong>rlichist, aber wir wollen uns angewöhnen, alle Größen ausdrücklichzu <strong>de</strong>klarieren. Den Rückgabewert können Sie sich mit<strong>de</strong>m Shell-Kommando pr<strong>in</strong>t $? nach <strong>de</strong>r Ausführung anschauen.Um etwas Vernünftiges zu tun, muß das Programm um e<strong>in</strong>igeZeilen angereichert wer<strong>de</strong>n. Wir <strong>de</strong>klarieren e<strong>in</strong>e <strong>in</strong>t-Variablenamens i, weisen ihr e<strong>in</strong>en Wert zu (<strong>de</strong>f<strong>in</strong>ieren<strong>de</strong> Deklaration)und verwen<strong>de</strong>n die C-Standardfunktion pr<strong>in</strong>tf(3) für dieAusgabe auf stdout, <strong>de</strong>n Bildschirm. pr<strong>in</strong>tf(3) erwartet alserstes und notwendiges Argument e<strong>in</strong>en Formatstr<strong>in</strong>g, <strong>de</strong>ssenreichhaltige Syntax Sie im Referenz-Handbuch f<strong>in</strong><strong>de</strong>n./* Dies ist e<strong>in</strong> e<strong>in</strong>faches C-Programm von hohempaedagogischen, aber sonst fast ke<strong>in</strong>em Wert. */<strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t i = 53;pr<strong>in</strong>tf("\nDer Wert betraegt %d\n", i);return i;}Quelle 1.78 : C-Programm, e<strong>in</strong>fach


228 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Nun soll auch <strong>de</strong>r Präprozessor Arbeit bekommen. Wir <strong>de</strong>f<strong>in</strong>ierene<strong>in</strong>e symbolische Konstante NUMBER und schließen vorsichtshalberdie Inclu<strong>de</strong>-Datei stdio.h e<strong>in</strong>, die man immerbraucht, wenn es um E<strong>in</strong>- o<strong>de</strong>r Ausgabe geht. Weiterh<strong>in</strong> verwen<strong>de</strong>nwir e<strong>in</strong>en arithmetischen Operator und e<strong>in</strong>e Zuweisung:/* Dies ist e<strong>in</strong> fortgeschrittenes C-Programm */#<strong>de</strong>f<strong>in</strong>e NUMBER 2#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t i = 53, x;x = i + NUMBER;pr<strong>in</strong>tf("\nDer Wert betraegt %d\n", x);return 0;}Quelle 1.79 : C-Programm, fortgeschrittenDa e<strong>in</strong> Ausdruck se<strong>in</strong> Ergebnis zurückgibt, können wir <strong>in</strong> <strong>de</strong>rFunktion pr<strong>in</strong>tf(3) anstelle von x auch die Summe h<strong>in</strong>schreiben.Als Rückgabewert unseres Hauptprogrammes wollen wir<strong>de</strong>n Rückgabewert <strong>de</strong>r Funktion pr<strong>in</strong>tf(3) haben, nämlich dieAnzahl <strong>de</strong>r ausgegebenen Zeichen. Das Programm wird kürzer,aber auch schwieriger zu verstehen (falls man nicht e<strong>in</strong> alter C-Hase ist):/* Dies ist e<strong>in</strong> kle<strong>in</strong>es C-Programm */#<strong>de</strong>f<strong>in</strong>e NUMBER 2#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t i = 53;return (pr<strong>in</strong>tf("\nDer Wert betraegt %d\n", i + NUMBER));}Quelle 1.80 : C-Programm, fortgeschritten, Variante


1.11. WEITERE C-PROGRAMME 229Der ausführbare Co<strong>de</strong> ist damit auf 35 KB angewachsen.Jetzt wollen wir die bei<strong>de</strong>n Summan<strong>de</strong>n im Dialog erfragen unddie Summe als Makro schreiben. Außer<strong>de</strong>m soll die Rechnungwie<strong>de</strong>rholt wer<strong>de</strong>n, bis wir e<strong>in</strong>e Null e<strong>in</strong>geben:/* Endlich mal was Vernuenftiges */#<strong>de</strong>f<strong>in</strong>e SUMME(x, y) (x + y)#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t a = 1, b, i = 0;while (a != 0) {pr<strong>in</strong>tf("Ersten Summan<strong>de</strong>n e<strong>in</strong>geben : ");scanf("%d", &a);pr<strong>in</strong>tf("Zweiten Summan<strong>de</strong>n e<strong>in</strong>geben: ");scanf("%d", &b);pr<strong>in</strong>tf("Die Summe ist %d\n", SUMME(a, b));i++;}return i;}Quelle 1.81 : C-Programm mit E<strong>in</strong>gabeDer Rückgabewert ist die Anzahl <strong>de</strong>r Schleifendurchläufe.Die Str<strong>in</strong>gkonstanten wer<strong>de</strong>n nicht mit puts(3) ausgegeben,da diese Funktion e<strong>in</strong>en hier unerwünschten Zeilenvorschub anfügt.Denken Sie daran, daß die Funktion scanf(3) Po<strong>in</strong>ter alsArgumente braucht!1.11.3 FehlersucheE<strong>in</strong>ige Gesichtspunkte s<strong>in</strong>d bereits im Abschnitt 1.2.4 Debuggerauf Seite 39 behan<strong>de</strong>lt wor<strong>de</strong>n. Der erfahrene Programmiererunterschei<strong>de</strong>t sich vom Anfänger <strong>in</strong> drei Punkten:• Er macht raff<strong>in</strong>iertere Fehler.• Er weiß das.• Er kennt die Wege und Werkzeuge zur Fehlersuche.


230 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Fehlerfreie Programme schreibt auch <strong>de</strong>r beste Programmierernicht. Deshalb ist es wichtig, schon beim Programmentwurf andie Fehlersuche zu <strong>de</strong>nken und vor allem das Programm so zu gestalten,daß es bei e<strong>in</strong>em Fehler nicht e<strong>in</strong> richtiges Ergebnis vortäuscht.Das ist so ungefähr das Schlimmste, was e<strong>in</strong> Programmmachen kann. Dann lieber noch e<strong>in</strong> knallharter Absturz. Besserist e<strong>in</strong>e sanfte Notlandung mit e<strong>in</strong>er aussagekräftigen Fehlermeldung.Die Programme<strong>in</strong>heiten (Funktionen) lasse man nicht zu umfangreichwer<strong>de</strong>n. E<strong>in</strong> bis zwei Seiten Quelltext überschaut mannoch, wird es mehr, sollte man die Funktion unterteilen. Weiterh<strong>in</strong>gebe man im Entwicklungsstadium an kritischen Stellen dieWerte mittels pr<strong>in</strong>tf() o<strong>de</strong>r fpr<strong>in</strong>tf() aus. Diese Zeilen kommentiertman später aus o<strong>de</strong>r klammert sie gleich <strong>in</strong> #if<strong>de</strong>fund#endif-Anweisungen e<strong>in</strong>. Bewährt hat sich auch, die eigenenProgramme e<strong>in</strong>em an<strong>de</strong>ren zu erklären, da wun<strong>de</strong>rt mansich manchmal über <strong>de</strong>n eigenen Co<strong>de</strong>. E<strong>in</strong> Programm, das mannach e<strong>in</strong> bis zwei Wochen Pause selbst nicht mehr versteht, warvon vornhere<strong>in</strong> nicht gelungen.Und wenn dann <strong>de</strong>r Computerfreak zu nächtlicher Stun<strong>de</strong><strong>de</strong>n Bugs h<strong>in</strong>terherjagt, schließt sich e<strong>in</strong> weiter Bogen zurück<strong>in</strong> die Krei<strong>de</strong>zeit, <strong>de</strong>nn die ersten Säugetiere – Zeitgenossen <strong>de</strong>rSaurier – waren auch nachtjagen<strong>de</strong> Insektenfresser.1.11.4 OptimierungDas erste und wichtigste Ziel beim Programmieren ist – nächst<strong>de</strong>r selbstverständlichen, aber unerreichbaren Fehlerfreiheit –die Übersichtlichkeit. Erst wenn e<strong>in</strong> Programm sauber läuft,<strong>de</strong>nkt man über e<strong>in</strong>e Optimierung nach. Optimieren heißtschneller machen und Speicher e<strong>in</strong>sparen, sowohl beim Co<strong>de</strong> wieauch zur Laufzeit. Diese bei<strong>de</strong>n Ziele wi<strong>de</strong>rsprechen sich manchmal.Im folgen<strong>de</strong>n f<strong>in</strong><strong>de</strong>t man e<strong>in</strong>ige H<strong>in</strong>weise, die teils allgeme<strong>in</strong>,teils nur für C gelten.Die optimieren<strong>de</strong> Compiler-Option -O ist mit Vorsicht zugebrauchen. Es kommt vor, daß e<strong>in</strong> optimiertes Programm nichtmehr läuft. Die Gew<strong>in</strong>ne durch die Optimierung s<strong>in</strong>d auch nurmäßig. Immerh<strong>in</strong>, <strong>de</strong>r Versuch ist nicht strafbar.Als erstes schaut man sich die Schleifen an, von geschachteltendie <strong>in</strong>nersten. Dort sollte nur das Allernotwendigste stehen.


1.11. WEITERE C-PROGRAMME 231Bed<strong>in</strong>gungen sollten so e<strong>in</strong>fach wie möglich formuliert se<strong>in</strong>.Mehrfache Bed<strong>in</strong>gungen sollten darauf untersucht wer<strong>de</strong>n, obsie durch e<strong>in</strong>fache ersetzt wer<strong>de</strong>n können. Schleifen sollten möglichstdadurch been<strong>de</strong>t wer<strong>de</strong>n, daß die Kontrollvariable <strong>de</strong>nWert Null und nicht irgen<strong>de</strong><strong>in</strong>en an<strong>de</strong>ren Wert erreicht. Kontrollvariablekönnen auch heruntergezählt wer<strong>de</strong>n statt herauf.E<strong>in</strong>e Bed<strong>in</strong>gung mit mehreren ands o<strong>de</strong>r ors wird so langeausgewertet, bis die Richtigkeit o<strong>de</strong>r Falschheit <strong>de</strong>s gesamtenAusdrucks erkannt ist. S<strong>in</strong>d mehrere Bed<strong>in</strong>gungen durch or verbun<strong>de</strong>n,wird die Auswertung nach Erkennen <strong>de</strong>s ersten richtigenGlie<strong>de</strong>s abgebrochen. Zweckmäßig stellt man das Glied, dasam häufigsten richtig ist, an <strong>de</strong>n Anfang. Umgekehrt ist e<strong>in</strong> Ausdruckmit durch and verbun<strong>de</strong>nen Glie<strong>de</strong>rn falsch, sobald e<strong>in</strong>Glied falsch ist. Das am häufigsten falsche Glied gehört an <strong>de</strong>nAnfang.Ähnliche Überlegungen gelten für die switch-Anweisung.Die häufigste Auswahl sollte als erste abgefragt wer<strong>de</strong>n. Ist das<strong>de</strong>r <strong>de</strong>fault-Fall, kann er durch e<strong>in</strong>e eigene if-Abfrage vor <strong>de</strong>rAuswahl abgefangen wer<strong>de</strong>n.Überflüssige Typumwandlungen – <strong>in</strong>sbeson<strong>de</strong>re die unauffälligenimpliziten – sollten zum<strong>in</strong><strong>de</strong>st <strong>in</strong> Schleifen vermie<strong>de</strong>nwer<strong>de</strong>n. Der Typ numerischer Konstanten sollte von vornhere<strong>in</strong>zu <strong>de</strong>n weiteren Operan<strong>de</strong>n passen. Beispielsweise führtfloat f, g;g = f + 1.2345;zu e<strong>in</strong>er Typumwandlung von f <strong>in</strong> double und e<strong>in</strong>er Rückwandlung<strong>de</strong>s Ergebnisses <strong>in</strong> float, da Gleitkommakonstanten standardmäßigvom Typ double s<strong>in</strong>d.Gleitkommarechnungen s<strong>in</strong>d aufwendiger als Rechnungenmit ganzen Zahlen und haben zu<strong>de</strong>m noch Tücken <strong>in</strong>folgevon Rundungsfehlern. E<strong>in</strong>e Gleitkomma-Null ist nicht immerwirklich null. Wer mit Geldbeträgen rechnet, sollte mit ganzzahligenCentbeträgen anstelle von gebrochenen Eurobeträgenarbeiten. Wenn schon mit Gleitkommazahlen gerechnet wer<strong>de</strong>nmuß und <strong>de</strong>r Speicher ausreicht, ist <strong>de</strong>r Typ double vorzuziehen,<strong>de</strong>r <strong>in</strong>tern ausschließlich verwen<strong>de</strong>t wird.Von zwei möglichen Operationen ist immer die e<strong>in</strong>facherezu wählen. Beispielsweise ist e<strong>in</strong>e Addition e<strong>in</strong>facher als e<strong>in</strong>eMultiplikation, e<strong>in</strong>e Multiplikation e<strong>in</strong>facher als e<strong>in</strong>e Potenz


232 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>und e<strong>in</strong>e Bitverschiebung e<strong>in</strong>facher als e<strong>in</strong>e Multiplikation mit2. E<strong>in</strong>e Abfrageif (x < sqrt(y))schreibt man besserif (x * x < y)Manchmal kann man durch Umstellen e<strong>in</strong>er Formel die Anzahl<strong>de</strong>r Rechenschritte verr<strong>in</strong>gern. Ob man mehrfach benötigte Zwischenergebnissespeichert o<strong>de</strong>r besser je<strong>de</strong>smal neu berechnet,ist nicht allgeme<strong>in</strong> zu entschei<strong>de</strong>n.Kle<strong>in</strong>e Funktionen lassen sich durch Makros ersetzen, dievom Präprozessor <strong>in</strong> In-l<strong>in</strong>e-Co<strong>de</strong> umgewan<strong>de</strong>lt wer<strong>de</strong>n. Damiterspart man sich <strong>de</strong>n Funktionsaufruf samt Parameterübergabe.Der ausführbare Co<strong>de</strong> wird ger<strong>in</strong>gfügig länger.Enthält e<strong>in</strong>e Schleife nur e<strong>in</strong>en Funktionsaufruf, ist es besser,die Schleife <strong>in</strong> die Funktion zu verlegen, da je<strong>de</strong>r FunktionsaufrufZeit kostet.Die maßvolle Verwendung globaler Variabler verbessertzwar nicht <strong>de</strong>n Stil, aber die Geschw<strong>in</strong>digkeit von Programmenmit vielen Funktionsaufrufen, da die Parameterübergabe entfällt.Die Verwendung von Bibliotheksfunktionen kann <strong>in</strong> oftdurchlaufenen Schleifen stärker verzögern als <strong>de</strong>r E<strong>in</strong>satz spezialisierterselbstgeschriebener Funktionen, da Bibliotheksfunktionenallgeme<strong>in</strong> und k<strong>in</strong><strong>de</strong>rsicher s<strong>in</strong>d. Verwen<strong>de</strong>n Sie die e<strong>in</strong>fachsteFunktion, die <strong>de</strong>n Zweck erfüllt, also puts(3) anstellevon pr<strong>in</strong>tf(3), wenn es nur um die Ausgabe e<strong>in</strong>es Str<strong>in</strong>gs samtZeilenwechsel geht.Die Adressierung von Arrayelementen durch Indizes ist langsamerals die Adressierung durch Po<strong>in</strong>ter. Der Prozessor kenntnur Adressen, also muß er Indizes erst <strong>in</strong> Adressen umrechnen.Das erspart man ihm, wenn man gleich mit Adressen sprichPo<strong>in</strong>tern arbeitet. Wer die Po<strong>in</strong>terei noch nicht gewohnt ist,schreibt das Programm zunächst mit Indizes, testet es aus undstellt es dann auf Po<strong>in</strong>ter um. E<strong>in</strong> Beispiel:long i, j, a[32];/* Adressierung durch Indizes, langsam */a[0] = a[i] + a[j];


1.11. WEITERE C-PROGRAMME 233/* Adressierung durch Po<strong>in</strong>ter, schnell */*a = *(a + i) + *(a + j);Wir er<strong>in</strong>nern uns, <strong>de</strong>r Name e<strong>in</strong>es Arrays ist <strong>de</strong>r Po<strong>in</strong>ter aufdas erste Element (mit <strong>de</strong>m In<strong>de</strong>x 0). Experimente mit verschie<strong>de</strong>nenCompilern haben allerd<strong>in</strong>gs <strong>de</strong>n Verdacht geschürt, dassmanche Compiler von sich aus die schnellere Variante (Po<strong>in</strong>ter)wählen. Übergeben Sie große Strukturen als Po<strong>in</strong>ter, nicht alsVariable. Dadurch spart man das Kopieren <strong>de</strong>r Daten.Input/Output ist immer zeitaufwendig. In vielen Programmengeht für diese Aufgabe sogar <strong>de</strong>r größte Teil <strong>de</strong>r Zeit drauf.Also unnötigen I/O vermei<strong>de</strong>n.Den größten Gew<strong>in</strong>n an Geschw<strong>in</strong>digkeit und manchmalauch zugleich an Speicherplatz erzielt man durch e<strong>in</strong>e zweckmäßigeDatenstruktur und e<strong>in</strong>en guten Algorithmus. DieseÜberlegungen gehören jedoch an <strong>de</strong>n Anfang <strong>de</strong>r Programmentwicklung.Wenn das alles noch nicht reicht, ist es Zeit, sich mittels e<strong>in</strong>esProfilers anzusehen, wo die Zeit verbraten wird, und vielleichtauch e<strong>in</strong>ige kritische Programmteile <strong>in</strong> Assembler schreiben.1.11.5 curses – Fluch o<strong>de</strong>r Segen?Im Englischen ist e<strong>in</strong> curse so viel wie e<strong>in</strong> Fluch, und diecurses(3)-Bibliothek ist früher wegen ihrer vielen Fehler oftverwünscht wor<strong>de</strong>n. An<strong>de</strong>rerseits erleichtert sie <strong>de</strong>n Umgangmit <strong>de</strong>m Term<strong>in</strong>al unabhängig von <strong>de</strong>ssen Typ. Wir beg<strong>in</strong>nenmit e<strong>in</strong>em e<strong>in</strong>fachen Programm, das term<strong>in</strong>fo-Funktionen aus<strong>de</strong>r curses(3)-Bibliothek verwen<strong>de</strong>t, um <strong>de</strong>n Bildschirm zulöschen, wobei <strong>de</strong>r Term<strong>in</strong>altyp aus <strong>de</strong>r UmgebungsvariablenTERM und die zugehörigen Steuersequenzen aus <strong>de</strong>r Term<strong>in</strong>albeschreibung<strong>in</strong> /usr/lib/term<strong>in</strong>fo(4) entnommen wer<strong>de</strong>n.Das Programm soll außer<strong>de</strong>m, wenn ihm Date<strong>in</strong>amen als Argumenteübergeben wer<strong>de</strong>n, die Dateien leeren, ohne sie zu löschen(<strong>de</strong>r Bildschirm wird ja auch nicht verschrottet):/* C-Programm, das Bildschirm o<strong>de</strong>r Files loescht *//* Compile: cc -o xclear xclear.c -lcurses *//* falls term<strong>in</strong>fo-Fkt. verwen<strong>de</strong>t wer<strong>de</strong>n sollen, noch-DTERMINFO anhaengen */


234 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>#<strong>in</strong>clu<strong>de</strong> /* enthaelt stdio.h */#if<strong>de</strong>f TERMINFO#<strong>in</strong>clu<strong>de</strong> /* nur fuer term<strong>in</strong>fo */#endif<strong>in</strong>t ma<strong>in</strong>(argc, argv)<strong>in</strong>t argc;char *argv[];{<strong>in</strong>t i;if (argc > 1) { /* Files leeren, nicht loeschen */}for(i = 1; i < argc; i++) {if (!access(argv[i], 0))close(creat(argv[i], 0));elsepr<strong>in</strong>tf("File %s unzugaenglich.\n", argv[i]);}else {#if<strong>de</strong>f TERMINFO /* Bildschirm leeren, term<strong>in</strong>fo */setupterm(0, 1, 0);putp(clear screen);resetterm();#else /* Bildschirm leeren, curses */#endif<strong>in</strong>itscr();refresh();endw<strong>in</strong>();}return 0;}Quelle 1.82 : C-Programm zum Leeren <strong>de</strong>s Bildschirms o<strong>de</strong>r vonDateien


1.11. WEITERE C-PROGRAMME 235Das Kommando /usr/local/b<strong>in</strong>/xclear ist e<strong>in</strong>erecht praktische Erweiterung von /b<strong>in</strong>/clear. Die Funktionsetupterm() ermittelt vor allem <strong>de</strong>n Term<strong>in</strong>altyp.putp() schickt die Steuersequenz zum Term<strong>in</strong>al, undreset_shell_mo<strong>de</strong>() bere<strong>in</strong>igt alle D<strong>in</strong>ge, die setupterm()aufgesetzt hat. Mit diesen term<strong>in</strong>fo-Funktionen soll man nur<strong>in</strong> e<strong>in</strong>fachen Fällen wie <strong>de</strong>m obigen arbeiten, <strong>in</strong> <strong>de</strong>r Regel s<strong>in</strong>ddie <strong>in</strong>telligenteren curses(3)-Funktionen vorzuziehen.Im folgen<strong>de</strong>n Beispiel verwen<strong>de</strong>n wir curses(3)-Funktionen zur Bildschirmsteuerung zum Erzeugen e<strong>in</strong>esHilfe-Fensters:/* help.c, Programm mit curses-Funktionen *//* Compiler: cc -o help help.c -lcurses */#<strong>de</strong>f<strong>in</strong>e END ((c == ’Q’) | (c == ’q’)) /* Makros */#<strong>de</strong>f<strong>in</strong>e HELP ((c == ’H’) | (c == ’h’))#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t c, disp=1;WINDOW *frame;<strong>in</strong>itscr();noecho();cbreak();mvpr<strong>in</strong>tw(10,15,"Program <strong>de</strong>monstrat<strong>in</strong>g Curses-W<strong>in</strong>dows");mvpr<strong>in</strong>tw(11,15,"You get a help-w<strong>in</strong>dow by press<strong>in</strong>g h");mvpr<strong>in</strong>tw(LINES-1,0,"Press q to quit");refresh();while (1) {c = getch();if END {clear();refresh();endw<strong>in</strong>();return 0;}elseif HELP {if (disp) {frame = neww<strong>in</strong>(13,40,10,35);wstandout(frame);


236 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>for (c = 0; c


1.11. WEITERE C-PROGRAMME 237chen Bildschirm hat sich noch nichts gerührt. Erst mitrefresh() wird <strong>de</strong>r Puffer zum Bildschirm übertragen.• getch() liest e<strong>in</strong> Zeichen von <strong>de</strong>r Tastatur• clear() putzt <strong>de</strong>n Bildschirm beim nächsten Aufruf vonrefresh()• neww<strong>in</strong>() erzeugt e<strong>in</strong> neues Fenster – hier mit <strong>de</strong>m Namenframe – auf <strong>de</strong>r angegebenen Position mit e<strong>in</strong>er bestimmtenAnzahl von Zeilen und Spalten.• wstandout() setzt das Attribut <strong>de</strong>s Fensters aufstandout, d. h. auf umgekehrte Helligkeiten beispielsweise.Gilt bis wstan<strong>de</strong>nd().• wrefresh() wie refresh(), nur für e<strong>in</strong> bestimmtes Fenster.• <strong>de</strong>lw<strong>in</strong>() löscht e<strong>in</strong> Fenster, Gegenstück zu neww<strong>in</strong>().• touchw<strong>in</strong>() schreibt beim nächsten refresh() e<strong>in</strong> Fenstervöllig neu.Die curses(3)-Funktionen machen von <strong>de</strong>n Term<strong>in</strong>albeschreibungen<strong>in</strong> <strong>de</strong>n /usr/lib/term<strong>in</strong>fo-Dateien Gebrauch, manbraucht sich beim Programmieren um <strong>de</strong>n Term<strong>in</strong>altyp nichtzu sorgen. An<strong>de</strong>rerseits kann man nichts verwirklichen, was <strong>in</strong>term<strong>in</strong>fo nicht vorgesehen ist, Grafik zum Beispiel.1.11.6 Mehr o<strong>de</strong>r weniger zufälligMan braucht im Leben manchmal Zufallszahlen (random number),zum Beispiel wenn e<strong>in</strong>e Reihe von Vokabeln bunt durche<strong>in</strong>an<strong>de</strong>rabgefragt wer<strong>de</strong>n soll. S<strong>in</strong>d die Anfor<strong>de</strong>rungen nicht sohoch geschraubt, daß man erst e<strong>in</strong>mal e<strong>in</strong> Philosophisches Sem<strong>in</strong>arüber <strong>de</strong>n Begriff Zufall absolvieren muß, reichen e<strong>in</strong>igeFunktionen aus <strong>de</strong>r C-Standard-Bibliothek. Das folgen<strong>de</strong> Programmerzeugt e<strong>in</strong>e Folge mehr o<strong>de</strong>r weniger zufälliger natürlicherZahlen und gibt sie auf stdout aus:/* random.c zur Erzeugung von ZufallszahlenMAX Zufallszahlen von 1 bis MOD */#<strong>de</strong>f<strong>in</strong>e MAX 100#<strong>de</strong>f<strong>in</strong>e MOD 200


238 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t i, r, s;s = (<strong>in</strong>t) time((time t *) 0);/*srand((unsigned) s);for (i = 0; i < MAX; i++) {r = 1 + (rand() % MOD);pr<strong>in</strong>tf("%d\n", r);}*/srandom((unsigned) s);for (i = 0; i < MAX; i++) {r = 1 + (random() % MOD);pr<strong>in</strong>tf("%d\n", r);}return 0;}Quelle 1.84 : C-Programm zur Erzeugung von MAX Zufallszahlenim Bereich von 1 bis MODWir <strong>de</strong>f<strong>in</strong>ieren die Anzahl MAX von Zufallszahlen, die wirbrauchen, sowie <strong>de</strong>n Modulus MOD, <strong>de</strong>r die größte Zufallszahl bestimmt.Weiter b<strong>in</strong><strong>de</strong>n wir die Inclu<strong>de</strong>-Dateien stdio.h für dieFunktion pr<strong>in</strong>tf(), time.h für <strong>de</strong>n Systemaufruf time() undstdlib.h für die Funktionen srandom() und random() e<strong>in</strong>.Die Variable i ist e<strong>in</strong> Schleifenzähler, r die jeweilige Zufallszahlund s <strong>de</strong>r sogenannte Seed (Samen), auch Salz genannt, <strong>de</strong>n wirbrauchen, um <strong>de</strong>n Zufallszahlengenerator zu starten.Den Seed gew<strong>in</strong>nen wir aus <strong>de</strong>r Systemuhr als Anzahl <strong>de</strong>rSekun<strong>de</strong>n seit <strong>de</strong>m 1. Januar 1970, 0 Uhr GMT. Damit ist sichergestellt,daß wir bei je<strong>de</strong>m Aufruf e<strong>in</strong>en an<strong>de</strong>ren Wert ha-


1.11. WEITERE C-PROGRAMME 239ben. Die Syntax von time() holt man sich mittels man 2 time.Das Argument von time() ist hier <strong>de</strong>r Nullpo<strong>in</strong>ter.Die Funktion srand() o<strong>de</strong>r srandom() startet <strong>de</strong>n Generatorrand() beziehungsweise random. Bei<strong>de</strong> Funktionspaareverwen<strong>de</strong>n unterschiedliche Algorithmen, siehe die zugehörigenman-Seiten. Das Ergebnis <strong>de</strong>s Generators wird modulo MOD genommen,um <strong>de</strong>n Zahlenbereich zu begrenzen. Da wir Zahlenvon 1 bis MOD, die Grenzen e<strong>in</strong>geschlossen, haben wollen, addierenwir e<strong>in</strong>e 1 h<strong>in</strong>zu. Das Ergebnis dieser Rechnung wird wieüblich mittels <strong>de</strong>r Funktion pr<strong>in</strong>tf() auf stdout ausgegeben.Wir wollen nun das Programm so umstricken, daß die Rechnung<strong>in</strong> e<strong>in</strong>er Funktion zufallszahl() durchgeführt wird unddas Hauptprogramm nur die Zahlen ausgibt:/* random2.c zur Erzeugung von ZufallszahlenMAX Zufallszahlen von 1 bis MOD */#<strong>de</strong>f<strong>in</strong>e MAX 100#<strong>de</strong>f<strong>in</strong>e MOD 200#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t zufallszahl(<strong>in</strong>t m); /* Prototyp */<strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t i;for (i = 0; i < MAX; i++) {pr<strong>in</strong>tf("%d\n", zufallszahl((<strong>in</strong>t) MOD));}return 0;}/* Funktion zufallszahl() */<strong>in</strong>t zufallszahl(<strong>in</strong>t m){static <strong>in</strong>t r = 0;unsigned s;


240 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>if (!r) {s = (unsigned) time((time t *) 0);srand(s);}r = 1 + (rand() % m);return r;}Quelle 1.85 : C-Programm zur Erzeugung von MAX Zufallszahlenim Bereich von 1 bis MOD, mit FunktionUm die Funktion zufallszahl() allgeme<strong>in</strong> verwendbar zugestalten, übergeben wir <strong>de</strong>n Modulus bei je<strong>de</strong>m Aufruf als Argument.Da <strong>de</strong>r Generator nur beim ersten Aufruf gestartet wer<strong>de</strong>nsoll, <strong>de</strong>klarieren wir die Variable r als static, <strong>in</strong>itialisierensie mit null und mißbrauchen sie als Flag für <strong>de</strong>n Generatorstartmittels srand(). Die Initialisierung wird nur e<strong>in</strong>mal,beim Programmaufruf, ausgeführt. Danach hat r immer <strong>de</strong>n jeweilsjüngsten Zufallswert, <strong>de</strong>r m<strong>in</strong>imal 1 ist und negiert stetsfalse liefert.Im wirklichen Leben verlangte die Aufgabe e<strong>in</strong>e C-Funktionfür e<strong>in</strong> PASCAL-Programm. Hierzu müssen Funktion undHauptprogramm <strong>in</strong> getrennten Dateien vorliegen, da es ke<strong>in</strong>ezweisprachigen Compiler gibt. Also wur<strong>de</strong>n die C-Funktionisoliert und e<strong>in</strong> Rahmenprogramm zum Testen <strong>in</strong> PASCAL geschrieben:/* Funktion zufallszahl.c zur Erzeugung von ZufallszahlenMAX Zufallszahlen von 1 bis MOD */#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t zufallszahl(<strong>in</strong>t m){static <strong>in</strong>t r = 0;unsigned s;if (!r) {


1.11. WEITERE C-PROGRAMME 241}s = (unsigned) time((time t *) 0);srand(s);r = 1 + (rand() % m);return r;}Quelle 1.86 : C-Funktion zur Erzeugung e<strong>in</strong>er Zufallszahl im Bereichvon 1 bis MODDie C-Funktion gibt pro Aufruf e<strong>in</strong>e Zufallszahl im Bereich von1 bis zum Modulus zurück, <strong>de</strong>r als Argument übergeben wird.{PASCAL-Programm, das C-Funktion aufruft}{Compileraufruf pc -o prandom prandom.p zufallszahl.o}{Funktion zufallszahl() braucht als Argument <strong>de</strong>n Modulus}program prandom (<strong>in</strong>put, output);var a, i, x: <strong>in</strong>teger;function zufallszahl(x: <strong>in</strong>teger): <strong>in</strong>teger;external C;beg<strong>in</strong>writeln(’Bitte Modulus e<strong>in</strong>geben!’);readln(x);writeln(’Bitte Anzahl e<strong>in</strong>geben!’);readln(a);writeln(’Zufallszahlen:’);for i := a downto 1 dowriteln(zufallszahl(x));end.Quelle 1.87 : PASCAL-Programm zur Erzeugung von Zufallszahlenim Bereich von 1 bis MOD, mit C-FunktionDie Compileraufrufe lauten:cc -c zufallszahl.cpc -o prandom prandom.p zufallszahl.oDie gemischte Programmierung funktioniert hier reibungslos,


242 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>weil bei<strong>de</strong> Sprachen <strong>de</strong>n Typ Ganzzahl kennen und die C-Funktion e<strong>in</strong>fach ist.Wie wir anfangs auf Seite ?? bemerkt haben, ist es pr<strong>in</strong>zipiellunmöglich, mit e<strong>in</strong>er <strong>de</strong>term<strong>in</strong>istischen Masch<strong>in</strong>e Zufallsergebnissezu erzeugen. Die vorstehen<strong>de</strong>n Programme liefern daherauch nur Pseudo-Zufallszahlen (pseudo random number), dieh<strong>in</strong>sichtlich bestimmter Eigenschaften mit echten Zufallszahlenübere<strong>in</strong>stimmen. Für viele Zwecke reicht das, für e<strong>in</strong>en Vokabeltra<strong>in</strong>ersicherlich. E<strong>in</strong>e ausführliche Diskussion f<strong>in</strong><strong>de</strong>t sich beiDONALD E. KNUTH.1.11.7 E<strong>in</strong> Herz für Po<strong>in</strong>terPo<strong>in</strong>ter s<strong>in</strong>d nicht schwierig, son<strong>de</strong>rn allenfalls gewöhnungsbedürftig.Sie s<strong>in</strong>d bei C-Programmierern beliebt, weil sie zu elegantenund schnellen Programmen führen. Wir wollen uns anHand e<strong>in</strong>iger Beispiele an ihren Gebrauch gewöhnen. E<strong>in</strong>e Wie<strong>de</strong>rholung:• Der Computer kennt nur Speicherplätze <strong>in</strong> E<strong>in</strong>heiten vone<strong>in</strong>em Byte. Je<strong>de</strong>s Byte hat e<strong>in</strong>e absolute Adresse (Hausnummer),die uns aber nichts angeht.• Die Deklaration e<strong>in</strong>er Variablen erzeugt e<strong>in</strong>e Variable mite<strong>in</strong>em Namen und bestimmten Eigenschaften, darunter<strong>de</strong>n durch <strong>de</strong>n Typ bestimmten Speicherbedarf <strong>in</strong> Bytes.• Die Def<strong>in</strong>ition e<strong>in</strong>er Variablen weist ihr e<strong>in</strong>en Wert zu, belegtSpeicherplatz und damit e<strong>in</strong>e Adresse.• Der Po<strong>in</strong>ter auf e<strong>in</strong>e Variable enthält ihre Speicheradresse.Da uns <strong>de</strong>r absolute Wert <strong>de</strong>r Adresse nicht <strong>in</strong>teressiert,greifen wir auf <strong>de</strong>n Po<strong>in</strong>ter mittels se<strong>in</strong>es Namens zu. Heißtdie Variable x, so ist &x <strong>de</strong>r Name <strong>de</strong>s Po<strong>in</strong>ters.• Deklariert man zuerst <strong>de</strong>n Po<strong>in</strong>ter px, so erhält man dieVariable durch Dereferenzierung *px. Es ist nicht immergleichgültig, ob man <strong>de</strong>n Po<strong>in</strong>ter o<strong>de</strong>r die Variable <strong>de</strong>klariertund das Gegenstück durch Referenzieren bzw. Dereferenzierenhandhabt.• E<strong>in</strong>e Variable kann notfalls auf e<strong>in</strong>en Namen verzichten,aber niemals auf ihren Po<strong>in</strong>ter.


1.11. WEITERE C-PROGRAMME 243• Po<strong>in</strong>ter s<strong>in</strong>d ke<strong>in</strong>e ganzen Zahlen (die Arithmetik läuft an<strong>de</strong>rs).• E<strong>in</strong> Po<strong>in</strong>ter auf e<strong>in</strong>e noch nicht o<strong>de</strong>r nicht mehr existieren<strong>de</strong>Variable hängt <strong>in</strong> <strong>de</strong>r Luft (dangl<strong>in</strong>g po<strong>in</strong>ter) und ist e<strong>in</strong>Programmfehler.Nun e<strong>in</strong>ige Beispiele zu bestimmten Anwendungen von Po<strong>in</strong>tern.1.11.7.1 Nullpo<strong>in</strong>terDie Zahl Null ist die e<strong>in</strong>zige Konstante, die s<strong>in</strong>nvollerweise e<strong>in</strong>emPo<strong>in</strong>ter zugewiesen wer<strong>de</strong>n kann. Auf dieser Adresse liegtke<strong>in</strong> gültiges Datenobjekt, sie tritt nur <strong>in</strong> Verb<strong>in</strong>dung mit Fehlerno<strong>de</strong>r Ausnahmen auf. Um die Beson<strong>de</strong>rheit dieser Adressehervorzuheben, schreibt man sie meist nicht als Ziffer, son<strong>de</strong>rnals Wort NULL. In <strong>de</strong>r Inclu<strong>de</strong>-Datei stdio.h ist das Wort alssymbolische Konstante mit <strong>de</strong>m Wert 0 <strong>de</strong>f<strong>in</strong>iert.Im Programm 1.94 Sortieren nach Du<strong>de</strong>n auf Seite 264 kommenbeim Öffnen e<strong>in</strong>er Datei zum Lesen folgen<strong>de</strong> Zeilen vor:if ((fp = fopen(argv[1], "r")) == NULL) {pr<strong>in</strong>tf("Datei %s kann nicht goeffnet wer<strong>de</strong>n.\n", argv[exit(1);}Die Funktion fopen(), die die Datei öffnet, gibt bei Mißerfolg –aus welchen Grün<strong>de</strong>n auch immer – anstatt e<strong>in</strong>es Dateipo<strong>in</strong>ters<strong>de</strong>n Nullpo<strong>in</strong>ter zurück. Falls <strong>de</strong>r Vergleich positiv ausfällt, alsobei Mißerfolg, wird e<strong>in</strong>e Fehlermeldung ausgegeben und dasProgramm mit <strong>de</strong>m Systemaufruf exit() verlassen. Bei Erfolgenthält <strong>de</strong>r Po<strong>in</strong>ter fp die Adresse <strong>de</strong>s Dateianfangs.1.11.7.2 Po<strong>in</strong>ter auf Typ voidMan braucht gelegentlich e<strong>in</strong>en Po<strong>in</strong>ter, <strong>de</strong>r auf e<strong>in</strong>e Variablevon e<strong>in</strong>em zunächst noch unbekannten Typ zeigt. Wenn es dannzur Sache geht, legt man <strong>de</strong>n Typ mittels <strong>de</strong>s cast-Operatorsfest.Früher nahm man dafür Po<strong>in</strong>ter auf <strong>de</strong>n Typ char, <strong>de</strong>nn dieserTyp belegt genau e<strong>in</strong> Byte, woraus man je<strong>de</strong>n an<strong>de</strong>ren Typ


244 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>aufbauen kann. Nach ANSI ist hierfür <strong>de</strong>r Typ void zu wählen.Je<strong>de</strong>r Po<strong>in</strong>ter kann ohne Verlust an Information per cast<strong>in</strong> e<strong>in</strong>en Po<strong>in</strong>ter auf void verwan<strong>de</strong>lt wer<strong>de</strong>n, und umgekehrt.Die Po<strong>in</strong>ter belegen ja selbst – unabhängig vom Typ, auf <strong>de</strong>n siezeigen – gleich viele Bytes.Im folgen<strong>de</strong>n Beispiel wird e<strong>in</strong>e Funktion xread() vorgestellt,die je<strong>de</strong> Tastature<strong>in</strong>gabe als langen Str<strong>in</strong>g übernimmt unddann die E<strong>in</strong>gabe – erfor<strong>de</strong>rlichenfalls nach Prüfung – <strong>in</strong> e<strong>in</strong>engewünschten Typ umwan<strong>de</strong>lt. Die Funktion ist e<strong>in</strong> Ersatz fürscanf(3) mit <strong>de</strong>r Möglichkeit, fehlerhafte E<strong>in</strong>gaben nach Beliebenzu behan<strong>de</strong>ln. Als erstes e<strong>in</strong> Programmrahmen, <strong>de</strong>r dieFunktion xread() aufruft, dann die Funktion:/* Fkt. xread() zum E<strong>in</strong>lesen und Umwan<strong>de</strong>ln von Str<strong>in</strong>gs *//* mit Rahmenprogramm ma<strong>in</strong>() zum Testen, 1992-05-11 */#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t xread(void *p, char *typ);void exit(); /* Systemaufruf */<strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t error = 0;<strong>in</strong>t x;double y;char z[80];/* Integer-E<strong>in</strong>gabe */pr<strong>in</strong>tf("Bitte Ganzzahl e<strong>in</strong>geben: \n");if (!xread(&x, "<strong>in</strong>t")) {pr<strong>in</strong>tf("Die E<strong>in</strong>gabe war: %d\n", x);}else {puts("Fehler von xread()");error = 1;}/* Gleitkomma-E<strong>in</strong>gabe */pr<strong>in</strong>tf("Bitte Gleitkomma-Zahl e<strong>in</strong>geben: \n");if (!xread(&y, "float")) {pr<strong>in</strong>tf("Die E<strong>in</strong>gabe war: %f\n", y);


1.11. WEITERE C-PROGRAMME 245}else {puts("Fehler von xread()");error = 1;}/* Str<strong>in</strong>ge<strong>in</strong>gabe */pr<strong>in</strong>tf("Bitte Str<strong>in</strong>g e<strong>in</strong>geben: \n");if (!xread(z, "char")) {pr<strong>in</strong>tf("Die E<strong>in</strong>gabe war: %s\n", z);}else {puts("Fehler von xread()");error = 1;}exit(error);}/* Funktion xread() *//* Parameter: Variable als Po<strong>in</strong>ter, C-Typ als Str<strong>in</strong>g */#<strong>de</strong>f<strong>in</strong>e MAXLAENGE 200 /* max. Laenge <strong>de</strong>r E<strong>in</strong>gabe */#<strong>in</strong>clu<strong>de</strong> <strong>in</strong>t atoi(); /* Standard-C-Bibliothek */long atol(); /* Standard-C-Bibliothek */double atof(); /* Standard-C-Bibliothek */<strong>in</strong>t xread(p, typ)void *p;char *typ;{char <strong>in</strong>put[MAXLAENGE];<strong>in</strong>t rwert = 0;if (gets(<strong>in</strong>put) != NULL) {switch(*typ) {case ’c’: /* Typ char */strcpy((char *)p, <strong>in</strong>put);break;case ’i’: /* Typ <strong>in</strong>t */case ’s’: /* Typ short */*((<strong>in</strong>t *)p) = atoi(<strong>in</strong>put);break;case ’l’: /* Typ long */


246 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>*((long *)p) = atol(<strong>in</strong>put);break;case ’d’: /* Typ double */case ’f’: /* Typ float */*((double *)p) = atof(<strong>in</strong>put);break;<strong>de</strong>fault:puts("xread: Unbekannter Typ");rwert = 1;}}else {puts("xread: Fehler bei E<strong>in</strong>gabe");rwert = 2;}return rwert;}Quelle 1.88 : C-Programm mit Po<strong>in</strong>ter auf voidDie Funktion xread() braucht als erstes Argument e<strong>in</strong>enPo<strong>in</strong>ter (aus <strong>de</strong>mselben Grund wie scanf(3), call by reference)auf die e<strong>in</strong>zulesen<strong>de</strong> Variable, als zweites Argument <strong>de</strong>n gewünschtenTyp <strong>in</strong> Form e<strong>in</strong>es Str<strong>in</strong>gs. Auf e<strong>in</strong>e wechseln<strong>de</strong> Anzahlvon Argumenten verzichten wir hier.Falls wir nicht für je<strong>de</strong>n e<strong>in</strong>zulesen<strong>de</strong>n Typ e<strong>in</strong>e eigene Funktionschreiben wollen, muß xread() e<strong>in</strong>en Po<strong>in</strong>ter auf e<strong>in</strong>en beliebigenTyp, sprich void, übernehmen. Erst nach Auswertung<strong>de</strong>s zweiten Argumentes weiß xread(), auf was für e<strong>in</strong>en Typ<strong>de</strong>r Po<strong>in</strong>ter zeigt.Das Programm läuft <strong>in</strong> se<strong>in</strong>er obigen Fassung e<strong>in</strong>wandfrei,<strong>de</strong>r Syntax-Prüfer l<strong>in</strong>t(1) hat aber e<strong>in</strong>ige Punkte anzumerken.1.11.7.3 Arrays und Po<strong>in</strong>terDas folgen<strong>de</strong> Programm berechnet die Primzahlen von 2 angefangenbis zu e<strong>in</strong>er oberen Grenze, die beim Aufruf e<strong>in</strong>gegebenwer<strong>de</strong>n kann. Ihr Maximalwert hängt verständlicherweisevom System ab. Aus Geschw<strong>in</strong>digkeitsgrün<strong>de</strong>n wer<strong>de</strong>n reichlichPo<strong>in</strong>ter verwen<strong>de</strong>t. Ursprünglich wur<strong>de</strong>n die Elemente <strong>de</strong>r Arraysüber Indizes angesprochen, was <strong>de</strong>n Gewohnheiten entgegenkommt.Bei <strong>de</strong>r Optimierung wur<strong>de</strong>n alle Indizes durch Po<strong>in</strong>-


1.11. WEITERE C-PROGRAMME 247ter ersetzt, wie im Abschnitt 1.11.4 Optimierung auf Seite 230erläutert./* Programm zur Berechnung von Primzahlen, 1990-10-03 *//* Compileraufruf MS-DOS/QuickC: qcl prim.c *//* Compileraufruf unter UNIX: cc -o prim prim.c -DUNIX *//* Die groesste zu untersuchen<strong>de</strong> Zahl wird unter MS-DOSdurch die Speichersegmentierung bestimmt. Ke<strong>in</strong> Datensegmentp[] darf groesser als 64 KB se<strong>in</strong>. Damit liegtMAX etwas ueber 150000.Unter UNIX begrenzt <strong>de</strong>r verfuegbare Speicher dieGroesse. Der Datentyp unsigned long geht <strong>in</strong> bei<strong>de</strong>nFaellen ueber 4 Milliar<strong>de</strong>n. */#if<strong>de</strong>f UNIX#<strong>de</strong>f<strong>in</strong>e MAX (unsigned long)1000000#else#<strong>de</strong>f<strong>in</strong>e MAX (unsigned long)100000#endif#<strong>de</strong>f<strong>in</strong>e MIN (unsigned long)50/* Defaultwert fuer Obergrenze */#<strong>de</strong>f<strong>in</strong>e DEF (unsigned long)10000#<strong>in</strong>clu<strong>de</strong> /* globale Variable */unsigned long p[MAX/10]; /* Array <strong>de</strong>r Primzahlen */unsigned d[MAX/1000]; /* Haeufigkeit <strong>de</strong>r Differenzen */unsigned long h[2][11]; /* Haeufigkeit <strong>de</strong>r Primzahlen */unsigned long z = 1; /* aktuelle Zahl */unsigned n = 1; /* lfd. Anzahl Primzahlen - 1 *//* Funktionsprototypen */void ttest(); /* Funktion Teilbarkeitstest */long time(); /* Systemaufruf zur Zeitmessung *<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc,char *argv[]) /* Hauptprogramm */{<strong>in</strong>t r;<strong>in</strong>t i = 1, j, k;unsigned long en<strong>de</strong> = DEF;


248 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>unsigned long *q;unsigned long dp, dmax = 1, d1, d2;unsigned long g;long zeit1, zeit2, zeit3;/* Auswertung <strong>de</strong>r Kommandozeile *//* <strong>de</strong>m Aufruf kann als Argument die Obergrenzemitgegeben wer<strong>de</strong>n *//* ke<strong>in</strong>e Pruefung auf negative Zahlen o<strong>de</strong>r Str<strong>in</strong>gs */if (argc > 1) {sscanf(*(argv + 1), "%lu", &en<strong>de</strong>);}}if (en<strong>de</strong> > MAX) {pr<strong>in</strong>tf("\nZ. zu gross! Maximal %lu\n", MAX);exit(1);if (en<strong>de</strong> < MIN) {pr<strong>in</strong>tf("\nZ. zu kle<strong>in</strong>; genommen wird %lu\n\n\n", \MIN);en<strong>de</strong> = MIN;}if (g = en<strong>de</strong> % 10) {pr<strong>in</strong>tf("\nZ. muss durch 10 teilbar se<strong>in</strong>: %lu\n\n\n", \en<strong>de</strong>=en<strong>de</strong> - g);}/* Algorithmus */time(&zeit1);*p = 2; *(p + 1) = 3; /* die ersten Primzahlen */en<strong>de</strong> -= 3;while (z < en<strong>de</strong>) {z += 4;ttest();z += 2;ttest();}/*Da z pro Durchlauf um 6 erhoeht wird, kann e<strong>in</strong>ePrimzahl zuviel berechnet wer<strong>de</strong>n,


1.11. WEITERE C-PROGRAMME 249*/gegebenenfalls loeschenif (*(p + n) > (en<strong>de</strong> = en<strong>de</strong> + 3))n -= 1;/* Berechnung <strong>de</strong>r Haeufigkeit <strong>in</strong> <strong>de</strong>n Klassen */g = en<strong>de</strong>/10; **h = 1; **(h + 1) = 0; j = 1; k = 0;for (i = 0; i g) {*(*h + j) = g;*(*(h + 1) + j) = i - k;k = i;j++;g += en<strong>de</strong>/10;}}*(*h + j) = g;*(*(h + 1) + j) = i - k;/* Berechnung <strong>de</strong>r Differenz benachbarter Primzahlen */for (i = 1; i dmax) {dmax = dp;d1 = *(p + i);d2 = *(p + i - 1);}}time(&zeit2);/* achtspaltige Ausgabe auf stdout */pr<strong>in</strong>tf("\tPrimzahlen bis %lu\n\n", en<strong>de</strong>);j = n - ( r = ((n + 1) % 8));q = p;for (i = 0; i


250 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>q += 8;}\t%6lu\n", *q, *(q+1), *(q+2), *(q+3), \*(q+4), *(q+5), *(q+6), *(q+7));if (r != 0) {pr<strong>in</strong>tf("\t");for (i = 0; i < r; i++) /* letzte Zeile */pr<strong>in</strong>tf("%6lu\t", *(q+i));puts("");}pr<strong>in</strong>tf("\n\tGesamtzahl: %u\n\n", n + 1);for (i = 1; i


1.11. WEITERE C-PROGRAMME 251for (i = 1; *(p + i) * *(p + i)


252 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>void done(); /* Aufraeumen *//* Hauptprogramm */<strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t i, rf, x;struct vi<strong>de</strong>oconfig vc;<strong>in</strong>t (*schiff[MAX])(), <strong>in</strong><strong>de</strong>x[MAXARR];time t zeit;/* Titel und Vorspann */rf = titel();/* Grafikmodus VGA 16 Farben */if (! setvi<strong>de</strong>omo<strong>de</strong>( VRES16COLOR)) {puts("Fehler: Ke<strong>in</strong>e VGA-Grafik");exit(1);}setbkcolor(BGRAU);/* Array <strong>de</strong>r Funktionen (Bil<strong>de</strong>r) fuellen */schiff[0] = bild000; schiff[1] = bild001;schiff[2] = bild002; schiff[3] = bild003;....schiff[124] = bild124; schiff[125] = bild125;/* In<strong>de</strong>x-Array fuellen (Zufallszahlen) */if (rf == 49) {time(&zeit);srand((unsigned)zeit);}else {for (i = 0; i < MAXARR; i++) {x = rand() % MAX;if (x == <strong>in</strong><strong>de</strong>x[i - 1])x = rand() % MAX;<strong>in</strong><strong>de</strong>x[i] = x;}for (i = 0; i < MAXARR; i++)


1.11. WEITERE C-PROGRAMME 253}<strong>in</strong><strong>de</strong>x[i] = i % MAX;#if<strong>de</strong>f DEBUGfor (i = 0; i < MAXARR; i++)pr<strong>in</strong>tf("%d\n", <strong>in</strong><strong>de</strong>x[i]);while (!kbhit());#endif/* Koord<strong>in</strong>atensystem *//* x nach rechts, x = 0 <strong>in</strong> Mitte;y nach unten, y = 0 oben */getvi<strong>de</strong>oconfig(&vc);setlogorg(vc.numxpixels / 2 - 1, 0);/* Textfenster */settextw<strong>in</strong>dow(7 * vc.numtextrows / 8, 4, vc.numtextrows,vc.numtextcols - 3);wrapon( GWRAPOFF);/* Hauptschleife */i = 0;do {/* H<strong>in</strong>tergrund (Tag - Nacht) */if ( getbkcolor() == BSCHWARZ) {setbkcolor(BGRAU);setcolor(HWEISS);}else {setbkcolor(BSCHWARZ);setcolor(SCHWARZ);}if ( getbkcolor())settextcolor(HWEISS);elsesettextcolor(SCHWARZ);/* Aufruf <strong>de</strong>r Fkt. zum Zeichnen <strong>de</strong>r Schiffe */(*schiff[<strong>in</strong><strong>de</strong>x[i]])();


254 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>/* Tastature<strong>in</strong>gabe zum Weitermachen */if ((x = getch()) == 13 || x == 43 || x == 45) {if (x == 45) i-;else i++;if (i >= MAXARR || i


1.11. WEITERE C-PROGRAMME 255Befeuerungen <strong>in</strong> e<strong>in</strong>er systematischen o<strong>de</strong>r zufälligen Folge anzeigenlassen.Die Funktionen bild***() s<strong>in</strong>d <strong>in</strong> e<strong>in</strong>er Datei <strong>in</strong> e<strong>in</strong>em eigenenUnterverzeichnis vere<strong>in</strong>igt:/* Funktionen bild*() */#<strong>in</strong>clu<strong>de</strong> "bil<strong>de</strong>r.h"/*************//* Sportboot *//*************/...<strong>in</strong>t bild001(){text0("Bild 001:");text1("Sportboot von vorn");sportboot(0);feuersport1();return 0;}...Quelle 1.91 : C-Funktion bil<strong>de</strong>r.c zum Programm schiff.cDie Funktionen rufen im wesentlichen weitere Funktionenauf. Das Unterverzeichnis enthält e<strong>in</strong>e eigene Inclu<strong>de</strong>-Datei un<strong>de</strong><strong>in</strong> eigenes Makefile. In gleicher Weise s<strong>in</strong>d die übrigen Funktionenorganisiert.Das Makefile <strong>de</strong>s Hauptprogramms ruft Makefiles <strong>in</strong> <strong>de</strong>n Unterverzeichnissenauf. Wir haben also e<strong>in</strong>e Hierarchie von Makefiles:# makefile fuer schiff.c<strong>in</strong>clu<strong>de</strong> make.h# Compiler-Auswahl, make-<strong>in</strong>clu<strong>de</strong># UnterverzeichnisseA = assemB = bil<strong>de</strong>rF = feuer


256 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>K = konturS = schallT = text# Weitere MakrosOBJS = schiff.obj titel.obj bil<strong>de</strong>r.obj text.obj \feuer.obj schall.obj kontur.obj sound.obj \nosound.obj <strong>de</strong>lay.obj# Anweisungenall : schiff.exe <strong>in</strong>stall cleanschiff.exe : schiff.obj titel.obj bil<strong>de</strong>r o text o \feuer o kontur o schall o assem o$(LD) $(LDFLAGS) $(OBJS)„„schiff.obj : schiff.c schiff.h$(CC) $(CFLAGS) schiff.ctitel.obj : titel.c$(CC) $(CFLAGS) titel.cbil<strong>de</strong>r o :cd $(B)$(MAKE) allcd ..text o :cd $(T)$(MAKE) allcd ..feuer o :cd $(F)$(MAKE) allcd ..kontur o :cd $(K)$(MAKE) allcd ..schall o :cd $(S)


1.11. WEITERE C-PROGRAMME 257$(MAKE) allcd ..assem o :cd $(A)$(MAKE) allcd ..<strong>in</strong>stall :$(CP) schiff.exe s.execlean :$(RM) *.bak$(RM) *.objQuelle 1.92 : Makefile zu schiff.cDieses Projekt – obwohl beschei<strong>de</strong>n – wäre ohne make(1) nurnoch mühsam zu beherrschen. Es ist für das Gel<strong>in</strong>gen entschei<strong>de</strong>nd,sich zu Beg<strong>in</strong>n die Struktur sorgfältig zu überlegen.Infolge <strong>de</strong>r Verwendung von Grafikfunktionen <strong>de</strong>s MS-Quick-C-Compilers ist das Programm nicht auf an<strong>de</strong>re Systeme übertragbar.Man müßte eigene Grafikfunktionen verwen<strong>de</strong>n, dieVerpackungen um die Grafikfunktionen <strong>de</strong>s jeweiligen Compilersdarstellen. Dasselbe gilt für die Funktion zum Tuten, e<strong>in</strong>eAssemblerrout<strong>in</strong>e. Vielleicht stellen wir das Programm e<strong>in</strong>malauf X11 um und verpacken dabei die spezifischen Funktionen.1.11.8 Verarbeitung von Str<strong>in</strong>gsStr<strong>in</strong>gs (Zeichenketten) s<strong>in</strong>d <strong>in</strong> C/<strong>C++</strong> e<strong>in</strong> <strong>de</strong>nkbar e<strong>in</strong>facher Datentyp,nämlich Arrays of char, die mit <strong>de</strong>m ASCII-Zeichen Nr. 0abgeschlossen s<strong>in</strong>d. In <strong>de</strong>r Standard-C-Bibliothek f<strong>in</strong><strong>de</strong>n sich fertigeFunktionen für die häufigsten Aufgaben <strong>de</strong>r Str<strong>in</strong>gverarbeitung.Trotz<strong>de</strong>m hat dieses Gebiet e<strong>in</strong> paar kle<strong>in</strong>e Tücken.E<strong>in</strong> beliebter Laufzeitfehler ist das Schreiben von Str<strong>in</strong>gs <strong>in</strong>Pufferspeicher, die zu kle<strong>in</strong> s<strong>in</strong>d. Es kommt dann zu e<strong>in</strong>em Überlaufmit nicht immer vorhersehbaren Folgen, manchmal auch zuvon bösen Buben beabsichtigten Folgen. Man me<strong>in</strong>t, <strong>de</strong>r Puffersei reichlich bemessen – es ist auch jahrelang alles gut gegangen– und dann taucht e<strong>in</strong>mal e<strong>in</strong> überlanger Str<strong>in</strong>g auf, <strong>de</strong>r<strong>de</strong>n Puffer sprengt. Das Gegenmittel besteht im Beschränken


258 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong><strong>de</strong>s Schreibens auf maximal e<strong>in</strong> Zeichen weniger als <strong>de</strong>r Pufferfasst. Wo E<strong>in</strong>gaben verlangt wer<strong>de</strong>n, ist immer damit zu rechnen,dass:• die E<strong>in</strong>gabe leer ist (leerer Str<strong>in</strong>g, nur ASCII-Nr. 0) o<strong>de</strong>r• zu lang ist (Überlauf)E<strong>in</strong> gewiefter Programmierer sieht solche Fehler o<strong>de</strong>r Ausnahmenvoraus.gets() – fgets()1.11.9 Dynamische Speicherverwaltung (malloc)Wir haben gelernt, daß die Größe e<strong>in</strong>es Arrays o<strong>de</strong>r e<strong>in</strong>er Strukturbereits zur Übersetzungszeit bekannt se<strong>in</strong>, d. h. im Programmstehen muß. Dies führt <strong>in</strong> manchen Fällen zur Verschwendungvon Speicher, da man Arrays <strong>in</strong> <strong>de</strong>r maximal möglichenGröße anlegen müßte. Die Standardfunktion malloc(3)samt Verwandtschaft hilft aus <strong>de</strong>r Klemme. Im folgen<strong>de</strong>n Beispielwird e<strong>in</strong> Array zunächst nur als Po<strong>in</strong>ter la <strong>de</strong>klariert, dannmittels calloc(3) Speicher zugewiesen, mittels realloc(3)vergrößert und schließlich von free(3) wie<strong>de</strong>r freigegeben:/* Programm allo.c zum Ueben von malloc(3), 1994-06-01 */#<strong>de</strong>f<strong>in</strong>e MAX 40#<strong>de</strong>f<strong>in</strong>e DELTA 2#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> long *la; /* Po<strong>in</strong>ter auf long */<strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t i, x;/* calloc() belegt Speicher fuer Array von MAX Elementen<strong>de</strong>r Groesse sizeof(long), <strong>in</strong>itialisert mit 0,gibt Anfangsadresse zurueck.In stdlib.h wird size t als unsigned <strong>in</strong>t <strong>de</strong>f<strong>in</strong>iert. */la = (long *)calloc((size t)MAX, (size t)sizeof(long));


1.11. WEITERE C-PROGRAMME 259if (la != NULL)puts("Zuordnung ok.");else {puts("G<strong>in</strong>g daneben.");exit(-1);}/* Array anschauen */pr<strong>in</strong>tf("Ganzzahl e<strong>in</strong>geben: ");scanf("%d", &x);for (i = 0; i < MAX; i++)la[i] = (long)(i * x);pr<strong>in</strong>tf("Ausgabe: %ld%ld\n", la[10], la[20]);/* Array verlaengern mit realloc() */la = (long *)realloc((void *)la, \(size t)(DELTA * sizeof(long)));/* Array anschauen */la[MAX + DELTA] = x;pr<strong>in</strong>tf("erweitert: %ld%ld\n", la[10], la[MAX + DELTA])/* Speicher freigeben mit free() */free((void *)la);return 0;}Quelle 1.93 : C-Programm mit dynamischer Speicherverwaltung(malloc(3))Das nächste Beispiel sortiert die Zeilen e<strong>in</strong>es Textes nach <strong>de</strong>nRegeln <strong>de</strong>s Du<strong>de</strong>n (Du<strong>de</strong>n-Taschenbuch Nr. 5: Satz- und Korrekturanweisungen),die von <strong>de</strong>n Regeln <strong>in</strong> DIN 5007 etwas abweichen./* "du<strong>de</strong>n" sortiert Textfile zeilenweise nach <strong>de</strong>m erstenWort unter Beruecksichtigung <strong>de</strong>r Du<strong>de</strong>n-Regeln */


260 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>/* Falls das Wort mit e<strong>in</strong>em Komma en<strong>de</strong>t, wird auch dasnaechste Wort beruecksichtigt (z. B. Vorname) *//* Compiler: cc -O -o du<strong>de</strong>n du<strong>de</strong>n.c -lmalloc */#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>de</strong>f<strong>in</strong>e MAX 1024 /* max. Anzahl <strong>de</strong>r Zeilen */#<strong>de</strong>f<strong>in</strong>e EXT ".s" /* Kennung <strong>de</strong>s sort. Files */#<strong>de</strong>f<strong>in</strong>e NOWHITE(c) \(((c) != ’ ’) && ((c) != ’\t’) && ((c) != ’\n’))#<strong>de</strong>f<strong>in</strong>e NOCHAR(c) \(((c) == ’ ’) || ((c) == ’\t’) || ((c) == ’\0’))#<strong>de</strong>f<strong>in</strong>e SCHARF(c) (((c) == ’~’) || ((c) == 222)) /* sz */#<strong>de</strong>f<strong>in</strong>e KOMMA(c) ((c) == ’,’)/* statische Initialisierung e<strong>in</strong>es externen Arrays *//* ASCII-Tafel. Die Zahlen stellen die Nummer <strong>de</strong>sZeichens dar. *//* angefuegt HP ROMAN EXTENSION (optional) */char wert[256] = {/* Steuerzeichen */0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19,20, 21, 22, 23, 24, 25, 26, 27, 28, 29,30, 31,/* Space, Son<strong>de</strong>r- und Satzzeichen */32, 33, 34, 35, 36, 37, 38, 39,40, 41, 42, 43, 44, 45, 46, 47,/* Ziffern */65, 66, 67, 68, 69, 70, 71, 72, 73, 74,/* Son<strong>de</strong>r- und Satzzeichen */48, 49, 50, 51, 52, 53, 89,/* Grossbuchstaben */75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,/* Son<strong>de</strong>r- und Satzzeichen */75, 89, 95, 58, 59, 60,/* Kle<strong>in</strong>buchstaben */75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,/* Son<strong>de</strong>r- und Satzzeichen */75, 89, 95, 93,


1.11. WEITERE C-PROGRAMME 261/* DEL */111,};/* ROMAN EXTENSION *//* un<strong>de</strong>f<strong>in</strong>ierte Zeichen */0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0,/* Buchstaben */75, 75, 79, 79, 79, 83, 83,/* Zeichen */0, 0, 0, 0, 0,/* Buchstaben */93, 93,/* Zeichen */0, 0, 0, 0, 0,/* Buchstaben */77, 77, 88, 88,/* Zeichen */0, 0, 0, 0, 0, 0, 0, 0,/* Buchstaben */75, 79, 89, 95, 75, 79, 89, 95,75, 79, 89, 95, 75, 79, 89, 95,75, 83, 89, 75, 75, 83, 89, 75,75, 83, 89, 95, 79, 83, 93, 89,75, 75, 75, 78, 78, 83, 83, 89,89, 89, 89, 93, 93, 95, 99, 99,101, 101,/* Zeichen und un<strong>de</strong>f<strong>in</strong>ierte Zeichen */0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0char *ap[MAX]; /* P. auf Zeilenanfaenge *//* Hauptprogramm */<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc, char *argv[]){<strong>in</strong>t flag = 0, i = 0, j;char a, *mp;FILE *fp, *fps;struct stat buf;extern char *ap[];


262 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>extern char *strcat();void exit();/* Pruefung <strong>de</strong>s Programmaufrufs */if (argc != 2) {pr<strong>in</strong>tf("Aufruf: du<strong>de</strong>n FILENAME\n");exit(1);}/* Arbeitsspeicher allokieren */stat(argv[1], &buf);if ((mp = malloc((unsigned)buf.st size)) == NULL) {pr<strong>in</strong>tf("Ke<strong>in</strong> Speicher frei.\n");exit(1);}ap[0] = mp;/* Textfile e<strong>in</strong>lesen, fuehren<strong>de</strong> NOCHARs loeschen */if ((fp = fopen(argv[1], "r")) == NULL) {pr<strong>in</strong>tf("File %s kann nicht goeffnet wer<strong>de</strong>n.\n", \argv[1]);exit(1);}while((a = fgetc(fp)) != EOF) {if ((flag == 0) && NOCHAR(a));else {flag = 1;*mp = a;if (*mp == ’\n’) {flag = 0;ap[++i] = ++mp;}elsemp++;}}fclose(fp);/* Zeilenpo<strong>in</strong>ter sortieren */if (sort(i - 1) != 0) {


1.11. WEITERE C-PROGRAMME 263}pr<strong>in</strong>tf("Sortieren g<strong>in</strong>g daneben.\n");exit(1);/* Textfile zurueckschreiben */if ((fps = fopen(strcat(argv[1], EXT), "w")) == NULL) {pr<strong>in</strong>tf("File %s.s kann nicht geoeffnet wer<strong>de</strong>n.\n", \argv[1]);exit(1);}for (j = 0; j < i; j++) {while ((a = *((ap[j])++)) != ’\n’)fputc(a, fps);fputc(’\n’, fps);}fclose(fps);}/* En<strong>de</strong> Hauptprogramm *//* Sortierfunktion (Bubblesort, stabil) */<strong>in</strong>t sort(<strong>in</strong>t imax){<strong>in</strong>t flag = 0, i = 0, j = 0, k = 0;char *p1, *p2;extern char *ap[];while (flag == 0) {flag = 1;k = i;p2 = ap[imax];for (j = imax; j > k; j-) {p1 = ap[j - 1];if (vergleich(p1, p2)


264 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}}ap[j] = p2;}return(0);}/* Vergleich zweier Str<strong>in</strong>gs bis zum ersten Whitespace *//* Returnwert = 0, falls Str<strong>in</strong>gs gleichReturnwert < 0, falls Str<strong>in</strong>g1 < Str<strong>in</strong>g2Returnwert > 0, falls Str<strong>in</strong>g1 > Str<strong>in</strong>g2 */<strong>in</strong>t vergleich(char *x1, *x2){<strong>in</strong>t flag = 0;while((wert[*x1] - wert[*x2]) == 0) {if (NOWHITE(*x1)) {if (SCHARF(*x1)) x2++; /* scharfes s */if (SCHARF(*x2)) {x1++;flag = 1;}x1++;x2++;}else {if (KOMMA(*(x1 - 1))) { /* weiteres Wort */while (NOCHAR(*x1))x1++;while (NOCHAR(*x2))x2++;flag = vergleich(x1, x2);}return flag;}}return(wert[*x1] - wert[*x2]);}Quelle 1.94 : C-Programm zum Sortieren e<strong>in</strong>es Textes nach <strong>de</strong>nRegeln <strong>de</strong>s Du<strong>de</strong>nDie Variable flag, die auch an<strong>de</strong>rs heißen kann, ist e<strong>in</strong> Flago<strong>de</strong>r e<strong>in</strong>e Schaltvariable, d. h. e<strong>in</strong>e Variable, die <strong>in</strong> Abhängig-


1.11. WEITERE C-PROGRAMME 265keit von bestimmten Bed<strong>in</strong>gungen e<strong>in</strong>en Wert 0 o<strong>de</strong>r nicht-0 annimmtund ihrerseits wie<strong>de</strong>r <strong>in</strong> an<strong>de</strong>ren Bed<strong>in</strong>gungen auftritt.E<strong>in</strong> gängiger, e<strong>in</strong>wandfreier Programmiertrick.1.11.10 X W<strong>in</strong>dow SystemDas folgen<strong>de</strong> Beispiel zeigt, wie man unter Benutzung von Xlib-Funktionen e<strong>in</strong> Programm schreibt, das unter <strong>de</strong>m X W<strong>in</strong>dowSystem läuft:/* xw<strong>in</strong>dows.c, this program <strong>de</strong>monstrates how to useX’s base w<strong>in</strong>dow system through the Xlib <strong>in</strong>terface *//* Compiler: cc xw<strong>in</strong>dows.c -lX11 */#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>de</strong>f<strong>in</strong>e QUIT "Press q to quit"#<strong>de</strong>f<strong>in</strong>e CLEAR "Press c to clear this w<strong>in</strong>dow"#<strong>de</strong>f<strong>in</strong>e DELETE "Press d to <strong>de</strong>lete this w<strong>in</strong>dow"#<strong>de</strong>f<strong>in</strong>e SUBWIN "Press n to create subw<strong>in</strong>dow"#<strong>de</strong>f<strong>in</strong>e DELSUB "Press n aga<strong>in</strong> to <strong>de</strong>lete w<strong>in</strong>dow"#<strong>de</strong>f<strong>in</strong>e WIN1 "WINDOW 1"#<strong>de</strong>f<strong>in</strong>e WIN2 "WINDOW 2"#<strong>de</strong>f<strong>in</strong>e WIN3 "WINDOW 3"char hallo[]="Hallo World";char hi[] ="Hi";<strong>in</strong>t ma<strong>in</strong>(<strong>in</strong>t argc,char **argv){Display *mydisplay; /* d. structure */W<strong>in</strong>dow myw<strong>in</strong>1, myw<strong>in</strong>2, neww<strong>in</strong>; /* w. structure */Pixmap mypixmap; /* pixmap */GC mygc1, mygc12, newgc; /* graphic contextXEvent myevent; /* event to send */KeySym mykey; /* keyboard key */XSizeH<strong>in</strong>ts myh<strong>in</strong>t; /* w<strong>in</strong>dow <strong>in</strong>fo */Colormap cmap; /* color map */XColor yellow, exact, color1, color2, color3;static XSegment segments[]={{350,100,380,280}, /{380,280,450,300}};unsigned long myforeground; /* fg color */unsigned long mybackground; /* bg color */


266 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong><strong>in</strong>tcharmyscreen, i, num=2, <strong>de</strong>l=1, w<strong>in</strong>=1;text[10];/* <strong>in</strong>itialization */if (!(mydisplay = XOpenDisplay(""))) {fpr<strong>in</strong>tf(st<strong>de</strong>rr, "Cannot <strong>in</strong>itiate a display connection");exit(1);}myscreen = DefaultScreen(mydisplay); /* display screen *//* <strong>de</strong>fault pixel values */mybackground = WhitePixel(mydisplay, myscreen);myforeground = BlackPixel(mydisplay, myscreen);/* specification of w<strong>in</strong>dow position and size */myh<strong>in</strong>t.x = 200; myh<strong>in</strong>t.y = 300;myh<strong>in</strong>t.width = 550; myh<strong>in</strong>t.height = 450;myh<strong>in</strong>t.flags = PPosition | PSize;/* w<strong>in</strong>dow creation */myw<strong>in</strong>1 = XCreateSimpleW<strong>in</strong>dow(mydisplay,DefaultRootW<strong>in</strong>dow(mydisplay),myh<strong>in</strong>t.x, myh<strong>in</strong>t.y, myh<strong>in</strong>t.width, myh<strong>in</strong>t.height,5, myforeground, mybackground);XSetStandardProperties(mydisplay, myw<strong>in</strong>1, hallo, hallo, \None, argv, argc, &myh<strong>in</strong>t);myh<strong>in</strong>t.x = 400; myh<strong>in</strong>t.y = 400;myh<strong>in</strong>t.width = 700; myh<strong>in</strong>t.height = 200;myh<strong>in</strong>t.flags = PPosition | PSize;myw<strong>in</strong>2 = XCreateSimpleW<strong>in</strong>dow(mydisplay,DefaultRootW<strong>in</strong>dow(mydisplay),myh<strong>in</strong>t.x, myh<strong>in</strong>t.y, myh<strong>in</strong>t.width, \myh<strong>in</strong>t.height, 5, myforeground, mybackground);/* creation of a new w<strong>in</strong>dow */XSetStandardProperties(mydisplay, myw<strong>in</strong>2, "Hallo", \"Hallo", None, argv, argc, &myh<strong>in</strong>t);/* pixmap creation */mypixmap = XCreatePixmap(mydisplay,DefaultRootW<strong>in</strong>dow(mydisplay),400, 200, DefaultDepth(mydisplay, myscreen));/* GC creation and <strong>in</strong>itialization */mygc1 = XCreateGC(mydisplay, myw<strong>in</strong>1, 0, 0);


1.11. WEITERE C-PROGRAMME 267mygc12 = XCreateGC(mydisplay, myw<strong>in</strong>2, 0, 0);newgc = XCreateGC(mydisplay, myw<strong>in</strong>2, 0, 0);/* <strong>de</strong>term<strong>in</strong>ation of <strong>de</strong>fault color map for a screen */cmap = DefaultColormap(mydisplay, myscreen);yellow.red = 65535; yellow.green = 65535; yellow.blue =/* allocation of a color cell */if (XAllocColor(mydisplay, cmap, &yellow) == 0) {fpr<strong>in</strong>tf(st<strong>de</strong>rr, "Cannot specify color");exit(2);}/* allocation of color cell us<strong>in</strong>g pre<strong>de</strong>f<strong>in</strong>edcolor-name */if (XAllocNamedColor(mydisplay, cmap, "red", &exact, \&color1) == 0){fpr<strong>in</strong>tf(st<strong>de</strong>rr, "Cannot use pre<strong>de</strong>f<strong>in</strong>ed color");exit(3);}if (XAllocNamedColor(mydisplay, cmap, "blue", &exact, \&color2) == 0){fpr<strong>in</strong>tf(st<strong>de</strong>rr, "Cannot use pre<strong>de</strong>f<strong>in</strong>ed color");exit(3);}if (XAllocNamedColor(mydisplay, cmap, "green", \&exact, &color3) == 0){fpr<strong>in</strong>tf(st<strong>de</strong>rr, "Cannot use pre<strong>de</strong>f<strong>in</strong>ed color");exit(3);}XSetW<strong>in</strong>dowBackground(mydisplay, myw<strong>in</strong>1, color2.pixel);/* chang<strong>in</strong>g the background of w<strong>in</strong>dow */XSetW<strong>in</strong>dowBackground(mydisplay, myw<strong>in</strong>2, color3.pixel);XSetBackground(mydisplay, mygc1, color2.pixel);/* sett<strong>in</strong>g foreground attribute <strong>in</strong> GC structure */XSetForeground(mydisplay, mygc1, yellow.pixel);/* sett<strong>in</strong>g background attribute <strong>in</strong> GC structure */XSetForeground(mydisplay, mygc12, color1.pixel);XSetBackground(mydisplay, mygc12, color3.pixel);XSetBackground(mydisplay, newgc, mybackground);XSetFont(mydisplay, mygc1, XLoadFont(mydisplay, \"vrb-25"));/* sett<strong>in</strong>g font attribute <strong>in</strong> GC structure */


268 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>XSetFont(mydisplay, mygc12, XLoadFont(mydisplay, \"vri-25"));XSetFont(mydisplay, newgc, XLoadFont(mydisplay, \"vri-25"));/* w<strong>in</strong>dow mapp<strong>in</strong>g */XMapRaised(mydisplay, myw<strong>in</strong>1);XMapRaised(mydisplay, myw<strong>in</strong>2);/* <strong>in</strong>put event selection */XSelectInput(mydisplay, myw<strong>in</strong>1, \KeyPressMask | ExposureMask);XSelectInput(mydisplay, myw<strong>in</strong>2, \KeyPressMask | ExposureMask |ButtonPressMask);/* ma<strong>in</strong> event-read<strong>in</strong>g loop */while (1) {XNextEvent(mydisplay, &myevent); /* read next event */switch (myevent.type) {/* process keyboard <strong>in</strong>put */case KeyPress:i = XLookupStr<strong>in</strong>g(&myevent, text, 10, &mykey, 0);if (i == 1 && (text[0] == ’q’ | text[0] == ’Q’)) {XFreeGC(mydisplay, mygc1);XFreeGC(mydisplay, mygc12);XFreeGC(mydisplay, newgc);if (!w<strong>in</strong>) XDestroyW<strong>in</strong>dow(mydisplay, neww<strong>in</strong>);XDestroyW<strong>in</strong>dow(mydisplay, myw<strong>in</strong>1);if (<strong>de</strong>l) XDestroyW<strong>in</strong>dow(mydisplay, myw<strong>in</strong>2);XFreePixmap(mydisplay, mypixmap);XCloseDisplay(mydisplay);exit(0);}elseif (i == 1 && (text[0] == ’c’ | text[0] == ’C’) &&myevent.xkey.w<strong>in</strong>dow == myw<strong>in</strong>1) {XClearW<strong>in</strong>dow(mydisplay, myw<strong>in</strong>1);XSetFont(mydisplay, mygc1, \XLoadFont(mydisplay, "fgb-13"));XDrawImageStr<strong>in</strong>g(mydisplay, myw<strong>in</strong>1, mygc1, \240, 400,SUBWIN, strlen(SUBWIN));XDrawImageStr<strong>in</strong>g(mydisplay, myw<strong>in</strong>1, mygc1, \240, 420,CLEAR, strlen(CLEAR));


1.11. WEITERE C-PROGRAMME 269XDrawImageStr<strong>in</strong>g(mydisplay, myw<strong>in</strong>1, mygc1, \240, 440,QUIT, strlen(QUIT));XSetFont(mydisplay, mygc1, \XLoadFont(mydisplay, "vrb-25"));}elseif (i == 1 && (text[0] == ’d’ | text[0] == ’D’)&& myevent.xkey.w<strong>in</strong>dow == myw<strong>in</strong>2) {XDestroyW<strong>in</strong>dow(mydisplay, myw<strong>in</strong>2);<strong>de</strong>l = 0;}elseif (i == 1 && (text[0] == ’n’ | text[0] == ’N’&& myevent.xkey.w<strong>in</strong>dow == myw<strong>in</strong>1)if (w<strong>in</strong>) {neww<strong>in</strong> = XCreateSimpleW<strong>in</strong>dow(mydisplay, \myw<strong>in</strong>1, 70, 60, 400, 200, 1, \myforeground, mybackground);/* w<strong>in</strong>dow mapp<strong>in</strong>g */XMapRaised(mydisplay, neww<strong>in</strong>);XSetForeground(mydisplay, newgc, \mybackground);XFillRectangle(mydisplay, mypixmap, newgc,0, 0, 400, 200);XSetForeground(mydisplay, newgc, \color1.pixel);XDrawImageStr<strong>in</strong>g(mydisplay, mypixmap, newg140, 100, WIN3, strlen(WINXSetFont(mydisplay, newgc, \XLoadFont(mydisplay, "fgb-13"));XDrawImageStr<strong>in</strong>g(mydisplay, mypixmap, newg180, DELSUB, strlen(DELSUXSetFont(mydisplay, newgc, \XLoadFont(mydisplay, "vri-25"));/* copy<strong>in</strong>g pixels from pixmap to w<strong>in</strong>dow */XCopyArea(mydisplay, mypixmap, neww<strong>in</strong>, new0, 0, 400, 200, 0,}elseXDestroySubw<strong>in</strong>dows(mydisplay, myw<strong>in</strong>1);w<strong>in</strong> = !w<strong>in</strong>;}break;/* repa<strong>in</strong>t w<strong>in</strong>dow on expose event */


270 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>case Expose:if (myevent.xexpose.count == 0) {XDrawImageStr<strong>in</strong>g(mydisplay, myw<strong>in</strong>1, mygc1,50, 50, WIN1, strlen(WIN1));XDrawImageStr<strong>in</strong>g(mydisplay, myw<strong>in</strong>2, mygc12,270, 50, WIN2, strlen(WIN2));XSetFont(mydisplay, mygc1, \XLoadFont(mydisplay, "fgb-13"));XDrawImageStr<strong>in</strong>g(mydisplay, myw<strong>in</strong>1, mygc1, \240, 400, SUBWIN, strlen(SUBWIN));XDrawImageStr<strong>in</strong>g(mydisplay, myw<strong>in</strong>1, mygc1, \240, 420, CLEAR, strlen(CLEAR));XDrawImageStr<strong>in</strong>g(mydisplay, myw<strong>in</strong>1, mygc1, \240, 440, QUIT, strlen(QUIT));XSetFont(mydisplay, mygc1, \XLoadFont(mydisplay, "vrb-25"));XDrawImageStr<strong>in</strong>g(mydisplay, myw<strong>in</strong>2, mygc12, \300, 180, DELETE, strlen(DELETE));XDrawL<strong>in</strong>e(mydisplay, myw<strong>in</strong>1, mygc1, \100, 100, 300, 300);XDrawSegments(mydisplay, myw<strong>in</strong>1, mygc1, \segments, num);XDrawArc(mydisplay, myw<strong>in</strong>1, mygc1, 200, \160, 200, 200, 0, 23040);XFillArc(mydisplay, myw<strong>in</strong>1, mygc12, 60, \200, 120, 120, 0, 23040);XDrawRectangle(mydisplay, myw<strong>in</strong>1, mygc1, \60, 200, 120, 120);}break;/* process mouse-button presses */case ButtonPress:XSetFont(mydisplay, mygc1, \XLoadFont(mydisplay,"vxms-37"));XDrawImageStr<strong>in</strong>g(myevent.xbutton.display, \myevent.xbutton.w<strong>in</strong>dow, mygc1, \myevent.xbutton.x, \myevent.xbutton.y, \hi, strlen(hi));XSetFont(mydisplay, mygc1, \XLoadFont(mydisplay, "vrb-25"));break;/* process keyboard mapp<strong>in</strong>g changes */case Mapp<strong>in</strong>gNotify:


1.11. WEITERE C-PROGRAMME 271}}}XRefreshKeyboardMapp<strong>in</strong>g(&myevent);Quelle 1.95 : C-Programm für das X W<strong>in</strong>dow System mit Funktionen<strong>de</strong>r Xlib-BibliothekDie Xlib-Biliothek stellt die unterste Stufe <strong>de</strong>r X11-Bibliotheken dar. Nach Möglichkeit verwen<strong>de</strong>t man höhereBibliotheken, die ihrerseits auf <strong>de</strong>r Xlib aufsetzen. Man erspartsich damit viel Mühe.1.11.11 cgi-ProgrammeDie Abkürzung cgi be<strong>de</strong>utet Common Gateway Interface. Dasist e<strong>in</strong> Protokoll zum Gedankenaustausch zwischen HTML-Forms und Programmen. Die Programme können <strong>in</strong> je<strong>de</strong>r Spracheverfasst se<strong>in</strong>, die es ermöglicht, von std<strong>in</strong> zu lesen, nachstdout zu schreiben und außer<strong>de</strong>m Umgebungsvariable auszuwerten.Obwohl viele <strong>de</strong>rartige Programme Perl-Skripte s<strong>in</strong>d –siehe Abschnitt ?? Forms und cgi-Scripts auf Seite ?? – ist dasnicht zw<strong>in</strong>gend, e<strong>in</strong> C-Programm tut es genau so gut und istschneller.TestGET-Formular


272 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>POST-FormularQuelle 1.96 : Webseite cgi_test.html mit FORM-Elementenzum Ausprobieren <strong>de</strong>r cgi-SchnittstelleE<strong>in</strong> Benutzer ruft mittels se<strong>in</strong>es Brausers e<strong>in</strong>e Webseite auf,die e<strong>in</strong> FORM-Element enthält. Was das im e<strong>in</strong>zelnen ist, tut hiernichts zur Sache und kann <strong>in</strong> HTML-Anleitungen nachgelesenwer<strong>de</strong>n. Unter <strong>de</strong>n Attributen <strong>de</strong>s FORM-Elements f<strong>in</strong><strong>de</strong>n sichaction und method. Die action gibt <strong>de</strong>n vollständigen o<strong>de</strong>rrelativen URL <strong>de</strong>s Programms an, das auf <strong>de</strong>m Webserver 36 ausgeführtwer<strong>de</strong>n soll. H<strong>in</strong>ter method f<strong>in</strong><strong>de</strong>t sich entwe<strong>de</strong>r posto<strong>de</strong>r get, wobei letzteres veraltet (<strong>de</strong>precated <strong>in</strong> HTML 4.0) ist.Der Benutzer gibt <strong>in</strong> die Webseite verschie<strong>de</strong>ne Werte e<strong>in</strong>,die durch die INPUT-Elemente näher spezifiert s<strong>in</strong>d, und drücktdann e<strong>in</strong> Knöpfchen, das submit o<strong>de</strong>r ähnlich heißt. Darauf h<strong>in</strong>verlangt <strong>de</strong>r Brauser vom WWW <strong>de</strong>n unter action genanntenURL unter Beifügung <strong>de</strong>r e<strong>in</strong>gegebenen Werte. Der Webserverstellt fest, dass e<strong>in</strong>es se<strong>in</strong>er cgi-Skripte verlangt wird, und ruftdieses auf./** cgi.h* Teil e<strong>in</strong>er Implementation <strong>de</strong>r CGI-Schnittstelle <strong>in</strong> C.*/#<strong>de</strong>f<strong>in</strong>e MAX QUERY LEN 4095 /* gegen Missbrauch */struct list item {36 Etwas völlig an<strong>de</strong>res s<strong>in</strong>d aktive Inhalte (Anweisungen <strong>in</strong>Javascript, Java-Applets) von Webseiten, die auf <strong>de</strong>m Computer<strong>de</strong>s Benutzers ausgeführt wer<strong>de</strong>n.


1.11. WEITERE C-PROGRAMME 273};struct list item *next;char *key, *value;struct array item {char *key, *value;};void unescape str(char *); /* eigene Funktionen */char *get query();struct list item *parse list(char *);struct array item *parse array(char *);Quelle 1.97 : Inclu<strong>de</strong>-Datei cgi.h zum Programm cgi_test.c/** cgi test.c, Hauptprogramm* Teil e<strong>in</strong>er Implementation <strong>de</strong>r CGI-Schnittstelle <strong>in</strong> C.* normalerweise entwe<strong>de</strong>r l<strong>in</strong>ked list o<strong>de</strong>r array verwen<strong>de</strong>n*/#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> "cgi.h"<strong>in</strong>t ma<strong>in</strong>() {char *list query, *array query;struct list item *param list;struct array item *param array;/* hiermit beg<strong>in</strong>nt die Ausgabe */pr<strong>in</strong>tf("Content-Type: text/pla<strong>in</strong>\015\012\015\012");/* query str<strong>in</strong>g ermitteln und duplizieren */list query = get query();if (list query == NULL) {pr<strong>in</strong>tf("Ke<strong>in</strong>e Parameter!\n");return 0;}array query = strdup(list query);/* l<strong>in</strong>ked list erzeugen */param list = parse list(list query);pr<strong>in</strong>tf("Parameter per L<strong>in</strong>ked List:\n");


274 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>while (param list != NULL) {pr<strong>in</strong>tf("%s = %s\n", param list->key, param list->valuparam list = param list->next;}/* array erzeugen */param array = parse array(array query);pr<strong>in</strong>tf("\nParameter per Array:\n");while (param array->key != NULL) {pr<strong>in</strong>tf("%s = %s\n", param array->key, param array->vaparam array++;}}return 0;Quelle 1.98 : C-Programm cgi_test.c zum Ausprobieren <strong>de</strong>r cgi-Schnittstelle/** cgi.c, Funktionen* Teil e<strong>in</strong>er Implementation <strong>de</strong>r CGI-Schnittstelle <strong>in</strong> C.*/#<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> #<strong>in</strong>clu<strong>de</strong> "cgi.h"/** Wan<strong>de</strong>lt alle %xx-Tripel <strong>in</strong> e<strong>in</strong>zelne Zeichen um und ’+’ <strong>in</strong>* wobei <strong>de</strong>r uebergebene Str<strong>in</strong>g veraen<strong>de</strong>rt wird!*/void unescape str(char *s) {size t i;for(i = strlen(s); i > 2; i-, s++) {if (*s == ’+’)*s = ’ ’;else if (*s == ’%’ && isxdigit(s[1]) && isxdigit(s[2]*s = (isdigit(s[1]) ? s[1] - ’0’ : tolower(s[1])(isdigit(s[2]) ? s[2] - ’0’ : tolower(s[2])memmove(s + 1, s + 3, i -= 2);}


1.11. WEITERE C-PROGRAMME 275}}/** Gibt <strong>de</strong>n query str<strong>in</strong>g zurueck, wenn ke<strong>in</strong>e Fehler auftre* ansonsten NULL. Unterschei<strong>de</strong>t dabei zwischen GET und PO* Darf bei POST nur e<strong>in</strong>mal aufgerufen wer<strong>de</strong>n!*/char *get query() {char *p, *q;size t len;/* REQUEST METHOD suchen */p = getenv("REQUEST METHOD");if (p == NULL) return NULL;/* ke<strong>in</strong>e REQUEST METH/* 1. Fall: GET */if (strcmp(p, "GET") == 0) {p = getenv("QUERY STRING");if (p == NULL) return NULL; /* ke<strong>in</strong> QUERY STRINGlen = strlen(p);if (len < 1 || len > MAX QUERY LEN) return NULL;q = malloc(len + 1);if (q == NULL) return NULL;memmove(q, p, len + 1); /* spart L<strong>in</strong>ken von sreturn q;/* 2. Fall: POST */} else if (strcmp(p, "POST") == 0) {p = getenv("CONTENT LENGTH");if (p == NULL) return NULL; /* ke<strong>in</strong>e CONTENT LENGlen = strtoul(p, NULL, 0);if (len < 1 || len > MAX QUERY LEN) return NULL;q = malloc(len + 1);if (q == NULL) return NULL;if (fread(q, 1, len, std<strong>in</strong>) < len)return NULL; /* Laenge von std<strong>in</strong> < CONTENTq[len] = ’\0’;return q;}/* 3. Fall: we<strong>de</strong>r noch - kann von diesem Programmnicht behan<strong>de</strong>lt wer<strong>de</strong>n */} else return NULL;/*


276 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>* Gibt e<strong>in</strong>e l<strong>in</strong>ked list <strong>de</strong>s geparsten query str<strong>in</strong>g zurueck,* wenn ke<strong>in</strong>e Fehler auftreten, ansonsten NULL. Veraen<strong>de</strong>rt* <strong>de</strong>n uebergebenen Str<strong>in</strong>g!*/struct list item *parse list(char *query) {struct list item first = { NULL }, *last = &first;while (*query != ’\0’) {/* neues Listenelement allozieren */last->next = malloc(sizeof *last);if(last == NULL) return first.next;last = last->next;last->next = NULL;/* e<strong>in</strong>en Parameter extrahieren */last->key = query;do {query++;} while (*query != ’\0’ && (*query != ’&’ || *(queryif (*query != ’\0’) *query++ = ’\0’;/* <strong>in</strong> key und value splitten */last->value = last->key;do {last->value++;} while (*last->value != ’\0’ && *last->value != ’=’)if (*last->value != ’\0’) *(last->value++) = ’\0’;}/* "%xx"-Tripel umwan<strong>de</strong>ln */unescape str(last->key);unescape str(last->value);}return first.next;/** Gibt e<strong>in</strong> Array von Strukturen zurueck mit <strong>de</strong>n geparsten* Parametern, falls ke<strong>in</strong>e Fehler auftreten, ansonsten NULL.* Geht dabei zweimal ueber <strong>de</strong>n query str<strong>in</strong>g, was aber nicht* weiter schlimm ist. Das Array wird durch e<strong>in</strong>e Struktur* abgeschlossen, bei <strong>de</strong>r bei<strong>de</strong> Werte (key und value) NULL si* Veraen<strong>de</strong>rt <strong>de</strong>n uebergebenen Str<strong>in</strong>g!*/struct array item *parse array(char *query) {<strong>in</strong>t count;char *temp;


1.11. WEITERE C-PROGRAMME 277struct array item *first, *last;/* Anzahl Parameter bestimmen */for (count = 0, temp = query; *temp != ’\0’; count++)do {temp++;} while (*temp != ’\0’ && (*temp != ’&’ || *(temp}if (count == 0) return NULL;/* Array allozieren */last = first = malloc(sizeof *first * (count + 1));if (last == NULL) return NULL;first[count].key = first[count].value = NULL;while (*query != ’\0’) {/* e<strong>in</strong>en Parameter extrahieren */last->key = query;do {query++;} while (*query != ’\0’ && (*query != ’&’ || *(queif (*query != ’\0’) *query++ = ’\0’;/* <strong>in</strong> key und value splitten */last->value = last->key;do {last->value++;} while (*last->value != ’\0’ && *last->value != ’if (*last->value != ’\0’) *(last->value++) = ’\0’;/* "%xx"-Tripel umwan<strong>de</strong>ln */unescape str(last->key);unescape str(last->value);}last++;}return first;Quelle 1.99 : C-Funktionen zum Programm cgi_test.cNun wird es spannend. Wie erfährt das cgi-Skript, hier e<strong>in</strong>C-Programm, von <strong>de</strong>n vom Benutzer e<strong>in</strong>gegebenen Werten? Bei<strong>de</strong>r Metho<strong>de</strong> get stehen die Werte als e<strong>in</strong> langer Str<strong>in</strong>g <strong>in</strong> <strong>de</strong>rUmgebungs-Variablen QUERY_STRING, bei <strong>de</strong>r Metho<strong>de</strong> postwird <strong>de</strong>r Str<strong>in</strong>g von std<strong>in</strong> gelesen. Der Rest besteht im Aufdrö-


278 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>seln (parsen) <strong>de</strong>s Str<strong>in</strong>gs, <strong>de</strong>r Verarbeitung <strong>de</strong>r e<strong>in</strong>zelnen Werteund <strong>de</strong>r Ausgabe e<strong>in</strong>es HTML-konformen Dokumentes nachstdout. Dieses Dokument schickt <strong>de</strong>r Webserver an <strong>de</strong>n anfragen<strong>de</strong>nBrauser zurück. Das wars. Fehler macht man vor allembei <strong>de</strong>n Kle<strong>in</strong>igkeiten wie Gänsefüßchen o<strong>de</strong>r Semikolons. E<strong>in</strong>großer Teil <strong>de</strong>s Programms besteht wie üblich im Abfangen unzulässigerE<strong>in</strong>gaben. Be<strong>de</strong>nken Sie, dass wildfrem<strong>de</strong> Benutzerdieses Programm auf Ihrem WWW-Server starten. Lesen Sie dasProgrammbeispiel und weitere aus <strong>de</strong>m Netz. Dort f<strong>in</strong><strong>de</strong>n sichauch Funktions- und Klassenbibliotheken für cgi-Programme<strong>in</strong> C/<strong>C++</strong>.1.12 Obfuscated CWie bereits <strong>in</strong> e<strong>in</strong>er Fußnote auf Seite 15 bemerkt, f<strong>in</strong><strong>de</strong>t jährliche<strong>in</strong> Wettbewerb um das undurchsichtigste C-Programm statt (toobfuscate = vernebeln, verwirren). Die Siegerprogramme habenaußer Nebel auch noch e<strong>in</strong>en Witz aufzuweisen. Als Beispiel gebenwir e<strong>in</strong> Programm von JACK APPLIN, Hewlett-Packard, FortColl<strong>in</strong>s/USA wie<strong>de</strong>r, das erfolgreich am Contest 1986 teilgenommenhat. Es ist das Hello-World-Programm <strong>in</strong> e<strong>in</strong>er Fassung,die als C-Programm, FORTRAN-77-Programm und als Bourne-Shellscript gültig ist 37cat =13 /*/ >/<strong>de</strong>v/null 2>&1; echo "Hello, world!"; exit** This program works un<strong>de</strong>r cc, f77, and /b<strong>in</strong>/sh.**/; ma<strong>in</strong>() {write(cat-~-cat/*,’(*/,"Hello, world!",cat); putchar(~-~-~-cat); } /*37 Unter www.ee.ryerson.ca:8080/˜elf/hack/multilang.htmliegt e<strong>in</strong> ähnliches Programm, das als C-Programm, Perl-Skript,Tcl-Skript und Shell-Skript gültig ist.


1.12. OBFUSCATED C 279*/,)’)endAuch die Leerzeichen s<strong>in</strong>d wichtig. Entfernt man die Kommentare,bleibt als C-Programm übrig:cat =13;ma<strong>in</strong>() {write(cat-~-cat, "Hello, world!", cat);putchar(~-~-~-cat); }Zuerst wird e<strong>in</strong>e globale Variable cat – per Defaultvom Typ <strong>in</strong>t – auf 13 gesetzt. Dann wird <strong>de</strong>r Systemaufrufwrite(1, "Hello, world!", 13) ausgeführt, <strong>de</strong>r13 Zeichen <strong>de</strong>s Str<strong>in</strong>gs Hello, world! nach stdout (Datei<strong>de</strong>skriptor1) schreibt, anschließend die Standardfunktionputchar(10). Der Gebrauch <strong>de</strong>s unären M<strong>in</strong>uszeichens samt<strong>de</strong>r bitweisen Negation ist ungewohnt. Man muß sich die Umrechnungen<strong>in</strong> Bits aufschreiben (negative Zahlen wer<strong>de</strong>n durchihr Zweierkomplement dargestellt). Bei write():13 gibt 0000 0000 0000 0000 0000 0000 0000 110-13 gibt 1111 1111 1111 1111 1111 1111 1111 001~(-13) gibt 0000 0000 0000 0000 0000 0000 0000 11013 - (~(-13))gibt 0000 0000 0000 0000 0000 0000 0000 000was <strong>de</strong>zimal 1 ist. Bei putchar() sieht die Geschichte so aus:13 gibt 0000 0000 0000 0000 0000 0000 0000 110-13 gibt 1111 1111 1111 1111 1111 1111 1111 001~(-13) gibt 0000 0000 0000 0000 0000 0000 0000 110-(~(-13)) gibt 1111 1111 1111 1111 1111 1111 1111 010~(-(~(-13)))gibt 0000 0000 0000 0000 0000 0000 0000 101-(~(-(~(-13))))gibt 1111 1111 1111 1111 1111 1111 1111 010~(-(~(-(~(-13)))))gibt 0000 0000 0000 0000 0000 0000 0000 101was <strong>de</strong>zimal 10 = ASCII-Zeichen L<strong>in</strong>efeed ist.Für FORTRAN 77 bleiben folgen<strong>de</strong> Zeilen übrig:


280 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>write(*, ’("Hello, world!")’)endZeilen, die an erster Stelle e<strong>in</strong> c o<strong>de</strong>r e<strong>in</strong> * enthalten, gelten alsKommentar. Zeilen, die an sechster Stelle irgen<strong>de</strong><strong>in</strong> Zeichen enthalten,wer<strong>de</strong>n als Fortsetzungen aufgefaßt. Anweisungen beg<strong>in</strong>nen<strong>in</strong> Spalte 7 (die Sitte stammt aus <strong>de</strong>r Lochkartenzeit).Das Shellscript enthält als e<strong>in</strong>zige wirksame Kommandos:echo "Hello, world!"; exitWas davor steht, geht nach /<strong>de</strong>v/null. Mit exit wird dasScript verlassen. Mehr solcher Scherze f<strong>in</strong><strong>de</strong>t man im Netz o<strong>de</strong>r<strong>in</strong> <strong>de</strong>m Buch von DON LIBES.E<strong>in</strong>e ähnliche <strong>in</strong>tellektuelle Herausfor<strong>de</strong>rung stellen dieQu<strong>in</strong>e-Programme dar. Das s<strong>in</strong>d Programme, die ihren eigenenQuellco<strong>de</strong> ausgeben. Näheres unter:http://www.nyx.net/~gthompso/qu<strong>in</strong>e.htm1.13 Portieren von Programmen1.13.1 RegelnUnter <strong>de</strong>m Übertragen o<strong>de</strong>r Portieren von Programmen verstehtman das Anpassen an e<strong>in</strong> an<strong>de</strong>res System unter Beibehaltung<strong>de</strong>r Programmiersprache o<strong>de</strong>r das Übersetzen <strong>in</strong> e<strong>in</strong>ean<strong>de</strong>re Programmiersprache auf <strong>de</strong>mselben System, schlimmstenfallsbei<strong>de</strong>s zugleich.E<strong>in</strong> Programm läßt sich immer portieren, <strong>in</strong><strong>de</strong>m man bis zurAufgabenstellung zurückgeht. Das ist mit <strong>de</strong>m maximalen Aufwandverbun<strong>de</strong>n; es läuft auf Neuschreiben h<strong>in</strong>aus. Unter günstigenUmstän<strong>de</strong>n kann e<strong>in</strong> Programm Zeile für Zeile übertragenwer<strong>de</strong>n, ohne die Aufgabe und die Algorithmen zu kennen. Indiesem Fall reicht die Intelligenz e<strong>in</strong>es Computers zum Portieren;es gibt auch Programme für diese Tätigkeit 38 . Die wirklichenAufgaben liegen zwischen diesen bei<strong>de</strong>n Grenzfällen.38 Im GNU-Projekt f<strong>in</strong><strong>de</strong>n sich e<strong>in</strong> Program f2c (lies: f to c)zum Übertragen von FORTRAN nach C und e<strong>in</strong> Programm p2czum Portieren von PASCAL nach C.


1.13. PORTIEREN VON PROGRAMMEN 281Schon beim ersten Schreiben e<strong>in</strong>es Programmes erleichtertman e<strong>in</strong> künftiges Portieren, wenn man e<strong>in</strong>ige Regeln beherzigt.Man vermei<strong>de</strong>:• Annahmen über Eigenheiten <strong>de</strong>s Datei-Systems (z. B. Länge<strong>de</strong>r Namen),• Annahmen über die Reihenfolge <strong>de</strong>r Auswertung von Ausdrücken,Funktionsargumenten o<strong>de</strong>r Nebeneffekten (z. B.bei pr<strong>in</strong>tf(3)),• Annahmen über die Anordnung <strong>de</strong>r Daten im Arbeitsspeicher,• Annahmen über die Anzahl <strong>de</strong>r signifikanten Zeichen vonNamen,• Annahmen über die automatische Initialisierung von Variablen,• <strong>de</strong>n Gebrauch von stillschweigen<strong>de</strong>n (automatischen) Typumwandlungen,zum Beispiel von long nach <strong>in</strong>t unter<strong>de</strong>r Annahme, daß die bei<strong>de</strong>n Typen gleich lang s<strong>in</strong>d,• das Mischen von vorzeichenlosen und vorzeichenbehaftetenWerten,• die Dereferenzierung von Nullpo<strong>in</strong>tern (Null ist ke<strong>in</strong>eAdresse),• Annahmen über die Darstellung von Po<strong>in</strong>tern (Po<strong>in</strong>ter s<strong>in</strong>dke<strong>in</strong>e Ganzzahlen), Zuweisungen von Po<strong>in</strong>terwerten an<strong>in</strong>t- o<strong>de</strong>r long-Variable,• die Annahme, e<strong>in</strong>en Po<strong>in</strong>ter <strong>de</strong>referenzieren zu können, <strong>de</strong>rnicht richtig auf e<strong>in</strong>e Datengrenze ausgerichtet ist (Alignment),• die Annahme, daß Groß- und Kle<strong>in</strong>buchstaben unterschie<strong>de</strong>nwer<strong>de</strong>n,• die Annahme, daß <strong>de</strong>r Typ char vorzeichenbehaftet o<strong>de</strong>rvorzeichenlos ist (EOF = -1?),• Bitoperationen mit vorzeichenbehafteten Ganzzahlen,• die Verwendung von Bitfel<strong>de</strong>rn mit an<strong>de</strong>ren Typen alsunsigned,• Annahmen über das Vorzeichen <strong>de</strong>s Divisionsrestes bei <strong>de</strong>rganzzahligen Division,


282 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>• die Annahme, daß e<strong>in</strong>e extern-Deklaration <strong>in</strong> e<strong>in</strong>em Blockauch außerhalb <strong>de</strong>s Blockes gilt.Diese und noch e<strong>in</strong>ige D<strong>in</strong>ge wer<strong>de</strong>n von unterschiedlichen Betriebssystemenund Compilern unterschiedlich gehandhabt, undman weiß nie, was e<strong>in</strong>em begegnet. Dagegen soll man:• <strong>de</strong>n Syntax-Prüfer l<strong>in</strong>t(1) befragen,• Präprozessor-Anweisungen und type<strong>de</strong>f benutzen, umAbhängigkeiten e<strong>in</strong>zugrenzen,• alle Variablen, Po<strong>in</strong>ter und Funktionen or<strong>de</strong>ntlich <strong>de</strong>klarieren,• Funktions-Prototypen verwen<strong>de</strong>n,• symbolische Konstanten (#<strong>de</strong>f<strong>in</strong>e) anstelle von rätselhaftenWerten im Programm verwen<strong>de</strong>n,• richtig ausgerichtete Unions anstelle von trickreichenÜberlagerungen von Typen verwen<strong>de</strong>n,• <strong>de</strong>n sizeof()-Operator verwen<strong>de</strong>n, wenn man die Größevon Typen o<strong>de</strong>r Variablen braucht,• daran <strong>de</strong>nken, daß die Größe von Datentypen je nach Architekturunterschiedlich ist,• umfangreiche Deklarationen <strong>in</strong> Inclu<strong>de</strong>-Dateien packen,• nur die C-Standard-Funktionen verwen<strong>de</strong>n o<strong>de</strong>r für an<strong>de</strong>reFunktionen die Herkunft o<strong>de</strong>r <strong>de</strong>n Quellco<strong>de</strong> angeben,m<strong>in</strong><strong>de</strong>stens aber die Funktionalität und die Syntax,• bei pr<strong>in</strong>tf(3) o<strong>de</strong>r scanf(3) die richtigen Platzhalterverwen<strong>de</strong>n (%ld für long),• alle unvermeidlichen Systemabhängigkeiten auf wenigeStellen konzentrieren und <strong>de</strong>utlich kommentieren.Im folgen<strong>de</strong>n wollen wir e<strong>in</strong>ige Beispiele betrachten, die nichtallzu lang und daher auch nur e<strong>in</strong>fach se<strong>in</strong> können.1.13.2 Übertragen von ALGOL nach CWir haben hier e<strong>in</strong> ALGOL-Programm von RICHARD WAGNERaus <strong>de</strong>m Buch von KARL NICKEL ALGOL-Praktikum (1964) ausgewählt,weil es mit Sicherheit nicht im H<strong>in</strong>blick auf e<strong>in</strong>e Übertragungnach C geschrieben wor<strong>de</strong>n ist. Es geht um die Bestimmung<strong>de</strong>s größten geme<strong>in</strong>samen Teilers mit <strong>de</strong>m Algorithmus


1.13. PORTIEREN VON PROGRAMMEN 283von EUKLID. Daß wir die Aufgabe und <strong>de</strong>n Algorithmus kennen,erleichtert die Arbeit, daß außer e<strong>in</strong>igen Graubärten niemandmehr ALGOL kennt, erschwert sie.’BEGIN’ ’COMMENT’ BEISPIEL 12 ;’INTEGER’ A, B, X, Y, R ;L1:READ(A,B) ;’IF’ A ’NOT LESS’ B’THEN”BEGIN’ X:= A ; Y:= B ’END’’ELSE”BEGIN’ X:= B ; Y:= A ’END’ ;L2:R:= X - Y*ENTIER(X/Y) ;’IF’ R ’NOT EQUAL’ 0 ’THEN”BEGIN’ X:= Y ; Y:= R ;’GO TO’ L2 ’END’ ;PRINT(A,B,Y) ;’GO TO’ L1’END’Quelle 1.100 : ALGOL-Programm ggT nach EuklidDie E<strong>in</strong>lese- und Übersetzungszeit auf e<strong>in</strong>er Z22 betrug 50 s,die Rechen- und Druckzeit 39 s. Damals hatten schnelle Kopfrechnernoch e<strong>in</strong>e Chance. E<strong>in</strong>e Analyse <strong>de</strong>s Quelltextes ergibt:• Das Programm besteht aus e<strong>in</strong>er Datei mit <strong>de</strong>m Hauptprogramm(war kaum an<strong>de</strong>rs möglich),• Schlüsselwörter stehen <strong>in</strong> Hochkommas,• logische Blöcke wer<strong>de</strong>n durch beg<strong>in</strong> und end begrenzt,• es kommen nur ganzzahlige Variable vor,• es wird Ganzzahl-Arithmetik verwen<strong>de</strong>t,• an Funktionen treten read() und pr<strong>in</strong>t() auf,• an Kontrollanweisungen wer<strong>de</strong>n if - then - else undgoto verwen<strong>de</strong>t.Das sieht hoffnungsvoll aus. Die Übertragung nach C:/* Groesster geme<strong>in</strong>samer Teiler nach EuklidUebertragung e<strong>in</strong>es ALGOL-Programms aus K. Nickel nach Czu compilieren mit cc -o ggt ggt.c */#<strong>in</strong>clu<strong>de</strong>


284 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong><strong>in</strong>t ma<strong>in</strong>(){<strong>in</strong>t a, b, x, y, r;while(1) {/* E<strong>in</strong>gabe */puts("ggT von a und b nach Euklid");puts("Been<strong>de</strong>n mit E<strong>in</strong>gabe 0");pr<strong>in</strong>tf("Bitte a und b e<strong>in</strong>geben: ");scanf("%d %d", &a, &b);/* Been<strong>de</strong>n, falls a o<strong>de</strong>r b gleich 0 */if ((a == 0) || (b == 0)) exit(0);/* x muss <strong>de</strong>n groesseren Wert aus a und b enthalten */if (a >= b) { x = a; y = b; }else { x = b; y = a; }/* Euklid */while (r = x % y) {x = y;y = r;}/* Ausgabe */}}pr<strong>in</strong>tf("%d und %d haben <strong>de</strong>n ggT %d\n", a, b, y);Quelle 1.101 : C-Programm ggT nach EuklidDer auch nach UNIX-Maßstäben karge Dialog <strong>de</strong>s ALGOL-Programms wur<strong>de</strong> etwas angereichert, die goto-Schleifen wur<strong>de</strong>ndurch while-Schleifen ersetzt und <strong>de</strong>r ALGOL-Behelf zurBerechnung <strong>de</strong>s Divisionsrestes (entier) durch die <strong>in</strong> C vorhan<strong>de</strong>neModulo-Operation.Bei e<strong>in</strong>em Vergleich mit <strong>de</strong>m Programm 1.55 C-Programmggt nach Euklid, rekursiv auf Seite 160 sieht man, wie unterschiedlichselbst e<strong>in</strong> so e<strong>in</strong>facher Algorithmus programmiert


1.13. PORTIEREN VON PROGRAMMEN 285wer<strong>de</strong>n kann. Dazu kommen an<strong>de</strong>re Algorithmen zur Lösung<strong>de</strong>rselben Aufgabe, beispielsweise das Ermitteln aller Teiler <strong>de</strong>rbei<strong>de</strong>n Zahlen und das Herausfischen <strong>de</strong>s ggT.1.13.3 Übertragen von FORTRAN nach CGegeben sei e<strong>in</strong> e<strong>in</strong>faches Programm zur Lösung quadratischerGleichungen <strong>in</strong> FORTRAN77:c --------------------------------c Loesung <strong>de</strong>r quadratischen Gleichungc a*x*x + b*x + c = 0c reelle Koeffizienten, Loesungen auch komplexc --------------------------------program quadcreal a,b,c,d,h,r,s,x1,x2real epscomplex x1c,x2cdata eps/1.0e-30/cwrite(*,*) ’Loesung von a*x*x + b*x + c = 0’write(*,*) ’Bitte a, b, und c e<strong>in</strong>geben’read (*,*) a,b,cc --------------------------------c 1. Fall : a nahe Null, l<strong>in</strong>eare Gleichungc --------------------------------if (abs(a) .lt. eps) thenwrite(*,*) ’WARNUNG : a nahe Null,1 Null angenommen’if (abs(b) .lt. eps) thenwrite(*,*) ’WARNUNG : auch b nahe Null,1 Uns<strong>in</strong>n’goto 100elsewrite(*,*) ’Loesung : x = ’,-c/bgoto 100endifelsec --------------------------------c Berechnung <strong>de</strong>r Diskrim<strong>in</strong>anten dc --------------------------------d = b*b - 4.0*a*ch = a+ac --------------------------------


286 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>c 2. Fall : e<strong>in</strong>e o<strong>de</strong>r zwei reelle Loesungenc --------------------------------if ( d .ge. 0.0 ) thens = sqrt(d)x1 = (-b + s) / hx2 = (-b - s) / h1write(*,*) ’E<strong>in</strong>e o<strong>de</strong>r zwei reelleLoesungen’write(*,*) ’x1 = ’, x1write(*,*) ’x2 = ’, x2goto 100c --------------------------------c 3. Fall : konjugiert komplexe Loesungenc --------------------------------elser = -b / hs = sqrt(-d) / hx1c = cmplx(r,s)x2c = cmplx(r,-s )1write(*,*) ’Konjugiert komplexeLoesungen’write(*,*) ’x1 = ’, x1cwrite(*,*) ’x2 = ’, x2cgoto 100endifendifc --------------------------------c Programmen<strong>de</strong>c --------------------------------100 stopendQuelle 1.102 : FORTRAN-Programm Quadratische Gleichungmit reellen KoeffizientenE<strong>in</strong>e Analyse <strong>de</strong>s Quelltextes ergibt:• Das Programm besteht aus e<strong>in</strong>er Datei mit e<strong>in</strong>em Hauptprogramm,• es kommen reelle und komplexe Variable vor,• es wird Gleitkomma-Arithmetik verwen<strong>de</strong>t, aber ke<strong>in</strong>eKomplex-Arithmetik (was die Übertragung nach C erleichtert),• an Funktionen treten abs(), sqrt() und cmplx() auf,


1.13. PORTIEREN VON PROGRAMMEN 287• an Kontrollanweisungen wer<strong>de</strong>nif - then - else - endif und goto verwen<strong>de</strong>t.Wir wer<strong>de</strong>n etwas Arbeit mit <strong>de</strong>n komplexen Operan<strong>de</strong>n haben.Die Sprunganweisung goto gibt es zwar <strong>in</strong> C, aber wir bleibenstandhaft und vermei<strong>de</strong>n sie. Alles übrige sieht e<strong>in</strong>fach aus.Als Ersatz für <strong>de</strong>n komplexen Datentyp bietet sich e<strong>in</strong> Arrayof float o<strong>de</strong>r double an. E<strong>in</strong>e Struktur wäre auch möglich.Falls komplexe Arithmetik vorkäme, müßten wir uns die Operationenselbst schaffen. Hier wer<strong>de</strong>n aber nur die komplexenZahlen ausgegeben, was harmlos ist. Das goto wird hier nur gebraucht,um nach <strong>de</strong>r Ausgabe <strong>de</strong>r Lösung ans Programmen<strong>de</strong>zu spr<strong>in</strong>gen. Wir wer<strong>de</strong>n <strong>in</strong> C dafür e<strong>in</strong>e Funktion done() aufrufen.Das nach C übertragene Programm:/* Loesung <strong>de</strong>r quadratischen Gleichung a*x*x + b*x + c = 0reelle Koeffizienten, Loesungen auch komplexzu compilieren mit cc quad.c -lm */#<strong>de</strong>f<strong>in</strong>e EPS 1.0e-30 /* Typ double! */#<strong>in</strong>clu<strong>de</strong> /* wg. puts, pr<strong>in</strong>tf, scanf *#<strong>in</strong>clu<strong>de</strong> /* wg. fabs, sqrt */<strong>in</strong>t done();<strong>in</strong>t ma<strong>in</strong>(){double a, b, c, d, h, s, x1, x2;double z[2];puts("Loesung von a*x*x + b*x + c = 0");puts("Bitte a, b und c e<strong>in</strong>geben");scanf("%lf %lf %lf", &a, &b, &c);/* 1. Fall: a nahe Null, l<strong>in</strong>eare Gleichung */if (fabs(a) < EPS) {puts("WARNUNG: a nahe Null, als Null angenommen");if (fabs(b) < EPS) {puts("WARNUNG: auch b nahe Null, Uns<strong>in</strong>n");done();}else {pr<strong>in</strong>tf("Loesung: %lf\n", -c/b);


288 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}}else {done();/* Berechnung <strong>de</strong>r Diskrim<strong>in</strong>anten d */d = b * b - 4.0 * a * c;h = a + a;/* 2. Fall: e<strong>in</strong>e o<strong>de</strong>r zwei reelle Loesungen */if (d >= 0.0) {s = sqrt(d);x1 = (-b + s) / h;x2 = (-b - s) / h;puts("E<strong>in</strong>e o<strong>de</strong>r zwei reelle Loesungen");pr<strong>in</strong>tf("x1 = %lf\n", x1);pr<strong>in</strong>tf("x2 = %lf\n", x2);done();}else {/* 3. Fall: konjugiert komplexe Loesungen */}}}z[0] = -b / h;z[1] = sqrt(-d) / h;puts("Konjugiert komplexe Loesungen");pr<strong>in</strong>tf("x1 = (%lf %lf)\n", z[0], z[1]);pr<strong>in</strong>tf("x2 = (%lf %lf)\n", z[0], -z[1]);done();/* Funktion done() zur Beendigung <strong>de</strong>s Programms */<strong>in</strong>t done(){return(0);}Quelle 1.103 : C-Programm Quadratische Gleichung mit reellenKoeffizienten und komplexen Lösungen, aus FORTRAN übertragen


1.14. EXKURS ÜBER ALGORITHMEN 289Bei <strong>de</strong>r Übertragung haben wir ke<strong>in</strong>en Gebrauch von unserenKenntnissen über quadratische Gleichungen gemacht, son<strong>de</strong>rnziemlich schematisch gearbeitet. Mathematische Kenntnisses<strong>in</strong>d trotz<strong>de</strong>m hilfreich, auch sonst im Leben.Wir erhöhen <strong>de</strong>n Reiz <strong>de</strong>r Aufgabe, <strong>in</strong><strong>de</strong>m wir auch komplexeKoeffizienten zulassen: Schließlich wollen wir das Programm alsFunktion (Subrout<strong>in</strong>e) schreiben, die von e<strong>in</strong>em übergeordnetenProgramm aufgerufen wird:1.14 Exkurs über AlgorithmenDer Begriff Algorithmus – benannt nach e<strong>in</strong>em usbekischenMathematiker <strong>de</strong>s 9. Jahrhun<strong>de</strong>rts – kommt im vorliegen<strong>de</strong>nText selten vor, taucht aber <strong>in</strong> fast allen Programmierbüchernauf. E<strong>in</strong> beträchtlicher Teil <strong>de</strong>r Informatik befaßt sich damit.Locker ausgedrückt ist e<strong>in</strong> Algorithmus e<strong>in</strong>e Vorschrift, die mitendlich vielen Schritten zur Lösung e<strong>in</strong>es gegebenen Problemsführt. E<strong>in</strong> Programm ist die Umsetzung e<strong>in</strong>es Algorithmus <strong>in</strong> e<strong>in</strong>eProgrammiersprache. Algorithmen wer<strong>de</strong>n mit Worten, Formelno<strong>de</strong>r Grafiken dargestellt. E<strong>in</strong> Existenzbeweis ist <strong>in</strong> <strong>de</strong>rMathematik schon e<strong>in</strong> Erfolg, <strong>in</strong> <strong>de</strong>r Technik brauchen wir e<strong>in</strong>enLösungsweg, e<strong>in</strong>en Algorithmus.Das kl<strong>in</strong>gt alltäglich. Das Rezept zum Backen e<strong>in</strong>er Pr<strong>in</strong>zregententorte39 o<strong>de</strong>r die Beschreibung <strong>de</strong>s Aufstiegs auf die Hochwil<strong>de</strong><strong>in</strong> <strong>de</strong>n Ötztaler Alpen 40 s<strong>in</strong>d <strong>de</strong>mnach Algorithmen. E<strong>in</strong>igeAnfor<strong>de</strong>rungen an Algorithmen s<strong>in</strong>d:• Korrektheit. Das kl<strong>in</strong>gt selbstverständlich, ist aber meistschwierig zu beweisen. Und Korrektheit <strong>in</strong> e<strong>in</strong>em E<strong>in</strong>zelfallbesagt gar nichts. Umgekehrt beweist bereits e<strong>in</strong> Fehler dieInkorrektheit.• E<strong>in</strong><strong>de</strong>utigkeit. Das stellt Anfor<strong>de</strong>rungen an die Darstellungsweise,die Sprache; <strong>de</strong>nken Sie an e<strong>in</strong>e technische39 Dr. Oetker Backen macht Freu<strong>de</strong>, Ceres-Verlag, Bielefeld.Die Ausführung dieses Algorithmus läßt sich teilweise parallelisieren.40 H. KLIER, Alpenvere<strong>in</strong>sführer Ötztaler Alpen, BergverlagRudolf Rother, München. Der Algorithmus muß sequentiell abgeschwitztwer<strong>de</strong>n.


290 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Zeichnung o<strong>de</strong>r an Klaviernoten. Verschie<strong>de</strong>ne Ausführungsweges<strong>in</strong>d zulässig, bei gleichen E<strong>in</strong>gaben muß dasgleiche Ergebnis herauskommen.• Endlichkeit. Die Beschreibung <strong>de</strong>s Algorithmus muß e<strong>in</strong>eendliche Länge haben, sonst könnte man ihn endlichenWesen nicht mitteilen. Er muß ferner e<strong>in</strong>e endliche Ausführungszeithaben, man möchte se<strong>in</strong>e Früchte ja noch zuLebzeiten ernten. Er darf zur Ausführung nur e<strong>in</strong>e endlicheMenge von Betriebsmitteln belegen.• Allgeme<strong>in</strong>heit. 3 × 4 = 12 ist ke<strong>in</strong> Algorithmus, wohl aberdie Vorschrift, wie man die Multiplikation auf die Additionzurückführt.Man kann die Anfor<strong>de</strong>rungen herabschrauben und kommt dabeizu reizvollen Fragestellungen, aber für <strong>de</strong>n Anfang gilt obiges.E<strong>in</strong>e fünfte, technisch wie theoretisch be<strong>de</strong>utsame For<strong>de</strong>rung istdie nach e<strong>in</strong>em guten, zweckmäßigen Algorithmus o<strong>de</strong>r gar dienach <strong>de</strong>m besten. Denken Sie an die vielen Sortierverfahren (ke<strong>in</strong>esist das beste für alle Fälle).Es gibt – sogar ziemlich leicht verständliche – Aufgaben, dienicht mittels e<strong>in</strong>es Algorithmus zu lösen s<strong>in</strong>d. Falls Sie Bedarfan solchen Nüssen haben, suchen Sie unter <strong>de</strong>m Stichwort Entscheidbarkeit<strong>in</strong> Werken zur Theoretischen Informatik.


... aber die Daten fehlen, um <strong>de</strong>n ganzenNonsens richtig zu überblicken –Benn, Drei alte MännerAZahlensystemeAußer <strong>de</strong>m Dezimalsystem s<strong>in</strong>d das Dual-, das Oktal- unddas Hexa<strong>de</strong>zimalsystem gebräuchlich. Ferner spielt das B<strong>in</strong>ärcodierte Dezimalsystem (BCD) bei manchen Anwendungene<strong>in</strong>e Rolle. Bei diesem s<strong>in</strong>d die e<strong>in</strong>zelnen Dezimalstellen für sichdual dargestellt. Die folgen<strong>de</strong> Tabelle enthält die Werte von 0 bis<strong>de</strong>zimal 255. Bequemlichkeitshalber s<strong>in</strong>d auch die zugeordnetenASCII-Zeichen aufgeführt.<strong>de</strong>zimal dual oktal hex BCD ASCII0 0 0 0 0 nul1 1 1 1 1 soh2 10 2 2 10 stx3 11 3 3 11 etx4 100 4 4 100 eot5 101 5 5 101 enq6 110 6 6 110 ack7 111 7 7 111 bel8 1000 10 8 1000 bs9 1001 11 9 1001 ht10 1010 12 a 1.0 lf11 101 13 b 1.1 vt12 1100 14 c 1.10 ff13 1101 15 d 1.11 cr14 1110 16 e 1.100 so15 1111 17 f 1.101 si16 10000 20 10 1.110 dle17 10001 21 11 1.111 dc118 10010 22 12 1.1000 dc219 10011 23 13 1.1001 dc320 10100 24 14 10.0 dc421 10101 25 15 10.1 nak22 10110 26 16 10.10 syn291


292 ANHANG A. ZAHLENSYSTEME23 10111 27 17 10.11 etb24 11000 30 18 10.100 can25 11001 31 19 10.101 em26 11010 32 1a 10.110 sub27 11011 33 1b 10.111 esc28 11100 34 1c 10.1000 fs29 11101 35 1d 10.1001 gs30 11110 36 1e 11.0 rs31 11111 37 1f 11.1 us32 100000 40 20 11.10 space33 100001 41 21 11.11 !34 100010 42 22 11.100 ”35 100011 43 23 11.101 #36 100100 44 24 11.110 $37 100101 45 25 11.111 %38 100110 46 26 11.1000 &39 100111 47 27 11.1001 ’40 101000 50 28 100.0 (41 101001 51 29 100.1 )42 101010 52 2a 100.10 *43 101011 53 2b 100.11 +44 101100 54 2c 100.100 ,45 101101 55 2d 100.101 -46 101110 56 2e 100.110 .47 101111 57 2f 100.111 /48 110000 60 30 100.1000 049 110001 61 31 100.1001 150 110010 62 32 101.0 251 110011 63 33 101.1 352 110100 64 34 101.10 453 110101 65 35 101.11 554 110110 66 36 101.100 655 110111 67 37 101.101 756 111000 70 38 101.110 857 111001 71 39 101.111 958 111010 72 3a 101.1000 :59 111011 73 3b 101.1001 ;60 111100 74 3c 110.0


29363 111111 77 3f 110.11 ?64 1000000 100 40 110.100 @65 1000001 101 41 110.101 A66 1000010 102 42 110.110 B67 1000011 103 43 110.111 C68 1000100 104 44 110.1000 D69 1000101 105 45 110.1001 E70 1000110 106 46 111.0 F71 1000111 107 47 111.1 G72 1001000 110 48 111.10 H73 1001001 111 49 111.11 I74 1001010 112 4a 111.100 J75 1001011 113 4b 111.101 K76 1001100 114 4c 111.110 L77 1001101 115 4d 111.111 M78 1001110 116 4e 111.1000 N79 1001111 117 4f 111.1001 O80 1010000 120 50 1000.0 P81 1010001 121 51 1000.1 Q82 1010010 122 52 1000.10 R83 1010011 123 53 1000.11 S84 1010100 124 54 1000.100 T85 1010101 125 55 1000.101 U86 1010110 126 56 1000.110 V87 1010111 127 57 1000.111 W88 1011000 130 58 1000.1000 X89 1011001 131 59 1000.1001 Y90 1011010 132 5a 1001.0 Z91 1011011 133 5b 1001.1 [92 1011100 134 5c 1001.10 \93 1011101 135 5d 1001.11 ]94 1011110 136 5e 1001.100 ^95 1011111 137 5f 1001.101 _96 1100000 140 60 1001.110 ‘97 1100001 141 61 1001.111 a98 1100010 142 62 1001.1000 b99 1100011 143 63 1001.1001 c100 1100100 144 64 1.0.0 d101 1100101 145 65 1.0.1 e102 1100110 146 66 1.0.10 f


294 ANHANG A. ZAHLENSYSTEME103 1100111 147 67 1.0.11 g104 1101000 150 68 1.0.100 h105 1101001 151 69 1.0.101 i106 1101010 152 6a 1.0.110 j107 1101011 153 6b 1.0.111 k108 1101100 154 6c 1.0.1000 l109 1101101 155 6d 1.0.1001 m110 1101110 156 6e 1.1.0 n111 1101111 157 6f 1.1.1 o112 1110000 160 70 1.1.10 p113 1110001 161 71 1.1.11 q114 1110010 162 72 1.1.100 r115 1110011 163 73 1.1.101 s116 1110100 164 74 1.1.110 t117 1110101 165 75 1.1.111 u118 1110110 166 76 1.1.1000 v119 1110111 167 77 1.1.1001 w120 1111000 170 78 1.10.0 x121 1111001 171 79 1.10.1 y122 1111010 172 7a 1.10.10 z123 1111011 173 7b 1.10.11 {124 1111100 174 7c 1.10.100 |125 1111101 175 7d 1.10.101 }126 1111110 176 7e 1.10.110 ~127 1111111 177 7f 1.10.111 <strong>de</strong>l128 10000000 200 80 1.10.1000129 10000001 201 81 1.10.1001130 10000010 202 82 1.11.0131 10000011 203 83 1.11.1132 10000100 204 84 1.11.10133 10000101 205 85 1.11.11134 10000110 206 86 1.11.100135 10000111 207 87 1.11.101136 10001000 210 88 1.11.110137 10001001 211 89 1.11.111138 10001010 212 8a 1.11.1000139 10001011 213 8b 1.11.1001140 10001100 214 8c 1.100.0141 10001101 215 8d 1.100.1142 10001110 216 8e 1.100.10


143 10001111 217 8f 1.100.11144 10010000 220 90 1.100.100145 10010001 221 91 1.100.101146 10010010 222 92 1.100.110147 10010011 223 93 1.100.111148 10010100 224 94 1.100.1000149 10010101 225 95 1.100.1001150 10010110 226 96 1.101.0151 10010111 227 97 1.101.1152 10011000 230 98 1.101.10153 10011001 231 99 1.101.11154 10011010 232 9a 1.101.100155 10011011 233 9b 1.101.101156 10011100 234 9c 1.101.110157 10011101 235 9d 1.101.111158 10011110 236 9e 1.101.1000159 10011111 237 9f 1.101.1001160 10100000 240 a0 1.110.0161 10100001 241 a1 1.110.1162 10100010 242 a2 1.110.10163 10100011 243 a3 1.110.11164 10100100 244 a4 1.110.100165 10100101 245 a5 1.110.101166 10100110 246 a6 1.110.110167 10100111 247 a7 1.110.111168 10101000 250 a8 1.110.1000169 10101001 251 a9 1.110.1001170 10101010 252 aa 1.111.0171 10101011 253 ab 1.111.1172 10101100 254 ac 1.111.10173 10101101 255 ad 1.111.11174 10101110 256 ae 1.111.100175 10101111 257 af 1.111.101176 10110000 260 b0 1.111.110177 10110001 261 b1 1.111.111178 10110010 262 b2 1.111.1000179 10110011 263 b3 1.111.1001180 10110100 264 b4 1.1000.0181 10110101 265 b5 1.1000.1182 10110110 266 b6 1.1000.10295


296 ANHANG A. ZAHLENSYSTEME183 10110111 267 b7 1.1000.11184 10111000 270 b8 1.1000.100185 10111001 271 b9 1.1000.101186 10111010 272 ba 1.1000.110187 10111011 273 bb 1.1000.111188 10111100 274 bc 1.1000.1000189 10111101 275 bd 1.1000.1001190 10111110 276 be 1.1001.0191 10111111 277 bf 1.1001.1192 11000000 300 c0 1.1001.10193 11000001 301 c1 1.1001.11194 11000010 302 c2 1.1001.100195 11000011 303 c3 1.1001.101196 11000100 304 c4 1.1001.110197 11000101 305 c5 1.1001.111198 11000110 306 c6 1.1001.1000199 11000111 307 c7 1.1001.1001200 11001000 310 c8 10.0.0201 11001001 311 c9 10.0.1202 11001010 312 ca 10.0.10203 11001011 313 cb 10.0.11204 11001100 314 cc 10.0.100205 11001101 315 cd 10.0.101206 11001110 316 ce 10.0.110207 11001111 317 cf 10.0.111208 11010000 320 d0 10.0.1000209 11010001 321 d1 10.0.1001210 11010010 322 d2 10.1.0211 11010011 323 d3 10.1.1212 11010100 324 d4 10.1.10213 11010101 325 d5 10.1.11214 11010110 326 d6 10.1.100215 11010111 327 d7 10.1.101216 11011000 330 d8 10.1.110217 11011001 331 d9 10.1.111218 11011010 332 da 10.1.1000219 11011011 333 db 10.1.1001220 11011100 334 dc 10.10.0221 11011101 335 dd 10.10.1222 11011110 336 <strong>de</strong> 10.10.10


223 11011111 337 df 10.10.11224 11100000 340 e0 10.10.100225 11100001 341 e1 10.10.101226 11100010 342 e2 10.10.110227 11100011 343 e3 10.10.111228 11100100 344 e4 10.10.1000229 11100101 345 e5 10.10.1001230 11100110 346 e6 10.11.0231 11100111 347 e7 10.11.1232 11101000 350 e8 10.11.10233 11101001 351 e9 10.11.11234 11101010 352 ea 10.11.100235 11101011 353 eb 10.11.101236 11101100 354 ec 10.11.110237 11101101 355 ed 10.11.111238 11101110 356 ee 10.11.1000239 11101111 357 ef 10.11.1001240 11110000 360 f0 10.100.0241 11110001 361 f1 10.100.1242 11110010 362 f2 10.100.10243 11110011 363 f3 10.100.11244 11110100 364 f4 10.100.100245 11110101 365 f5 10.100.101246 11110110 366 f6 10.100.110247 11110111 367 f7 10.100.111248 11111000 370 f8 10.100.1000249 11111001 371 f9 10.100.1001250 11111010 372 fa 10.101.0251 11111011 373 fb 10.101.1252 11111100 374 fc 10.101.10253 11111101 375 fd 10.101.11254 11111110 376 fe 10.101.100255 11111111 377 ff 10.101.101297


BZeichensätzeB.1 EBCDIC, ASCII, Roman8, IBM-PCDie Zeichensätze s<strong>in</strong>d <strong>in</strong> <strong>de</strong>n E<strong>in</strong>- und Ausgabegeräten (Term<strong>in</strong>al,Drucker) gespeicherte Tabellen, die die Zeichen <strong>in</strong> Zahlenund zurück umsetzen.<strong>de</strong>zimal oktal EBCDIC ASCII-7 Roman8 IBM-PC0 0 nul nul nul nul1 1 soh soh soh Grafik2 2 stx stx stx Grafik3 3 etx etx etx Grafik4 4 pf eot eot Grafik5 5 ht enq enq Grafik6 6 lc ack ack Grafik7 7 <strong>de</strong>l bel bel bel8 10 bs bs Grafik9 11 rlf ht ht ht10 12 smm lf lf lf11 13 vt vt vt home12 14 ff ff ff ff13 15 cr cr cr cr14 16 so so so Grafik15 17 si si si Grafik16 20 dle dle dle Grafik17 21 dc1 dc1 dc1 Grafik18 22 dc2 dc2 dc2 Grafik19 23 dc3 dc3 dc3 Grafik20 24 res dc4 dc4 Grafik21 25 nl nak nak Grafik22 26 bs syn syn Grafik23 27 il etb etb Grafik24 30 can can can Grafik25 31 em em em Grafik26 32 cc sub sub Grafik298


B.1. EBCDIC, ASCII, ROMAN8, IBM-PC 29927 33 esc esc Grafik28 34 ifs fs fs cur right29 35 igs gs gs cur left30 36 irs rs rs cur up31 37 ius us us cur down32 40 ds space space space33 41 sos ! ! !34 42 fs ” ” ”35 43 # # #36 44 byp $ $ $37 45 lf % % %38 46 etb & & &39 47 esc ’ ’ ’40 50 ( ( (41 51 ) ) )42 52 sm * * *43 53 + + +44 54 , , ,45 55 enq - - -46 56 ack . . .47 57 bel / / /48 60 0 0 049 61 1 1 150 62 syn 2 2 251 63 3 3 352 64 pn 4 4 453 65 rs 5 5 554 66 uc 6 6 655 67 eot 7 7 756 70 8 8 857 71 9 9 958 72 : : :59 73 ; ; ;60 74 dc4 < < > >63 77 sub ? ? ?64 100 space @ @ @65 101 A A A66 102 â B B B


300 ANHANG B. ZEICHENSÄTZE67 103 ä C C C68 104 à D D D69 105 á E E E70 106 ã F F F71 107 å G G G72 110 ç H H H73 111 ñ I I I74 112 [ J J J75 113 . K K K76 114 < L L L77 115 ( M M M78 116 + N N N79 117 ! O O O80 120 & P P P81 121 é Q Q Q82 122 ê R R R83 123 ë S S S84 124 è T T T85 125 í U U U86 126 î V V V87 127 ï W W W88 130 ì X X X89 131 ß Y Y Y90 132 ] Z Z Z91 133 $ [ [ [92 134 * \ \ \93 135 ) ] ] ]94 136 ; ^ ^ ^95 137 ^ _ _ _96 140 – ‘ ‘ ‘97 141 / a a a98 142 Â b b b99 143 Ä c c c100 144 À d d d101 145 Á e e e102 146 Ã f f f103 147 Å g g g104 150 Ç h h h105 151 Ñ i i i


B.1. EBCDIC, ASCII, ROMAN8, IBM-PC 301106 152 | j j j107 153 , k k k108 154 % l l l109 155 _ m m m110 156 > n n n111 157 ? o o o112 160 ø p p p113 161 É q q q114 162 Ê r r r115 163 Ë s s s116 164 È t t t117 165 Í u u u118 166 Î v v v119 167 Ï w w w120 170 Ì x x x121 171 ‘ y y y122 172 : z z z123 173 # { { {124 174 @ | | |125 175 ’ } } }126 176 = ~ ~ ~127 177 ” <strong>de</strong>l <strong>de</strong>l Grafik128 200 Ø Ç129 201 a ü130 202 b é131 203 c â132 204 d ä133 205 e à134 206 f å135 207 g ç136 210 h ê137 211 i ë138 212 ≪ è139 213 ≫ ı140 214 î141 215 ý ì142 216 Ä143 217 ± Å144 220 É


302 ANHANG B. ZEICHENSÄTZE145 221 j œ146 222 k Æ147 223 l ô148 224 m ö149 225 n ò150 226 o û151 227 p ù152 230 q y153 231 r Ö154 232 ā Ü155 233 ō156 234 æ £157 235 – Yen158 236 Æ Pt159 237 f160 240 µ á161 241 ∼ À í162 242 s  ó163 243 t È ú164 244 u Ê ñ165 245 v Ë Ñ166 246 w Î ā167 247 x Ï ō168 250 y ’ ¿169 251 z ‘ Grafik170 252 ¡ ^ Grafik171 253 ¿ 1/2172 254 ~ 1/4173 255 Ý Ù ¡174 256 Û ≪175 257 ≫176 260 Grafik177 261 £ Grafik178 262 Yen Grafik179 263 ◦ Grafik180 264 f Ç Grafik181 265 § ç Grafik182 266 Ñ Grafik183 267 ñ Grafik


B.1. EBCDIC, ASCII, ROMAN8, IBM-PC 303184 270 ¡ Grafik185 271 ¿ Grafik186 272 Grafik187 273 | £ Grafik188 274 – Yen Grafik189 275 § Grafik190 276 f Grafik191 277 = Grafik192 300 { â Grafik193 301 A ê Grafik194 302 B ô Grafik195 303 C û Grafik196 304 D á Grafik197 305 E é Grafik198 306 F ó Grafik199 307 G ú Grafik200 310 H à Grafik201 311 I è Grafik202 312 ò Grafik203 313 ô ù Grafik204 314 ö ä Grafik205 315 ò ë Grafik206 316 ó ö Grafik207 317 õ ü Grafik208 320 } Å Grafik209 321 J î Grafik210 322 K Ø Grafik211 323 L Æ Grafik212 324 M å Grafik213 325 N í Grafik214 326 O ø Grafik215 327 P æ Grafik216 330 Q Ä Grafik217 331 R ì Grafik218 332 Ö Grafik219 333 û Ü Grafik220 334 ü É Grafik221 335 ù ı Grafik222 336 ú ß Grafik


304 ANHANG B. ZEICHENSÄTZE223 337 y Ô Grafik224 340 \ Á α225 341 Ã β226 342 S ã Γ227 343 T π228 344 U Σ229 345 V Í σ230 346 W Ì µ231 347 X Ó τ232 350 Y Ò Φ233 351 Z Õ θ234 352 õ Ω235 353 Ô Š δ236 354 Ö š ∞237 355 Ò Ú Ø238 356 Ó Y ∈239 357 Õ y ∩240 360 0 thorn ≡241 361 1 Thorn ±242 362 2 ≥243 363 3 ≤244 364 4 Haken245 365 5 Haken246 366 6 – ÷247 367 7 1/4 ≈248 370 8 1/2 ◦249 371 9 ā •250 372 ō ·√251 373 Û ≪252 374 Ü ⊔ n253 375 Ù ≫ 2254 376 Ú ± ⊔255 377 (FF)


B.2. GERMAN-ASCII 305B.2 German-ASCIIFalls das E<strong>in</strong>- o<strong>de</strong>r Ausgabegerät e<strong>in</strong>en <strong>de</strong>utschen 7-Bit-ASCII-Zeichensatz enthält, s<strong>in</strong>d folgen<strong>de</strong> Ersetzungen <strong>de</strong>r amerikanischenZeichen durch <strong>de</strong>utsche Son<strong>de</strong>rzeichen üblich:Nr. US-Zeichen US-ASCII German ASCII91 l<strong>in</strong>ke eckige Klammer [ Ä92 Backslash \ Ö93 rechte eckige Klammer ] Ü123 l<strong>in</strong>ke geschweifte Klammer { ä124 senkrechter Strich | ö125 rechte geschweifte Klammer } ü126 Til<strong>de</strong> ~ ßAchtung: Der IBM-PC und Ausgabegeräte von Hewlett-Packardverwen<strong>de</strong>n ke<strong>in</strong>en 7-Bit-ASCII-Zeichensatz, son<strong>de</strong>rn eigene 8-Bit-Zeichensätze, die die Son<strong>de</strong>rzeichen unter Nummern höher127 enthalten, siehe vorhergehen<strong>de</strong> Tabelle.B.3 ASCII-SteuerzeichenDie Steuerzeichen <strong>de</strong>r Zeichensätze dienen <strong>de</strong>r Übermittlungvon Befehlen und Informationen an das empfangen<strong>de</strong> Gerät undnicht <strong>de</strong>r Ausgabe e<strong>in</strong>es sicht- o<strong>de</strong>r druckbaren Zeichens. DieAusgabegeräte kennen <strong>in</strong> <strong>de</strong>r Regel jedoch e<strong>in</strong>en Modus (transparent,Monitor, Display Functions), <strong>in</strong> <strong>de</strong>r die Steuerzeichennicht ausgeführt, son<strong>de</strong>rn angezeigt wer<strong>de</strong>n. Die meisten Steuerzeichenbelegen ke<strong>in</strong>e eigene Taste auf <strong>de</strong>r Tastatur, son<strong>de</strong>rnwer<strong>de</strong>n als Komb<strong>in</strong>ation aus <strong>de</strong>r control-Taste und e<strong>in</strong>er Zeichentastee<strong>in</strong>gegeben. In C/<strong>C++</strong> läßt sich je<strong>de</strong>s Zeichen durchse<strong>in</strong>e oktale Nummer <strong>in</strong> <strong>de</strong>r Form \123 o<strong>de</strong>r durch se<strong>in</strong>e hexa<strong>de</strong>zimaleNummer <strong>in</strong> <strong>de</strong>r Form \x53 e<strong>in</strong>geben (hier das S).<strong>de</strong>zimal C-Konst. ASCII Be<strong>de</strong>utung Tasten0 \x00 nul ASCII-Null control @1 soh Start of head<strong>in</strong>g control a2 stx Start of text control b


306 ANHANG B. ZEICHENSÄTZE3 etx End of text control c4 eot End of transmission control d5 enq Enquiry control e6 ack Acknowledge control f7 \a bel Bell control g8 \b bs Backspace control h, BS9 \t ht Horizontal tab control i, TAB10 \n lf L<strong>in</strong>e feed control j, LF11 \v vt Vertical tab control k12 \f ff Form feed control l13 \r cr Carriage return control m, RETURN14 so Shift out control n15 si Shift <strong>in</strong> control o16 dle Data l<strong>in</strong>k escape control p17 dc1 Device control 1, xon control q18 dc2 Device control 2, tape control r19 dc3 Device control 3, xoff control s20 dc4 Device control 4, tape control t21 nak Negative acknowledge control u22 syn Synchronous idle control v23 etb End transmission block control w24 can Cancel control x25 em End of medium control y26 sub Substitute control z27 \x1b esc Escape control [, ESC28 fs File separator control \29 gs Group separator control ]30 rs Record separator control ^31 us Unit separator control _127 <strong>de</strong>l Delete DEL, RUBOUTB.4 Lat<strong>in</strong>-1 (ISO 8859-1)Die <strong>in</strong>ternationale Norm ISO 8859 beschreibt gegenwärtigzehn Zeichensätze, die je<strong>de</strong>s Zeichen durch jeweils e<strong>in</strong> Bytedarstellen. Je<strong>de</strong>r Zeichensatz umfaßt also maximal 256 druckbareZeichen und Steuerzeichen. Der erste – Lat<strong>in</strong>-1 genannt– ist für west- und mitteleuropäische Sprachen – darunterDeutsch – vorgesehen. Lat<strong>in</strong>-2 <strong>de</strong>ckt Mittel- und Osteuropa


B.4. LATIN-1 (ISO 8859-1) 307ab, soweit das late<strong>in</strong>ische Alphabet verwen<strong>de</strong>t wird. Wer e<strong>in</strong>enpolnisch-<strong>de</strong>utschen Text schreiben will, braucht Lat<strong>in</strong> 2. Die<strong>de</strong>utschen Son<strong>de</strong>rzeichen liegen <strong>in</strong> Lat<strong>in</strong> 1 bis 6 an <strong>de</strong>nselbenStellen. Weiteres siehe <strong>in</strong> <strong>de</strong>r ISO-Norm und im RFC 1345Character Mnemonics and Character Sets vom Juni 1992. Auchhttp://wwwwbs.cs.tu-berl<strong>in</strong>.<strong>de</strong>/~czyborra/charsets/hilft weiter.Die erste Hälfte (0 – 127) aller Lat<strong>in</strong>-Zeichensätze stimmt mitUS-ASCII übere<strong>in</strong>, die zweite mit ke<strong>in</strong>em <strong>de</strong>r an<strong>de</strong>ren Zeichensätze.Zu je<strong>de</strong>m Zeichen gehört e<strong>in</strong>e standardisierte verbale Bezeichnung.E<strong>in</strong>ige Zeichen wie das isländische Thorn o<strong>de</strong>r dasCent-Zeichen konnten hier mit LaTeX nicht dargestellt wer<strong>de</strong>n.<strong>de</strong>zimal oktal hex Zeichen Bezeichnung000 000 00 nu Null (nul)001 001 01 sh Start of head<strong>in</strong>g (soh)002 002 02 sx Start of text (stx)003 003 03 ex End of text (etx)004 004 04 et End of transmission (eot)005 005 05 eq Enquiry (enq)006 006 06 ak Acknowledge (ack)007 007 07 bl Bell (bel)008 010 08 bs Backspace (bs)009 011 09 ht Character tabulation (ht)010 012 0a lf L<strong>in</strong>e feed (lf)011 013 0b vt L<strong>in</strong>e tabulation (vt)012 014 0c ff Form feed (ff)013 015 0d cr Carriage return (cr)014 016 0e so Shift out (so)015 017 0f si Shift <strong>in</strong> (si)016 020 10 dl Datal<strong>in</strong>k escape (dle)017 021 11 d1 Device control one (dc1)018 022 12 d2 Device control two (dc2)019 023 13 d3 Device control three (dc3)020 024 14 d4 Device control four (dc4)021 025 15 nk Negative acknowledge (nak)022 026 16 sy Synchronous idle (syn)023 027 17 eb End of transmission block (etb)024 030 18 cn Cancel (can)


308 ANHANG B. ZEICHENSÄTZE025 031 19 em End of medium (em)026 032 1a sb Substitute (sub)027 033 1b ec Escape (esc)028 034 1c fs File separator (is4)029 035 1d gs Group separator (is3)030 036 1e rs Record separator (is2)031 037 1f us Unit separator (is1)032 040 20 sp Space033 041 21 ! Exclamation mark034 042 22 ” Quotation mark035 043 23 # Number sign036 044 24 $ Dollar sign037 045 25 % Percent sign038 046 26 & Ampersand039 047 27 ’ Apostrophe040 050 28 ( Left parenthesis041 051 29 ) Right parenthesis042 052 2a * Asterisk043 053 2b + Plus sign044 054 2c , Comma045 055 2d - Hyphen-M<strong>in</strong>us046 056 2e . Full stop047 057 2f / Solidus048 060 30 0 Digit zero049 061 31 1 Digit one050 062 32 2 Digit two051 063 33 3 Digit three052 064 34 4 Digit four053 065 35 5 Digit five054 066 36 6 Digit six055 067 37 7 Digit seven056 070 38 8 Digit eight057 071 39 9 Digit n<strong>in</strong>e058 072 3a : Colon059 073 3b ; Semicolon060 074 3c < Less-than sign061 075 3d = Equals sign062 076 3e > Greater-than sign063 077 3f ? Question mark064 100 40 @ Commercial at


B.4. LATIN-1 (ISO 8859-1) 309065 101 41 A Lat<strong>in</strong> capital letter a066 102 42 B Lat<strong>in</strong> capital letter b067 103 43 C Lat<strong>in</strong> capital letter c068 104 44 D Lat<strong>in</strong> capital letter d069 105 45 E Lat<strong>in</strong> capital letter e070 106 46 F Lat<strong>in</strong> capital letter f071 107 47 G Lat<strong>in</strong> capital letter g072 110 48 H Lat<strong>in</strong> capital letter h073 111 49 I Lat<strong>in</strong> capital letter i074 112 4a J Lat<strong>in</strong> capital letter j075 113 4b K Lat<strong>in</strong> capital letter k076 114 4c L Lat<strong>in</strong> capital letter l077 115 4d M Lat<strong>in</strong> capital letter m078 116 4e N Lat<strong>in</strong> capital letter n079 117 4f O Lat<strong>in</strong> capital letter o080 120 50 P Lat<strong>in</strong> capital letter p081 121 51 Q Lat<strong>in</strong> capital letter q082 122 52 R Lat<strong>in</strong> capital letter r083 123 53 S Lat<strong>in</strong> capital letter s084 124 54 T Lat<strong>in</strong> capital letter t085 125 55 U Lat<strong>in</strong> capital letter u086 126 56 V Lat<strong>in</strong> capital letter v087 127 57 W Lat<strong>in</strong> capital letter w088 130 58 X Lat<strong>in</strong> capital letter x089 131 59 Y Lat<strong>in</strong> capital letter y090 132 5a Z Lat<strong>in</strong> capital letter z091 133 5b [ Left square bracket092 134 5c \ Reverse solidus093 135 5d ] Right square bracket094 136 5e ^ Circumflex accent095 137 5f _ Low l<strong>in</strong>e096 140 60 ‘ Grave accent097 141 61 a Lat<strong>in</strong> small letter a098 142 62 b Lat<strong>in</strong> small letter b099 143 63 c Lat<strong>in</strong> small letter c100 144 64 d Lat<strong>in</strong> small letter d101 145 65 e Lat<strong>in</strong> small letter e102 146 66 f Lat<strong>in</strong> small letter f103 147 67 g Lat<strong>in</strong> small letter g104 150 68 h Lat<strong>in</strong> small letter h


310 ANHANG B. ZEICHENSÄTZE105 151 69 i Lat<strong>in</strong> small letter i106 152 6a j Lat<strong>in</strong> small letter j107 153 6b k Lat<strong>in</strong> small letter k108 154 6c l Lat<strong>in</strong> small letter l109 155 6d m Lat<strong>in</strong> small letter m110 156 6e n Lat<strong>in</strong> small letter n111 157 6f o Lat<strong>in</strong> small letter o112 160 70 p Lat<strong>in</strong> small letter p113 161 71 q Lat<strong>in</strong> small letter q114 162 72 r Lat<strong>in</strong> small letter r115 163 73 s Lat<strong>in</strong> small letter s116 164 74 t Lat<strong>in</strong> small letter t117 165 75 u Lat<strong>in</strong> small letter u118 166 76 v Lat<strong>in</strong> small letter v119 167 77 w Lat<strong>in</strong> small letter w120 170 78 x Lat<strong>in</strong> small letter x121 171 79 y Lat<strong>in</strong> small letter y122 172 7a z Lat<strong>in</strong> small letter z123 173 7b { Left curly bracket124 174 7c | Vertical l<strong>in</strong>e125 175 7d } Right curly bracket126 176 7e ~ Til<strong>de</strong>127 177 7f dt Delete (<strong>de</strong>l)128 200 80 pa Padd<strong>in</strong>g character (pad)129 201 81 ho High octet preset (hop)130 202 82 bh Break permitted here (bph)131 203 83 nh No break here (nbh)132 204 84 <strong>in</strong> In<strong>de</strong>x (<strong>in</strong>d)133 205 85 nl Next l<strong>in</strong>e (nel)134 206 86 sa Start of selected area (ssa)135 207 87 es End of selected area (esa)136 210 88 hs Character tabulation set (hts)137 211 89 hj Character tabulation with justification (htj)138 212 8a vs L<strong>in</strong>e tabulation set (vts)139 213 8b pd Partial l<strong>in</strong>e forward (pld)140 214 8c pu Partial l<strong>in</strong>e backward (plu)141 215 8d ri Reverse l<strong>in</strong>e feed (ri)142 216 8e s2 S<strong>in</strong>gle-shift two (ss2)143 217 8f s3 S<strong>in</strong>gle-shift three (ss3)144 220 90 dc Device control str<strong>in</strong>g (dcs)


B.4. LATIN-1 (ISO 8859-1) 311145 221 91 p1 Private use one (pu1)146 222 92 p2 Private use two (pu2)147 223 93 ts Set transmit state (sts)148 224 94 cc Cancel character (cch)149 225 95 mw Message wait<strong>in</strong>g (mw)150 226 96 sg Start of guar<strong>de</strong>d area (spa)151 227 97 eg End of guar<strong>de</strong>d area (epa)152 230 98 ss Start of str<strong>in</strong>g (sos)153 231 99 gc S<strong>in</strong>gle graphic character <strong>in</strong>troducer (sgci)154 232 9a sc S<strong>in</strong>gle character <strong>in</strong>troducer (sci)155 233 9b ci Control sequence <strong>in</strong>troducer (csi)156 234 9c st Str<strong>in</strong>g term<strong>in</strong>ator (st)157 235 9d oc Operat<strong>in</strong>g system command (osc)158 236 9e pm Privacy message (pm)159 237 9f ac Application program command (apc)160 240 a0 ns No-break space161 241 a1 ¡ Inverted exclamation mark162 242 a2 Cent sign163 243 a3 £ Pound sign164 244 a4 Currency sign (künftig Euro?)165 245 a5 Yen sign166 246 a6 Broken bar167 247 a7 § Section sign168 250 a8 Diaresis169 251 a9 © Copyright sign170 252 aaaFem<strong>in</strong><strong>in</strong>e ord<strong>in</strong>al <strong>in</strong>dicator171 253 ab ≪ Left-po<strong>in</strong>t<strong>in</strong>g double angle quotation mark172 254 ac ¬ Not sign173 255 ad - Soft hyphen174 256 ae Registered sign175 257 af ¯ Overl<strong>in</strong>e176 260 b0◦Degree sign177 261 b1 ± Plus-m<strong>in</strong>us sign178 262 b22Superscript two179 263 b33Superscript three180 264 b4 ’ Acute accent181 265 b5 µ Micro sign182 266 b6 Pilcrow sign183 267 b7 · Middle dot184 270 b8 ¸ Cedilla


312 ANHANG B. ZEICHENSÄTZE185 271 b91Superscript one186 272 ba◦Mascul<strong>in</strong>e ord<strong>in</strong>al <strong>in</strong>dicator187 273 bb ≫ Right-po<strong>in</strong>t<strong>in</strong>g double angle quotation mark188 274 bc 1/4 Vulgar fraction one quarter189 275 bd 1/2 Vulgar fraction one half190 276 be 3/4 Vulgar fraction three quarters191 277 bf ¿ Inverted question mark192 300 c0 À Lat<strong>in</strong> capital letter a with grave193 301 c1 Á Lat<strong>in</strong> capital letter a with acute194 302 c2 Â Lat<strong>in</strong> capital letter a with circumflex195 303 c3 Ã Lat<strong>in</strong> capital letter a with til<strong>de</strong>196 304 c4 Ä Lat<strong>in</strong> capital letter a with diaresis197 305 c5 Å Lat<strong>in</strong> capital letter a with r<strong>in</strong>g above198 306 c6 Æ Lat<strong>in</strong> capital letter ae199 307 c7 Ç Lat<strong>in</strong> capital letter c with cedilla200 310 c8 È Lat<strong>in</strong> capital letter e with grave201 311 c9 É Lat<strong>in</strong> capital letter e with acute202 312 ca Ê Lat<strong>in</strong> capital letter e with circumflex203 313 cb Ë Lat<strong>in</strong> capital letter e with diaresis204 314 cc Ì Lat<strong>in</strong> capital letter i with grave205 315 cd Í Lat<strong>in</strong> capital letter i with acute206 316 ce Î Lat<strong>in</strong> capital letter i with circumflex207 317 cf Ï Lat<strong>in</strong> capital letter i with diaresis208 320 d0 Lat<strong>in</strong> capital letter eth (Icelandic)209 321 d1 Ñ Lat<strong>in</strong> capital letter n with til<strong>de</strong>210 322 d2 Ò Lat<strong>in</strong> capital letter o with grave211 323 d3 Ó Lat<strong>in</strong> capital letter o with acute212 324 d4 Ô Lat<strong>in</strong> capital letter o with circumflex213 325 d5 Õ Lat<strong>in</strong> capital letter o with til<strong>de</strong>214 326 d6 Ö Lat<strong>in</strong> capital letter o with diaresis215 327 d7 × Multiplication sign216 330 d8 Ø Lat<strong>in</strong> capital letter o with stroke217 331 d9 Ù Lat<strong>in</strong> capital letter u with grave218 332 da Ú Lat<strong>in</strong> capital letter u with acute219 333 db Û Lat<strong>in</strong> capital letter u with circumflex220 334 dc Ü Lat<strong>in</strong> capital letter u with diaresis221 335 dd Ý Lat<strong>in</strong> capital letter y with acute222 336 <strong>de</strong> Lat<strong>in</strong> capital letter thorn (Icelandic)


B.4. LATIN-1 (ISO 8859-1) 313223 337 df ß Lat<strong>in</strong> small letter sharp s (German)224 340 e0 à Lat<strong>in</strong> small letter a with grave225 341 e1 á Lat<strong>in</strong> small letter a with acute226 342 e2 â Lat<strong>in</strong> small letter a with circumflex227 343 e3 ã Lat<strong>in</strong> small letter a with til<strong>de</strong>228 344 e4 ä Lat<strong>in</strong> small letter a with diaresis229 345 e5 å Lat<strong>in</strong> small letter a with r<strong>in</strong>g above230 346 e6 æ Lat<strong>in</strong> small letter ae231 347 e7 ç Lat<strong>in</strong> small letter c with cedilla232 350 e8 è Lat<strong>in</strong> small letter e with grave233 351 e9 é Lat<strong>in</strong> small letter e with acute234 352 ea ê Lat<strong>in</strong> small letter e with circumflex235 353 eb ë Lat<strong>in</strong> small letter e with diaresis236 354 ec ì Lat<strong>in</strong> small letter i with grave237 355 ed í Lat<strong>in</strong> small letter i with acute238 356 ee î Lat<strong>in</strong> small letter i with circumflex239 357 ef ï Lat<strong>in</strong> small letter i with diaresis240 360 f0 Lat<strong>in</strong> small letter eth (Icelandic)241 361 f1 ñ Lat<strong>in</strong> small letter n with til<strong>de</strong>242 362 f2 ò Lat<strong>in</strong> small letter o with grave243 363 f3 ó Lat<strong>in</strong> small letter o with acute244 364 f4 ô Lat<strong>in</strong> small letter o with circumflex245 365 f5 õ Lat<strong>in</strong> small letter o with til<strong>de</strong>246 366 f6 ö Lat<strong>in</strong> small letter o with diaresis247 367 f7 ÷ Division sign248 370 f8 ø Lat<strong>in</strong> small letter o with stroke249 371 f9 ù Lat<strong>in</strong> small letter u with grave250 372 fa ú Lat<strong>in</strong> small letter u with acute251 373 fb û Lat<strong>in</strong> small letter u with circumflex252 374 fc ü Lat<strong>in</strong> small letter u with diaresis253 375 fd ý Lat<strong>in</strong> small letter y with acute254 376 fe Lat<strong>in</strong> small letter thorn (Icelandic)255 377 ff ÿ Lat<strong>in</strong> small letter y with diaresis


CUNIX-SystemaufrufeSystemaufrufe wer<strong>de</strong>n vom Anwendungsprogramm wie eigeneo<strong>de</strong>r frem<strong>de</strong> Funktionen angesehen. Ihrem Ursprung nach s<strong>in</strong><strong>de</strong>s auch C-Funktionen. Sie s<strong>in</strong>d jedoch nicht Bestandteil e<strong>in</strong>erFunktionsbibliothek, son<strong>de</strong>rn gehören zum Betriebssystem unds<strong>in</strong>d nicht durch an<strong>de</strong>re Funktionen erweiterbar.Die Systemaufrufe – als Bestandteil <strong>de</strong>s Betriebssystems– s<strong>in</strong>d für alle Programmiersprachen dieselben, während dieFunktionsbibliotheken zur jeweiligen Programmiersprache gehören.Folgen<strong>de</strong> Systemaufrufe s<strong>in</strong>d unter UNIX verfügbar:access prüft Zugriff auf Fileacct startet und stoppt Prozess Account<strong>in</strong>galarm setzt Weckeruhr für Prozessatexit Funktion für Programmen<strong>de</strong>brkän<strong>de</strong>rt Speicherzuweisungchdir wechselt Arbeitsverzeichnischmod än<strong>de</strong>rt Zugriffsrechte e<strong>in</strong>es Fileschown än<strong>de</strong>rt Besitzer e<strong>in</strong>es Fileschroot än<strong>de</strong>rt Root-Verzeichnisclose schließt e<strong>in</strong>en File-Deskriptorcreat öffnet File, ordnet Deskriptor zudupdupliziert File-Deskriptorerrno Fehlervariable <strong>de</strong>r Systemaufrufeexec führt e<strong>in</strong> Programm ausexit been<strong>de</strong>t e<strong>in</strong>en Prozessfcntl Filesteuerungfork erzeugt e<strong>in</strong>en neuen Prozessfsctl liest Information aus File-Systemfsync schreibt File aus Arbeitsspeicher auf Plattegetaccess ermittelt Zugriffsrechtegetacl ermittelt Zugriffsrechtegetcontext ermittelt Kontext e<strong>in</strong>es Prozessesgetdirentries ermittelt Verzeichnis-E<strong>in</strong>trägegetgroups ermittelt Gruppenrechte e<strong>in</strong>es Prozessesgethostname ermittelt Namen <strong>de</strong>s Systems314


315getitimer setzt o<strong>de</strong>r liest Intervall-Uhrgetpid liest Prozess-IDgettimeofdayermittelt Zeitgetuid liest User-ID <strong>de</strong>s aufrufen<strong>de</strong>n Prozessesioctl I/O-Steuerungkill schickt Signal an e<strong>in</strong>en Prozessl<strong>in</strong>k l<strong>in</strong>kt e<strong>in</strong> Filelockf setzt Semaphore und Record-Sperrenlseek bewegt Schreiblesezeiger <strong>in</strong> e<strong>in</strong>em Filemkdir erzeugt Verzeichnismknod erzeugt Filemount hängt File-System <strong>in</strong> File-Hierarchie e<strong>in</strong>msgctl Interprozess-Kommunikationnice än<strong>de</strong>rt die Priorität e<strong>in</strong>es Prozessesopen öffnet File zum Lesen o<strong>de</strong>r Schreibenpause suspendiert Prozess bis zum Empfang e<strong>in</strong>es Signalspipe erzeugt e<strong>in</strong>e Pipeprealloc reserviert Arbeitsspeicherprofil ermittelt Zeiten bei <strong>de</strong>r Ausführung e<strong>in</strong>es Programmesread liest aus e<strong>in</strong>em Filereadl<strong>in</strong>k liest symbolisches L<strong>in</strong>krename än<strong>de</strong>rt Filenamenrmdir löscht Verzeichnisrtprio än<strong>de</strong>rt Echtzeit-Prioritätsemctl Semaphoresetgrp setzt Gruppen-Zugriffsrechte e<strong>in</strong>es Prozessessetuid setzt User-ID e<strong>in</strong>es Prozessessignal legt fest, was auf e<strong>in</strong> Signal h<strong>in</strong> zu tun iststat liest die Ino<strong>de</strong> e<strong>in</strong>es Filesstatfs liest Werte <strong>de</strong>s File-Systemssyml<strong>in</strong>k erzeugt symbolischen L<strong>in</strong>ksync schreibt Puffer auf Platteszsconf ermittelt Systemwertetime ermittelt die Systemzeittimes ermittelt Zeitverbrauch e<strong>in</strong>es Prozessestruncate schnei<strong>de</strong>t File abumask setzt o<strong>de</strong>r ermittelt Filezugriffsmaskeumount entfernt Filesystem aus File-Hierarchieunl<strong>in</strong>k löscht Fileustat liest Werte <strong>de</strong>s File-Systems


316 ANHANG C. UNIX-SYSTEMAUFRUFEutimewaitwritesetzt Zeitstempel e<strong>in</strong>es Fileswartet auf En<strong>de</strong> e<strong>in</strong>es K<strong>in</strong>dprozessesschreibt <strong>in</strong> e<strong>in</strong> FileDie Aufzählung kann durch weitere Systemaufrufe <strong>de</strong>s jeweiligenLieferanten <strong>de</strong>s Betriebssystems (z. B. Hewlett-Packard)ergänzt wer<strong>de</strong>n. Diese erleichtern das Programmieren, verschlechternaber die Portabilität. Zu <strong>de</strong>n meisten Systemaufrufenmit get... gibt es e<strong>in</strong> Gegenstück set..., das <strong>in</strong> e<strong>in</strong>igenFällen <strong>de</strong>m Superuser vorbehalten ist.


DC-LexikonD.1 SchlüsselwörterIn C/<strong>C++</strong> dürfen Schlüsselwörter ke<strong>in</strong>esfalls als Namen verwen<strong>de</strong>twer<strong>de</strong>n. Laut ANSI verwen<strong>de</strong>t C folgen<strong>de</strong> Schlüsselwörter(Wortsymbole, keywords):• Deklaratoren– auto, Default-Speicherklasse (kann weggelassen wer<strong>de</strong>n)– char, Zeichentyp– const, Typattribut (neu <strong>in</strong> ANSI-C)– double, Typ Gleitkommazahl doppelter Genauigkeit– enum, Aufzählungstyp– extern, Speicherklasse– float, Typ Gleitkommazahl e<strong>in</strong>facher Genauigkeit– <strong>in</strong>t, Typ Ganzzahl e<strong>in</strong>facher Länge– long, Typ Ganzzahl doppelter Länge– register, Speicherklasse Registervariable– short, Typ Ganzzahl halber Länge– signed, Typzusatz zu Ganzzahl o<strong>de</strong>r Zeichen– static, Speicherklasse– struct, Strukturtyp– type<strong>de</strong>f, Def<strong>in</strong>ition e<strong>in</strong>es benutzereigenen Typs– union, Typ Union– unsigned, Typzusatz zu Ganzzahl o<strong>de</strong>r Zeichen– void, leerer Typ– volatile, Typattribut (neu <strong>in</strong> ANSI-C)• Schleifen und Bed<strong>in</strong>gungen (Kontrollanweisungen)317


318 ANHANG D. C-LEXIKON– break, Verlassen e<strong>in</strong>er Schleife– case, Fall e<strong>in</strong>er Auswahl (switch)– cont<strong>in</strong>ue, Rücksprung vor e<strong>in</strong>e Schleife– <strong>de</strong>fault, Default-Fall e<strong>in</strong>er Auswahl (switch)– do, Beg<strong>in</strong>n e<strong>in</strong>er do-Schleife– else, Alternative e<strong>in</strong>er Verzweigung– for, Beg<strong>in</strong>n e<strong>in</strong>er for-Schleife– goto, unbed<strong>in</strong>gter Sprung– if, Bed<strong>in</strong>gung o<strong>de</strong>r Beg<strong>in</strong>n e<strong>in</strong>er Verzweigung– switch, Beg<strong>in</strong>n e<strong>in</strong>er Auswahl– while, Beg<strong>in</strong>n e<strong>in</strong>er while-Schleife• Sonstige– return, Rücksprung <strong>in</strong> die aufrufen<strong>de</strong> E<strong>in</strong>heit– sizeof, Bytebedarf e<strong>in</strong>es Typs o<strong>de</strong>r e<strong>in</strong>er VariablenIn <strong>C++</strong> kommen laut BJARNE STROUSTRUP h<strong>in</strong>zu:• catch, Ausnahmebehandlung• class, Klassen<strong>de</strong>klaration• <strong>de</strong>lete, Löschen e<strong>in</strong>es Objektes• friend, Deklaration e<strong>in</strong>er Funktion• <strong>in</strong>l<strong>in</strong>e, <strong>in</strong>l<strong>in</strong>e-Funktion• new, Erzeugen e<strong>in</strong>es Objektes• operator, Überla<strong>de</strong>n von Operatoren• private, Deklaration von Klassenmitglie<strong>de</strong>rn• protected, Deklaration von Klassenmitglie<strong>de</strong>rn• public, Deklaration von Klassenmitglie<strong>de</strong>rn• template, Deklaration e<strong>in</strong>es Templates (Klasse)• this, Po<strong>in</strong>ter auf Objekt• throw, Ausnahmebehandlung• try, Ausnahmebehandlung• virtual, Deklaration


D.1. SCHLÜSSELWÖRTER 319Darüber h<strong>in</strong>aus verwen<strong>de</strong>n e<strong>in</strong>ige Compiler weitere Schlüsselwörter:• asm, Assembler-Aufruf <strong>in</strong>nerhalb e<strong>in</strong>er C- o<strong>de</strong>r <strong>C++</strong>-Quelle• bool, logischer o<strong>de</strong>r boolescher Typ• c<strong>de</strong>cl, Aufruf e<strong>in</strong>er Funktion nach C-Konventionen• const_cast, cast-Operator für const-Werte• dynamic_cast, cast-Operator• entry, (war <strong>in</strong> K&R-C für künftigen Gebrauch vorgesehen)• explicit, Konstruktor-Vere<strong>in</strong>barung• export, Vere<strong>in</strong>barung bei Klassen-Templates• false, boolesche Konstante• far, Typzusatz unter MS-DOS• fortran, Aufruf e<strong>in</strong>er Funktion nach FORTRAN-Konventionen• huge, Typzusatz unter MS-DOS• mutable, Typattribut• namespace, Vere<strong>in</strong>barung <strong>de</strong>s Geltungsbereiches von Namen• near, Typzusatz unter MS-DOS• pascal, Aufruf e<strong>in</strong>er Funktion nach PASCAL-Konventionen• re<strong>in</strong>terpret_cast, cast-Operator• static_cast, cast-Operator• true, boolesche Konstante• typeid, Operator zum Ermitteln <strong>de</strong>s Typs• typename, Alternative zum Schlüsselwort class• us<strong>in</strong>g, Deklaration <strong>in</strong> Verb<strong>in</strong>dung mit namespace• wchar_t, Typ (wi<strong>de</strong> character literal)


320 ANHANG D. C-LEXIKOND.2 OperatorenDie Operatoren von C/<strong>C++</strong> s<strong>in</strong>d im folgen<strong>de</strong>n ihrem Vorrangnach geordnet, höchster Rang (B<strong>in</strong>dungskraft) zuoberst. AlleOperatoren e<strong>in</strong>es Abschnitts haben gleichen Rang. l bzw. r be<strong>de</strong>utetvon l<strong>in</strong>ks bzw. rechts her assoziativ. E<strong>in</strong> unärer Operatorverlangt e<strong>in</strong>en Operan<strong>de</strong>n, e<strong>in</strong> b<strong>in</strong>ärer zwei und e<strong>in</strong> ternärerdrei.Operator A - Be<strong>de</strong>utung:: r unär Bezugsrahmen, global:: l b<strong>in</strong>är Bezugsrahmen, Klasse:: l b<strong>in</strong>är Bezugsrahmen, Namensraum( ) l unär Klammerung, Funktion[ ] l unär In<strong>de</strong>x-> l b<strong>in</strong>är Auswahl. l b<strong>in</strong>är Auswahl++ r unär Postfix Inkrement-- r unär Postfix Dekrementtypeid unär Typabfrageconst_cast b<strong>in</strong>är Typumwandlungdynamic_cast b<strong>in</strong>är Typumwandlungre<strong>in</strong>terpret_cast b<strong>in</strong>är Typumwandlungstatic_cast b<strong>in</strong>är Typumwandlungsizeof r unär Größenabfrage++ r unär Präfix Inkrement-- r unär Präfix Dekrement~ r unär bitweise Negation! r unär logische Negation- r unär negatives Vorzeichen+ r unär positives Vorzeichen* r unär Dereferenzierung& r unär Referenzierung( ) r b<strong>in</strong>är cast-Operatornew r unär dynamische Speicherbelegung<strong>de</strong>lete r unär dynamische Speicherfreigabe->* l b<strong>in</strong>är Auswahl.* l b<strong>in</strong>är Auswahl* l b<strong>in</strong>är Multiplikation/ l b<strong>in</strong>är Division


D.3. STANDARDFUNKTIONEN 321% l b<strong>in</strong>är Modulus (Divisionsrest)+ l b<strong>in</strong>är Addition- l b<strong>in</strong>är Subtraktion> l b<strong>in</strong>är bitweises Shiften rechts< l b<strong>in</strong>är kle<strong>in</strong>er als l b<strong>in</strong>är größer als>= l b<strong>in</strong>är größer gleich== l b<strong>in</strong>är Gleichheit!= l b<strong>in</strong>är Ungleichheit& l b<strong>in</strong>är bitweises Und^ l b<strong>in</strong>är bitweises exklusives O<strong>de</strong>r| l b<strong>in</strong>är bitweises O<strong>de</strong>r&& l b<strong>in</strong>är logisches Und|| l b<strong>in</strong>är logisches O<strong>de</strong>r?: l ternär bed<strong>in</strong>gte Bewertung= r b<strong>in</strong>är Zuweisung+=, -=, *=, /= r b<strong>in</strong>är zusammengesetzte%=, >>=,


322 ANHANG D. C-LEXIKON– iscntrl, prüft Zeichen, ob Kontrollzeichen– isdigit, prüft Zeichen, ob Ziffer– isgraph, prüft Zeichen, ob sichtbar– islower, prüft Zeichen, ob Kle<strong>in</strong>buchstabe– ispr<strong>in</strong>t, prüft Zeichen, ob druckbar– ispunct, prüft Zeichen, ob Satzzeichen– isspace, prüft Zeichen, ob Whitespace– isupper, prüft Zeichen. ob Großbuchstabe– isxdigit, prüft Zeichen, ob hexa<strong>de</strong>zimale Ziffer– tolower, wan<strong>de</strong>lt Großbuchstaben <strong>in</strong> Kle<strong>in</strong>buchstabenum– toupper, wan<strong>de</strong>lt Kle<strong>in</strong>buchstaben <strong>in</strong> Großbuchstabenum• Datenumwandlung– atof, wan<strong>de</strong>lt Str<strong>in</strong>g <strong>in</strong> double-Wert um– atoi, wan<strong>de</strong>lt Str<strong>in</strong>g <strong>in</strong> <strong>in</strong>t-Wert um– atol, wan<strong>de</strong>lt Str<strong>in</strong>g <strong>in</strong> long-Wert um– strtod, wan<strong>de</strong>lt Str<strong>in</strong>g <strong>in</strong> double-Wert um– strtol, wan<strong>de</strong>lt Str<strong>in</strong>g <strong>in</strong> long-Wert um– strtoul, wan<strong>de</strong>lt Str<strong>in</strong>g <strong>in</strong> unsigned long-Wert um• Filebehandlung– remove, löscht File– rename, än<strong>de</strong>rt Namen e<strong>in</strong>es Files• E<strong>in</strong>- und Ausgabe– clearerr, löscht Fehlermeldung e<strong>in</strong>es Filepo<strong>in</strong>ters– fclose, schließt Filepo<strong>in</strong>ter– fflush, leert Puffer e<strong>in</strong>es Filepo<strong>in</strong>ters– fgetc, liest Zeichen von Filepo<strong>in</strong>ter– fgetpos, ermittelt Stand <strong>de</strong>s Lesezeigers– fgets, liest Str<strong>in</strong>g von Filepo<strong>in</strong>ter


D.3. STANDARDFUNKTIONEN 323– fopen, öffnet Filepo<strong>in</strong>ter– fpr<strong>in</strong>tf, schreibt formatiert nach Filepo<strong>in</strong>ter– fputc, schreibt Zeichen nach Filepo<strong>in</strong>ter– fputs, schreibt Str<strong>in</strong>g nach Filepo<strong>in</strong>ter– fread, liest Bytes von Filepo<strong>in</strong>ter– freopen, ersetzt geöffneten Filepo<strong>in</strong>ter– fscanf, liest formatiert von Filepo<strong>in</strong>ter– fseek, setzt Lesezeiger auf bestimmte Stelle– fsetpos, setzt Lesezeiger auf bestimmte Stelle– ftell, ermittelt Stellung <strong>de</strong>s Lesezeigers– fwrite, schreibt Bytes nach Filepo<strong>in</strong>ter– getc, liest Zeichen von Filepo<strong>in</strong>ter– getchar, liest Zeichen von std<strong>in</strong>– gets, liest Str<strong>in</strong>g von Filepo<strong>in</strong>ter– pr<strong>in</strong>tf, schreibt formatiert nach stdout– putc, schreibt Zeichen nach Filepo<strong>in</strong>ter– putchar, schreibt Zeichen nach stdout– puts, schreibt Str<strong>in</strong>g nach Filepo<strong>in</strong>ter– rew<strong>in</strong>d, setzt Lesezeiger auf Fileanfang– scanf, liest formatiert von std<strong>in</strong>– setbuf, ordnet e<strong>in</strong>em Filepo<strong>in</strong>ter e<strong>in</strong>en Puffer zu– setvbuf, ordnet e<strong>in</strong>em Filepo<strong>in</strong>ter e<strong>in</strong>en Puffer zu– spr<strong>in</strong>tf, schreibt formatiert <strong>in</strong> e<strong>in</strong>en Str<strong>in</strong>g– sscanf, liest formatiert aus e<strong>in</strong>em Str<strong>in</strong>g– tempnam, erzeugt e<strong>in</strong>en temporären Filenamen– tmpfile, erzeugt e<strong>in</strong> temporäres File– ungetc, schreibt letztes gelesenes Zeichen zurück– vfpr<strong>in</strong>tf, schreibt formatiert aus e<strong>in</strong>er Argumentenliste– vpr<strong>in</strong>tf, schreibt formatiert aus e<strong>in</strong>er Argumentenliste


324 ANHANG D. C-LEXIKON– vspr<strong>in</strong>tf, schreibt formatiert aus e<strong>in</strong>er Argumentenlsite• Mathematik– acos, arcus cos<strong>in</strong>us– as<strong>in</strong>, arcus s<strong>in</strong>us– atan, arcus tangens– atan2, arcus tangens, erweiterter Bereich– ceil, kle<strong>in</strong>ste Ganzzahl– cos, cos<strong>in</strong>us– cosh, cos<strong>in</strong>us hyperbolicus– exp, Exponentialfunktion– fabs, Absolutwert, Betrag– floor, größte Ganzzahl– fmod, Divisionsrest– frexp, teilt Gleitkommazahl auf– l<strong>de</strong>xp, teilt Gleitkommazahl auf– log, Logarithmus naturalis– log10, <strong>de</strong>kadischer Logarithmus– modf, teilt Gleitkommazahl auf– pow, allgeme<strong>in</strong>e Potenz– s<strong>in</strong>, s<strong>in</strong>us– s<strong>in</strong>h, s<strong>in</strong>us hyperbolicus– sqrt, positive Quadratwurzel– tan, tangens– tanh, tangens hyperbolicus• Speicherzuweisung– calloc, allokiert Speicher für Array– free, gibt allokierten Speicher frei– malloc, allokiert Speicher– realloc, än<strong>de</strong>rt Größe <strong>de</strong>s allokierten Speichers


D.3. STANDARDFUNKTIONEN 325• Prozesssteuerung– abort, erzeugt SIGABRT-Signal– atexit, Funktionsaufruf bei Programmen<strong>de</strong>– exit, Programmen<strong>de</strong>– raise, sen<strong>de</strong>t Signal– signal, legt Antwort auf Siganl fest– system, übergibt Argument an Kommando<strong>in</strong>terpreter• Suchen und Sortieren– bsearch, b<strong>in</strong>äre Suche– qsort, Quicksort• Str<strong>in</strong>gbehandlung– strcat, verkettet Str<strong>in</strong>gs– strchr, sucht Zeichen <strong>in</strong> Str<strong>in</strong>g– strcmp, vergleicht Str<strong>in</strong>gs– strcpy, kopiert Str<strong>in</strong>g– strcspn, sucht Teilstr<strong>in</strong>g– strerror, verweist auf Fehlermeldung– strlen, ermittelt Str<strong>in</strong>glänge– strncat, verkettet n Zeichen von Str<strong>in</strong>gs– strncmp, vergleicht n Zeichen von Str<strong>in</strong>gs– strncpy, kopiert n Zeichen e<strong>in</strong>es Str<strong>in</strong>gs– strpbrk, sucht Zeichen <strong>in</strong> Str<strong>in</strong>g– strrchr, sucht Zeichen <strong>in</strong> Str<strong>in</strong>g– strspn, ermittelt Länge e<strong>in</strong>es Teilstr<strong>in</strong>gs– strstr, sucht Zeichen <strong>in</strong> Str<strong>in</strong>gDies s<strong>in</strong>d alle Funktionen <strong>de</strong>s ANSI-Vorschlags. Die meistenCompiler bieten darüberh<strong>in</strong>aus e<strong>in</strong>e Vielzahl weiterer Funktionen,die das Programmieren erleichtern, aber die Portabilitätverschlechtern.


326 ANHANG D. C-LEXIKOND.4 pr<strong>in</strong>tf(3), scanf(3)pr<strong>in</strong>tf(3) und scanf(3) s<strong>in</strong>d die bei<strong>de</strong>n Standardfunktionenzum E<strong>in</strong>- und Ausgeben von Daten. Wichtiger Unterschied:pr<strong>in</strong>tf(3) erwartet Variable, scanf(3) Po<strong>in</strong>ter. Die Formatbezeichnerstimmen weitgehend übere<strong>in</strong>:Bezeichner Typ Beispiel Be<strong>de</strong>utung%c char a Zeichen%s char * Karlsruhe Str<strong>in</strong>g%d <strong>in</strong>t -1234 <strong>de</strong>zimale Ganzzahl mit Vorzeichen%i <strong>in</strong>t -1234 <strong>de</strong>zimale Ganzzahl mit Vorzeichen%u unsigned 1234 <strong>de</strong>zimale Ganzzahl ohne Vorzeichen%ld long 1234 <strong>de</strong>zimal Ganzzahl doppelter Länge%f double 12.34 Gleitkommazahl mit Vorzeichen%e double 1.234 E 1 Gleitkommazahl, Exponentialform%g double 12.34 kurze Darstellung von %e o<strong>de</strong>r %f%o unsigned octal 2322 oktale Ganzzahl ohne Vorzeichen%x unsigned hex 4d2 hexa<strong>de</strong>zimale Ganzzahl o. Vorzeichen%p void * 68ff32e4 Po<strong>in</strong>ter%% - % ProzentzeichenWeiteres im Referenz-Handbuch unter pr<strong>in</strong>tf(3) o<strong>de</strong>rscanf(3). Länge, Bündigkeit, Unterdrückung führen<strong>de</strong>rNullen, Vorzeichenangabe können festgelegt wer<strong>de</strong>n.D.5 Inclu<strong>de</strong>-DateienDie Standard-Inclu<strong>de</strong>-Dateien enthalten <strong>in</strong> lesbarer Form Def<strong>in</strong>itionenvon Konstanten und Typen, Deklarationen von Funktionenund Makro<strong>de</strong>f<strong>in</strong>itionen. Sie wer<strong>de</strong>n von Systemaufrufenund Bibliotheksfunktionen benötigt. Bei <strong>de</strong>r Beschreibungje<strong>de</strong>r Funktion im Referenz-Handbuch ist angegeben, welcheInclu<strong>de</strong>-Dateien jeweils e<strong>in</strong>gebun<strong>de</strong>n wer<strong>de</strong>n müssen. GebräuchlicheInclu<strong>de</strong>-Dateien s<strong>in</strong>d:• ctype.h, Def<strong>in</strong>ition von Zeichenklassen (conv(3))• curses.h, Bildschirmsteuerung (curses(3))• errno.h, Fehlermeldungen <strong>de</strong>s Systems (errno(2))


D.6. PRÄPROZESSOR-ANWEISUNGEN 327• fcntl.h, Steuerung <strong>de</strong>s Dateizugriffs(fcntl(2), open(2))• malloc.h, Speicherallokierung (malloc(3))• math.h, mathematische Funktionen(log(3), sqrt(3), floor(3))• memory.h, Speicherfunktionen (memory(3))• search.h, Suchfunktionen (bsearch(3))• signal.h, Signalbehandlung (signal(2))• stdio.h, E<strong>in</strong>- und Ausgabe(pr<strong>in</strong>tf(3), scanf(3), fopen(3))• str<strong>in</strong>g.h, Str<strong>in</strong>gbehandlung (str<strong>in</strong>g(3))• time.h, Zeitfunktionen (ctime(3))• varargs.h, Argumentenliste variabler Länge(vpr<strong>in</strong>tf(3))• sys/ioctl.h, E<strong>in</strong>- und Ausgabe (ioctl(2))• sys/stat.h, Zugriffsrechte (chmod(2), mkdir(2), stat(2))• sys/types.h , verschie<strong>de</strong>ne Deklarationen(chmod(2), getut(3))Auch diese Liste ist vom Compiler und damit von <strong>de</strong>r Hardwareabhängig. So f<strong>in</strong><strong>de</strong>t man die <strong>in</strong>clu<strong>de</strong>-Datei dos.h nicht aufUNIX-Anlagen, son<strong>de</strong>rn nur bei Compilern unter MS-DOS fürPCs.D.6 Präprozessor-AnweisungenDer erste Schritt beim Compilieren ist die Bearbeitung <strong>de</strong>sQuelltextes durch <strong>de</strong>n Präprozessor. Dieser entfernt <strong>de</strong>n Kommentarund führt Ersetzungen und E<strong>in</strong>fügungen gemäß <strong>de</strong>r folgen<strong>de</strong>nAnweisungen (directives) aus:• #<strong>de</strong>f<strong>in</strong>e buchstäbliche Ersetzung e<strong>in</strong>er symbolischen Konstanteno<strong>de</strong>r e<strong>in</strong>es Makros. Ist ke<strong>in</strong> Ersatz angegeben, wirdnur <strong>de</strong>r Name als <strong>de</strong>f<strong>in</strong>iert angesehen (für #if<strong>de</strong>f). Häufig.• #un<strong>de</strong>f<strong>in</strong>e löscht die Def<strong>in</strong>ition e<strong>in</strong>es Namens.• #error führt zu e<strong>in</strong>er Fehlermeldung <strong>de</strong>s Präprozessors.


328 ANHANG D. C-LEXIKON• #<strong>in</strong>clu<strong>de</strong> zieht die angegebene Datei here<strong>in</strong>. Häufig.• #if, #else, #elif, #endif falls Bed<strong>in</strong>gung zutrifft,wer<strong>de</strong>n die nachfolgen<strong>de</strong>n Präprozessor-Anweisungen ausgeführt.• #if<strong>de</strong>f, #ifn<strong>de</strong>f falls <strong>de</strong>r angegebene Name <strong>de</strong>f<strong>in</strong>iertbzw. nicht <strong>de</strong>f<strong>in</strong>iert ist, wer<strong>de</strong>n die nachfolgen<strong>de</strong>nPräprozessor-Anweisungen ausgeführt.• #l<strong>in</strong>e führt bei Fehlermeldungen zu e<strong>in</strong>em Sprung auf dieangegebenen Zeilennummer.• #pragma veranlaßt <strong>de</strong>n Präprozessor zu e<strong>in</strong>er systemabhängigenHandlung.


EKarlsruher TestNicht je<strong>de</strong>rmann eignet sich für so schwierige D<strong>in</strong>ge wie die elektronischeDatenverarbeitung. Um Ihnen die Entscheidung zu erleichtern,ob Sie <strong>in</strong> die EDV e<strong>in</strong>steigen o<strong>de</strong>r sich angenehmerenD<strong>in</strong>gen widmen sollten, haben wir ganz beson<strong>de</strong>rs für Sie e<strong>in</strong>enTest entwickelt. Woran <strong>de</strong>nken Sie bei:BitBier aus <strong>de</strong>r Eifel (1 Punkt)Schraubendrehere<strong>in</strong>satz (1)kle<strong>in</strong>ste Datene<strong>in</strong>heit (2 Punkte)Festplatte Was zum Essen, vom Partyservice (1)Schallplatte (0)Massenspeicher (2)Menü Was zum Essen (1)Dialogtechnik (2)mittelalterlicher Tanz (0)CPU politische Partei (0)Zentralprozessor (2)Carnevalsvere<strong>in</strong> (0)L<strong>in</strong>ker L<strong>in</strong>kshän<strong>de</strong>r (0)Anhänger e<strong>in</strong>er L<strong>in</strong>kspartei (1)Programm zum B<strong>in</strong><strong>de</strong>n von Modulen (2)IBM Ich B<strong>in</strong> Mü<strong>de</strong> (1)International Bus<strong>in</strong>ess Mach<strong>in</strong>es (2)International Brotherhood of Magicians (1)Schnittstelle Verletzung (1)Verb<strong>in</strong>dungsstelle zweier EDV-Geräte (2)Werkstatt e<strong>in</strong>es Bartscherers (0)Slot Steckerleiste im Computer (2)329


330 ANHANG E. KARLSRUHER TESTe<strong>in</strong>armiger Bandit (1)nie<strong>de</strong>r<strong>de</strong>utsch für Kam<strong>in</strong> (0)


331Fortran starker Lebertran (0)Formal Trash Notation (0)Programmiersprache (2)Ma<strong>in</strong>frame Frachtkahn auf <strong>de</strong>m Ma<strong>in</strong> (0)Damit wollte FRIDTJOF NANSEN zum Nordpol (0)großer Computer (2)PC Plumpsklo (Gravitationstoilette) (1)Personal Computer (2)Power Comput<strong>in</strong>g Language (0)Puffer Was zum Essen, aus Kartoffeln (1)Was am Eisenbahnwagen (1)Zwischenspeicher (2)Software Rohstoff für Softice (0)Programme, Daten und so Zeugs (2)was zum Tr<strong>in</strong>ken (0)Port was zum Tr<strong>in</strong>ken (1)Hafen (1)Steckdose für Peripheriegeräte (2)Strichco<strong>de</strong> masch<strong>in</strong>ell lesbarer Co<strong>de</strong> (2)Geheimsprache im Rotlichtviertel (0)Urliste <strong>in</strong> <strong>de</strong>r Statistik (0)Chip was zum Essen (1)was zum Spielen (1)Halbleiterbauste<strong>in</strong> (2)Po<strong>in</strong>ter Hund (1)starker Whisky (0)Zeiger auf Daten, Adresse (2)Page Hotelboy (1)englisch, Seite <strong>in</strong> e<strong>in</strong>em Buch (1)Unterglie<strong>de</strong>rung e<strong>in</strong>es Speichers (2)


332 ANHANG E. KARLSRUHER TESTCharacter was manchen Politikern fehlt (1)Schriftzeichen (2)Wasserfall (0)


333BetriebssystemKonzern (0)betriebs<strong>in</strong>ternes Telefonsystem (0)wichtigstes Programm im Computer (2)Traktor Papiere<strong>in</strong>zugsvorrichtung (2)landwirtschaftliches Fahrzeug (1)Zahl beim Multiplizieren (0)Treiber Hilfsperson bei <strong>de</strong>r Jagd (1)Programm zum Ansprechen <strong>de</strong>r Peripherie (2)Vorarbeiter (0)Animator was zum Tr<strong>in</strong>ken (1)Unterhalter (1)Programm für bewegte Grafik (2)Hackbrett Musik<strong>in</strong>strument (1)Werkzeug im Hackbau (0)Tastatur (2)emulieren nachahmen (2)Öl <strong>in</strong> Wasser verteilen (0)entpflichten (0)Font Menge von Schriftzeichen (2)Soßengrundlage (1)H<strong>in</strong>tergrund, Geldmenge (0)Server Brettsegler (0)Kellner (0)Computer für Dienstleistungen (2)Yabbawhap Datenkompressionsprogramm (2)Kriegsruf <strong>de</strong>r Südstadt-Indianer (0)was zum Essen (0)Term<strong>in</strong>al Schnittstelle Mensch - Computer (2)Bahnhof o<strong>de</strong>r Hafen (1)Zubehör zu Drahttauwerk (1)


334 ANHANG E. KARLSRUHER TESTAmpersand Sand aus <strong>de</strong>r Amper (1)et-Zeichen, Kaufmanns-Und (2)Untiefe im Wattenmeer (0)


335Alias altgriechisches Epos (0)alttestamentarischer Prophet (0)Zweitname (2)Buscontroller Busfahrer (0)Busschaffner (0)Programm zur Steuerung e<strong>in</strong>es Datenbusses (2)Algol was zum Tr<strong>in</strong>ken (0)Doppelstern (1)Programmiersprache (2)Rom Stadt <strong>in</strong> Italien (1)schwedisch für Rum (1)Read only memory (2)Dram Dynamic random access memory (2)dänisch für Schnaps (1)Straßenbahn (0)Diskette Mädchen, das oft <strong>in</strong> Discos geht (0)weiblicher Diskjockey (0)Massenspeicher (2)Directory oberste Etage e<strong>in</strong>er Firma (0)Inhaltsverzeichnis (2)Kunststil zur Zeit <strong>de</strong>r Franz. Revolution (0)Dekrement was die Verdauung übrig läßt (0)Anordnung von oben (0)Wert, um <strong>de</strong>n e<strong>in</strong> Zähler verr<strong>in</strong>gert wird (2)Sprungbefehl Vorkommnis während Ihres Wehrdienstes (0)Kommando im Pfer<strong>de</strong>sport (0)Anweisung <strong>in</strong> e<strong>in</strong>em Programm (2)Oktalzahl Maß für die Klopffestigkeit (0)Zahl zur Basis 8 (2)Anzahl <strong>de</strong>r Oktaven e<strong>in</strong>er Orgel (0)


336 ANHANG E. KARLSRUHER TESTSubrout<strong>in</strong>e Kleidungsstück e<strong>in</strong>es Priesters (0)was im Unterbewußten (0)Unterprogramm (2)


337Spoiler Was zum Essen (0)Post<strong>in</strong>g <strong>in</strong> <strong>de</strong>n Netnews (2)Was am Auto (1)virtuell tugendhaft (0)die Augen betreffend (0)nicht wirklich vorhan<strong>de</strong>n, sche<strong>in</strong>bar (2)Klammeraffe ASCII-Zeichen (2)Bürogerät (1)Affenart <strong>in</strong> Südamerika (0)ESC Eisenbahner-Spar- und Creditvere<strong>in</strong> (0)Eishockeyclub (0)escape, Fluchtsymbol (2)Monitor Karlsruher Brauerei (0)Fernsehsendung (1)Bildschirmgerät, Überwachungsprogramm (2)Unix Tütensuppe (0)Freund von Asterix und Obelix (0)hervorragen<strong>de</strong>s Betriebssystem (2)Joystick Computerzubehör (2)männlicher Körperteil (0)Hebel am Spielautomat (0)Maus kle<strong>in</strong>es Säugetier (1)Computerzubehör (2)junge Dame (1)Icon russisches Heiligenbild (0)S<strong>in</strong>nbild (2)Kamerafabrik (0)Pascal französischer Mathematiker (1)Maße<strong>in</strong>heit für Druck (1)Programmiersprache (2)


338 ANHANG E. KARLSRUHER TESTWysiwyg englisch für Wolpert<strong>in</strong>ger (0)französisch für Elmentritschen (0)what you see is what you get (2)


339Register was <strong>in</strong> Flensburg (1)was an <strong>de</strong>r Orgel (1)Speicher (2)Record was im Sport (1)englisch für Blockflöte (0)Datensatz (2)HP High Price (0)Hewlett-Packard (2)Horse Power (1)Kermit Klebstoff (0)Frosch aus <strong>de</strong>r Muppet-Show (1)Fileübertragungs-Protokoll (2)Ethernet Baustoff (Asbestzement) (0)Local Area Network (2)Stu<strong>de</strong>nt <strong>de</strong>r ETH Zürich (0)Algorithmus Übermäßiger Genuß geistiger Getränke (0)Krankheit (0)Rechenvorschrift (2)File Was zum Essen (0)Menge von Daten (2)Durchtriebener Kerl (0)Bug Vor<strong>de</strong>rteil e<strong>in</strong>es Schiffes (1)Fehler im Programm (2)englisch für Wanze (1)Router jemand mit Rout<strong>in</strong>e (0)französischer LKW-Fahrer (0)Verb<strong>in</strong>dungsglied zweier Netze (2)Zyl<strong>in</strong><strong>de</strong>r Kopfbe<strong>de</strong>ckung (1)Teil e<strong>in</strong>er Kolbenmasch<strong>in</strong>e (1)Unterteilung e<strong>in</strong>es Plattenspeichers (2)


340 ANHANG E. KARLSRUHER TESTFTP kle<strong>in</strong>e, aber liberale Partei (0)File Transfer Protocol (2)Float<strong>in</strong>g Po<strong>in</strong>t Processor (0)


341DomäneGeist(0)Bereich (2)Blume (0)Bridge Kartenspiel (1)<strong>in</strong>ternationales Computernetz (0)Verb<strong>in</strong>dung zweier Computernetze (2)Email Glasur (1)elektronische Post (2)Sultanspalast (0)Baum was im Wald (Wurzel unten) (1)was auf e<strong>in</strong>em Schiff (ke<strong>in</strong>e Wurzel) (1)was aus <strong>de</strong>r Informatik (Wurzel oben) (2)Internet Schule mit Schlafgelegenheit (0)Zwischenraum (0)Weltweites Computernetz (2)Split UNIX-Kommando (2)kantige Ste<strong>in</strong>chen (0)Stadt <strong>in</strong> Dalmatien (1)M<strong>in</strong>i Damenoberbekleidung (1)kle<strong>in</strong>er Computer (2)Frau von Mickey Mouse (0)Cut Herrenoberbekleidung (1)Colonia Ulpia Traiana (1)UNIX-Kommando (2)2B|!2B Parallelprozessor (0)Assembler-Befehl (0)e<strong>in</strong> Wort Hamlets (2)Shell Filmschauspieler<strong>in</strong> (Maria S.) (0)Kommando-Interpreter (2)M<strong>in</strong>eralöl-Gesellschaft (1)


342 ANHANG E. KARLSRUHER TESTSlip Unterbekleidung (1)Schlupfschuh (0)Internet-Protokoll (2)


343Diäresis Durchfall (0)Diakritisches Zeichen (Umlaute) (2)Ernährungslehre (0)Space Bar Kneipe im Weltraum (www.spacebar.com) (0)Maße<strong>in</strong>heit für <strong>de</strong>n Druck im Weltraum (0)Größte Taste auf <strong>de</strong>r Tastatur (2)Popper Popcorn-Röster (0)Mail-Programm (2)Philosoph aus Wien (1)Rohl<strong>in</strong>g Wüster Kerl (1)Noch zu beschreiben<strong>de</strong> CD/DVD (2)Rohkost-Liebhaber (0)Schleife Kleidungsstück (1)Schlitterbahn (1)Kontrollanweisung e<strong>in</strong>es Programmes (2)<strong>Alex</strong> Altlasten-Expertensystem (1)Automatic Log<strong>in</strong> Executor (1)Globales Filesystem (1)Altair Stern (Alpha Aquilae) (1)Gebirge <strong>in</strong> Zentralasien (0)früher Personal Computer (2)Halbbitter Was zum Essen (Schokola<strong>de</strong>) (1)Strom- und bitsparen<strong>de</strong>r Prozessor (0)Was zum Tr<strong>in</strong>ken (0)Eure Priorität Anre<strong>de</strong> <strong>de</strong>s Priors <strong>in</strong> e<strong>in</strong>em Kloster (0)Anre<strong>de</strong> <strong>de</strong>s Ersten Sekretärs im Vatikan (0)Anre<strong>de</strong> <strong>de</strong>s System-Managers (6)Zählen Sie Ihre Punkte zusammen. Die Auswertung ergibt Folgen<strong>de</strong>s:• über 170 Punkte: Überlassen Sie das Rechnen künftig <strong>de</strong>mComputer.


344 ANHANG E. KARLSRUHER TEST• 85 bis 170 Punkte: Mit etwas Fleiß wird aus Ihnen e<strong>in</strong> EDV-Experte.• 18 bis 84 Punkte: Machen Sie e<strong>in</strong>e möglichst steile Karriereaußerhalb <strong>de</strong>r EDV und suchen Sie sich fähige Mitarbeiter.• unter 18 Punkten: Vielleicht hatten Sie schlechte Lehrer?


FGNU LizenzenF.1 GNU General Public LicenseKopiert von http://www.gnu.org/copyleft/.Version 2, June 1991Copyright © 1989, 1991 Free Software Foundation, Inc.59 Temple Place - Suite 330, Boston, MA 02111-1307, USAEveryone is permitted to copy and distribute verbatim copies ofthis license document, but chang<strong>in</strong>g it is not allowed.PREAMBLEThe licenses for most software are <strong>de</strong>signed to take away yourfreedom to share and change it. By contrast, the GNU GeneralPublic License is <strong>in</strong>ten<strong>de</strong>d to guarantee your freedom to shareand change free software—to make sure the software is free forall its users. This General Public License applies to most of theFree Software Foundation’s software and to any other programwhose authors commit to us<strong>in</strong>g it. (Some other Free SoftwareFoundation software is covered by the GNU Library General PublicLicense <strong>in</strong>stead.) You can apply it to your programs, too.When we speak of free software, we are referr<strong>in</strong>g to freedom,not price. Our General Public Licenses are <strong>de</strong>signed to make surethat you have the freedom to distribute copies of free software(and charge for this service if you wish), that you receive sourceco<strong>de</strong> or can get it if you want it, that you can change the softwareor use pieces of it <strong>in</strong> new free programs; and that you know youcan do these th<strong>in</strong>gs.To protect your rights, we need to make restrictions that forbidanyone to <strong>de</strong>ny you these rights or to ask you to surren<strong>de</strong>rthe rights. These restrictions translate to certa<strong>in</strong> responsibilitiesfor you if you distribute copies of the software, or if you modifyit.345


346 ANHANG F. GNU LIZENZENFor example, if you distribute copies of such a program, whethergratis or for a fee, you must give the recipients all the rightsthat you have. You must make sure that they, too, receive or canget the source co<strong>de</strong>. And you must show them these terms so theyknow their rights.We protect your rights with two steps: (1) copyright the software,and (2) offer you this license which gives you legal permissionto copy, distribute and/or modify the software.Also, for each author’s protection and ours, we want to makecerta<strong>in</strong> that everyone un<strong>de</strong>rstands that there is no warranty forthis free software. If the software is modified by someone else andpassed on, we want its recipients to know that what they have isnot the orig<strong>in</strong>al, so that any problems <strong>in</strong>troduced by others willnot reflect on the orig<strong>in</strong>al authors’ reputations.F<strong>in</strong>ally, any free program is threatened constantly by softwarepatents. We wish to avoid the danger that redistributors ofa free program will <strong>in</strong>dividually obta<strong>in</strong> patent licenses, <strong>in</strong> effectmak<strong>in</strong>g the program proprietary. To prevent this, we have ma<strong>de</strong>it clear that any patent must be licensed for everyone’s free useor not licensed at all.The precise terms and conditions for copy<strong>in</strong>g, distribution andmodification follow.GNU GENERAL PUBLIC LICENSETERMS AND CONDITIONS FOR COPYING,DISTRIBUTION AND MODIFICATION0. This License applies to any program or other work whichconta<strong>in</strong>s a notice placed by the copyright hol<strong>de</strong>r say<strong>in</strong>g itmay be distributed un<strong>de</strong>r the terms of this General PublicLicense. The “Program”, below, refers to any such programor work, and a “work based on the Program” means eitherthe Program or any <strong>de</strong>rivative work un<strong>de</strong>r copyright law:that is to say, a work conta<strong>in</strong><strong>in</strong>g the Program or a portionof it, either verbatim or with modifications and/or translated<strong>in</strong>to another language. (Here<strong>in</strong>after, translation is <strong>in</strong>clu<strong>de</strong>dwithout limitation <strong>in</strong> the term “modification”.) Eachlicensee is addressed as “you”.Activities other than copy<strong>in</strong>g, distribution and modificationare not covered by this License; they are outsi<strong>de</strong> its scope.


F.1. GNU GENERAL PUBLIC LICENSE 347The act of runn<strong>in</strong>g the Program is not restricted, and theoutput from the Program is covered only if its contents constitutea work based on the Program (<strong>in</strong><strong>de</strong>pen<strong>de</strong>nt of hav<strong>in</strong>gbeen ma<strong>de</strong> by runn<strong>in</strong>g the Program). Whether that istrue <strong>de</strong>pends on what the Program does.1. You may copy and distribute verbatim copies of the Program’ssource co<strong>de</strong> as you receive it, <strong>in</strong> any medium, provi<strong>de</strong>dthat you conspicuously and appropriately publish oneach copy an appropriate copyright notice and disclaimerof warranty; keep <strong>in</strong>tact all the notices that refer to thisLicense and to the absence of any warranty; and give anyother recipients of the Program a copy of this License alongwith the Program.You may charge a fee for the physical act of transferr<strong>in</strong>g acopy, and you may at your option offer warranty protection<strong>in</strong> exchange for a fee.2. You may modify your copy or copies of the Program or anyportion of it, thus form<strong>in</strong>g a work based on the Program,and copy and distribute such modifications or work un<strong>de</strong>rthe terms of Section 1 above, provi<strong>de</strong>d that you also meetall of these conditions:(a) You must cause the modified files to carry prom<strong>in</strong>entnotices stat<strong>in</strong>g that you changed the files and the dateof any change.(b) You must cause any work that you distribute or publish,that <strong>in</strong> whole or <strong>in</strong> part conta<strong>in</strong>s or is <strong>de</strong>rivedfrom the Program or any part thereof, to be licensedas a whole at no charge to all third parties un<strong>de</strong>r theterms of this License.(c) If the modified program normally reads commands <strong>in</strong>teractivelywhen run, you must cause it, when startedrunn<strong>in</strong>g for such <strong>in</strong>teractive use <strong>in</strong> the most ord<strong>in</strong>aryway, to pr<strong>in</strong>t or display an announcement <strong>in</strong>clud<strong>in</strong>g anappropriate copyright notice and a notice that there isno warranty (or else, say<strong>in</strong>g that you provi<strong>de</strong> a warranty)and that users may redistribute the program un<strong>de</strong>rthese conditions, and tell<strong>in</strong>g the user how to view acopy of this License. (Exception: if the Program itself


348 ANHANG F. GNU LIZENZENis <strong>in</strong>teractive but does not normally pr<strong>in</strong>t such an announcement,your work based on the Program is notrequired to pr<strong>in</strong>t an announcement.)These requirements apply to the modified work as a whole.If i<strong>de</strong>ntifiable sections of that work are not <strong>de</strong>rived fromthe Program, and can be reasonably consi<strong>de</strong>red <strong>in</strong><strong>de</strong>pen<strong>de</strong>ntand separate works <strong>in</strong> themselves, then this License,and its terms, do not apply to those sections when you distributethem as separate works. But when you distributethe same sections as part of a whole which is a work basedon the Program, the distribution of the whole must beon the terms of this License, whose permissions for otherlicensees extend to the entire whole, and thus to each an<strong>de</strong>very part regardless of who wrote it.Thus, it is not the <strong>in</strong>tent of this section to claim rights orcontest your rights to work written entirely by you; rather,the <strong>in</strong>tent is to exercise the right to control the distributionof <strong>de</strong>rivative or collective works based on the Program.In addition, mere aggregation of another work not basedon the Program with the Program (or with a work basedon the Program) on a volume of a storage or distributionmedium does not br<strong>in</strong>g the other work un<strong>de</strong>r the scope ofthis License.3. You may copy and distribute the Program (or a work basedon it, un<strong>de</strong>r Section 2) <strong>in</strong> object co<strong>de</strong> or executable formun<strong>de</strong>r the terms of Sections 1 and 2 above provi<strong>de</strong>d thatyou also do one of the follow<strong>in</strong>g:(a) Accompany it with the complete correspond<strong>in</strong>gmach<strong>in</strong>e-readable source co<strong>de</strong>, which must be distributedun<strong>de</strong>r the terms of Sections 1 and 2 above on amedium customarily used for software <strong>in</strong>terchange; or,(b) Accompany it with a written offer, valid for at leastthree years, to give any third party, for a charge nomore than your cost of physically perform<strong>in</strong>g sourcedistribution, a complete mach<strong>in</strong>e-readable copy of thecorrespond<strong>in</strong>g source co<strong>de</strong>, to be distributed un<strong>de</strong>r theterms of Sections 1 and 2 above on a medium customarilyused for software <strong>in</strong>terchange; or,


F.1. GNU GENERAL PUBLIC LICENSE 349(c) Accompany it with the <strong>in</strong>formation you received as tothe offer to distribute correspond<strong>in</strong>g source co<strong>de</strong>. (Thisalternative is allowed only for noncommercial distributionand only if you received the program <strong>in</strong> objectco<strong>de</strong> or executable form with such an offer, <strong>in</strong> accordwith Subsection b above.)The source co<strong>de</strong> for a work means the preferred form ofthe work for mak<strong>in</strong>g modifications to it. For an executablework, complete source co<strong>de</strong> means all the source co<strong>de</strong>for all modules it conta<strong>in</strong>s, plus any associated <strong>in</strong>terface<strong>de</strong>f<strong>in</strong>ition files, plus the scripts used to control compilationand <strong>in</strong>stallation of the executable. However, as a specialexception, the source co<strong>de</strong> distributed need not <strong>in</strong>clu<strong>de</strong> anyth<strong>in</strong>gthat is normally distributed (<strong>in</strong> either source or b<strong>in</strong>aryform) with the major components (compiler, kernel, andso on) of the operat<strong>in</strong>g system on which the executable runs,unless that component itself accompanies the executable.If distribution of executable or object co<strong>de</strong> is ma<strong>de</strong> by offer<strong>in</strong>gaccess to copy from a <strong>de</strong>signated place, then offer<strong>in</strong>gequivalent access to copy the source co<strong>de</strong> from the sameplace counts as distribution of the source co<strong>de</strong>, even thoughthird parties are not compelled to copy the source alongwith the object co<strong>de</strong>.4. You may not copy, modify, sublicense, or distribute the Programexcept as expressly provi<strong>de</strong>d un<strong>de</strong>r this License. Anyattempt otherwise to copy, modify, sublicense or distributethe Program is void, and will automatically term<strong>in</strong>ate yourrights un<strong>de</strong>r this License. However, parties who have receivedcopies, or rights, from you un<strong>de</strong>r this License willnot have their licenses term<strong>in</strong>ated so long as such partiesrema<strong>in</strong> <strong>in</strong> full compliance.5. You are not required to accept this License, s<strong>in</strong>ce you havenot signed it. However, noth<strong>in</strong>g else grants you permissionto modify or distribute the Program or its <strong>de</strong>rivativeworks. These actions are prohibited by law if you do not acceptthis License. Therefore, by modify<strong>in</strong>g or distribut<strong>in</strong>gthe Program (or any work based on the Program), you <strong>in</strong>dicateyour acceptance of this License to do so, and all its


350 ANHANG F. GNU LIZENZENterms and conditions for copy<strong>in</strong>g, distribut<strong>in</strong>g or modify<strong>in</strong>gthe Program or works based on it.6. Each time you redistribute the Program (or any work basedon the Program), the recipient automatically receives a licensefrom the orig<strong>in</strong>al licensor to copy, distribute or modifythe Program subject to these terms and conditions. You maynot impose any further restrictions on the recipients’ exerciseof the rights granted here<strong>in</strong>. You are not responsiblefor enforc<strong>in</strong>g compliance by third parties to this License.7. If, as a consequence of a court judgment or allegation ofpatent <strong>in</strong>fr<strong>in</strong>gement or for any other reason (not limitedto patent issues), conditions are imposed on you (whetherby court or<strong>de</strong>r, agreement or otherwise) that contradict theconditions of this License, they do not excuse you from theconditions of this License. If you cannot distribute so as tosatisfy simultaneously your obligations un<strong>de</strong>r this Licenseand any other pert<strong>in</strong>ent obligations, then as a consequenceyou may not distribute the Program at all. For example, if apatent license would not permit royalty-free redistributionof the Program by all those who receive copies directly or<strong>in</strong>directly through you, then the only way you could satisfyboth it and this License would be to refra<strong>in</strong> entirely fromdistribution of the Program.If any portion of this section is held <strong>in</strong>valid or unenforceableun<strong>de</strong>r any particular circumstance, the balance of thesection is <strong>in</strong>ten<strong>de</strong>d to apply and the section as a whole is<strong>in</strong>ten<strong>de</strong>d to apply <strong>in</strong> other circumstances.It is not the purpose of this section to <strong>in</strong>duce you to <strong>in</strong>fr<strong>in</strong>geany patents or other property right claims or to contest validityof any such claims; this section has the sole purposeof protect<strong>in</strong>g the <strong>in</strong>tegrity of the free software distributionsystem, which is implemented by public license practices.Many people have ma<strong>de</strong> generous contributions to the wi<strong>de</strong>range of software distributed through that system <strong>in</strong> relianceon consistent application of that system; it is up to theauthor/donor to <strong>de</strong>ci<strong>de</strong> if he or she is will<strong>in</strong>g to distributesoftware through any other system and a licensee cannotimpose that choice.


F.1. GNU GENERAL PUBLIC LICENSE 351This section is <strong>in</strong>ten<strong>de</strong>d to make thoroughly clear what isbelieved to be a consequence of the rest of this License.8. If the distribution and/or use of the Program is restricted <strong>in</strong>certa<strong>in</strong> countries either by patents or by copyrighted <strong>in</strong>terfaces,the orig<strong>in</strong>al copyright hol<strong>de</strong>r who places the Programun<strong>de</strong>r this License may add an explicit geographical distributionlimitation exclud<strong>in</strong>g those countries, so that distributionis permitted only <strong>in</strong> or among countries not thusexclu<strong>de</strong>d. In such case, this License <strong>in</strong>corporates the limitationas if written <strong>in</strong> the body of this License.9. The Free Software Foundation may publish revised and/ornew versions of the General Public License from time totime. Such new versions will be similar <strong>in</strong> spirit to the presentversion, but may differ <strong>in</strong> <strong>de</strong>tail to address new problemsor concerns.Each version is given a dist<strong>in</strong>guish<strong>in</strong>g version number. Ifthe Program specifies a version number of this Licensewhich applies to it and “any later version”, you have theoption of follow<strong>in</strong>g the terms and conditions either of thatversion or of any later version published by the Free SoftwareFoundation. If the Program does not specify a versionnumber of this License, you may choose any version everpublished by the Free Software Foundation.10. If you wish to <strong>in</strong>corporate parts of the Program <strong>in</strong>to otherfree programs whose distribution conditions are different,write to the author to ask for permission. For softwarewhich is copyrighted by the Free Software Foundation, writeto the Free Software Foundation; we sometimes makeexceptions for this. Our <strong>de</strong>cision will be gui<strong>de</strong>d by the twogoals of preserv<strong>in</strong>g the free status of all <strong>de</strong>rivatives of ourfree software and of promot<strong>in</strong>g the shar<strong>in</strong>g and reuse ofsoftware generally.NO WARRANTY11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE,THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EX-TENT PERMITTED BY APPLICABLE LAW. EXCEPT WHENOTHERWISE STATED IN WRITING THE COPYRIGHT HOL-DERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM


352 ANHANG F. GNU LIZENZEN“AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EX-PRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,THE IMPLIED WARRANTIES OF MERCHANTABILITY ANDFITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISKAS TO THE QUALITY AND PERFORMANCE OF THE PROGRAMIS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,YOU ASSUME THE COST OF ALL NECESSARY SERVICING,REPAIR OR CORRECTION.12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW ORAGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER,OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDIS-TRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLETO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECI-AL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISINGOUT OF THE USE OR INABILITY TO USE THE PROGRAM(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DA-TA BEING RENDERED INACCURATE OR LOSSES SUSTAINEDBY YOU OR THIRD PARTIES OR A FAILURE OF THE PRO-GRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVENIF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OFTHE POSSIBILITY OF SUCH DAMAGES.END OF TERMS AND CONDITIONSAppendix: How to Apply These Terms toYour New ProgramsIf you <strong>de</strong>velop a new program, and you want it to be of the greatestpossible use to the public, the best way to achieve this isto make it free software which everyone can redistribute andchange un<strong>de</strong>r these terms.To do so, attach the follow<strong>in</strong>g notices to the program. It issafest to attach them to the start of each source file to most effectivelyconvey the exclusion of warranty; and each file shouldhave at least the “copyright” l<strong>in</strong>e and a po<strong>in</strong>ter to where the fullnotice is found.


F.1. GNU GENERAL PUBLIC LICENSE 353Copyright (C) This program is free software; you can redistribute itand/or modify it un<strong>de</strong>r the terms of the GNU GeneralPublic License as published by the Free SoftwareFoundation; either version 2 of the License, or (at youroption) any later version.This program is distributed <strong>in</strong> the hope that it willbe useful, but WITHOUT ANY WARRANTY; withouteven the implied warranty of MERCHANTABILITYor FITNESS FOR A PARTICULAR PURPOSE. Seethe GNU General Public License for more <strong>de</strong>tails.You should have received a copy of the GNU GeneralPublic License along with this program; if not, write tothe Free Software Foundation, Inc., 59 Temple Place -Suite 330, Boston, MA 02111-1307, USA.Also add <strong>in</strong>formation on how to contact you by electronic andpaper mail.If the program is <strong>in</strong>teractive, make it output a short noticelike this when it starts <strong>in</strong> an <strong>in</strong>teractive mo<strong>de</strong>:Gnomovision version 69, Copyright (C) Gnomovision comes with ABSOLUTELY NO WAR-RANTY; for <strong>de</strong>tails type ‘show w’.This is free software, and you are welcome to redistributeit un<strong>de</strong>r certa<strong>in</strong> conditions; type ‘show c’ for<strong>de</strong>tails.The hypothetical commands show w and show c shouldshow the appropriate parts of the General Public License. Ofcourse, the commands you use may be called someth<strong>in</strong>g otherthan show w and show c; they could even be mouse-clicks ormenu items—whatever suits your program.You should also get your employer (if you work as a programmer)or your school, if any, to sign a “copyright disclaimer” forthe program, if necessary. Here is a sample; alter the names:Yoyodyne, Inc., hereby disclaims all copyright <strong>in</strong>terest<strong>in</strong> the program


354 ANHANG F. GNU LIZENZEN‘Gnomovision’ (which makes passes at compilers)written by James Hacker., 1 April 1989Ty Coon, Presi<strong>de</strong>nt of ViceThis General Public License does not permit <strong>in</strong>corporat<strong>in</strong>gyour program <strong>in</strong>to proprietary programs. If your program is asubrout<strong>in</strong>e library, you may consi<strong>de</strong>r it more useful to permit l<strong>in</strong>k<strong>in</strong>gproprietary applications with the library. If this is what youwant to do, use the GNU Library General Public License <strong>in</strong>steadof this License.F.2 GNU Free Documentation LicenseKopiert von http://www.gnu.org/copyleft/.Version 1.2, November 2002Copyright ©2000,2001,2002 Free Software Foundation, Inc.59 Temple Place, Suite 330, Boston, MA 02111-1307 USAEveryone is permitted to copy and distribute verbatim copies ofthis license document, but chang<strong>in</strong>g it is not allowed.PreambleThe purpose of this license is to make a manual, textbook, orother functional and useful document free <strong>in</strong> the sense of freedom:to assure everyone the effective freedom to copy and redistributeit, with or without modify<strong>in</strong>g it, either commercially ornoncommercially. Secondarily, this license preserves for the authorand publisher a way to get credit for their work, while notbe<strong>in</strong>g consi<strong>de</strong>red responsible for modifications ma<strong>de</strong> by others.This license is a k<strong>in</strong>d of copyleft, which means that <strong>de</strong>rivativeworks of the document must themselves be free <strong>in</strong> the same sense.It complements the GNU General Public License, which is acopyleft license <strong>de</strong>signed for free software.We have <strong>de</strong>signed this license <strong>in</strong> or<strong>de</strong>r to use it for manualsfor free software, because free software needs free documentation:a free program should come with manuals provid<strong>in</strong>g the


F.2. GNU FREE DOCUMENTATION LICENSE 355same freedoms that the software does. But this license is not limitedto software manuals; it can be used for any textual work,regardless of subject matter or whether it is published as a pr<strong>in</strong>tedbook. We recommend this license pr<strong>in</strong>cipally for works whosepurpose is <strong>in</strong>struction or reference.1. APPLICABILITY AND DEFINITIONSThis license applies to any manual or other work, <strong>in</strong> any medium,that conta<strong>in</strong>s a notice placed by the copyright hol<strong>de</strong>r say<strong>in</strong>git can be distributed un<strong>de</strong>r the terms of this license. Sucha notice grants a world-wi<strong>de</strong>, royalty-free license, unlimited <strong>in</strong>duration, to use that work un<strong>de</strong>r the conditions stated here<strong>in</strong>.The Document, below, refers to any such manual or work. Anymember of the public is a licensee, and is addressed as you. Youaccept the license if you copy, modify or distribute the work <strong>in</strong> away requir<strong>in</strong>g permission un<strong>de</strong>r copyright law.A Modified Version of the Document means any work conta<strong>in</strong><strong>in</strong>gthe Document or a portion of it, either copied verbatim,or with modifications and/or translated <strong>in</strong>to another language.A Secondary Section is a named appendix or a front-mattersection of the Document that <strong>de</strong>als exclusively with the relationshipof the publishers or authors of the Document to theDocument’s overall subject (or to related matters) and conta<strong>in</strong>snoth<strong>in</strong>g that could fall directly with<strong>in</strong> that overall subject. (Thus,if the Document is <strong>in</strong> part a textbook of mathematics, a SecondarySection may not expla<strong>in</strong> any mathematics.) The relationshipcould be a matter of historical connection with the subject or withrelated matters, or of legal, commercial, philosophical, ethical orpolitical position regard<strong>in</strong>g them.The Invariant Sections are certa<strong>in</strong> Secondary Sectionswhose titles are <strong>de</strong>signated, as be<strong>in</strong>g those of Invariant Sections,<strong>in</strong> the notice that says that the Document is released un<strong>de</strong>rthis license. If a section does not fit the above <strong>de</strong>f<strong>in</strong>ition of Secondarythen it is not allowed to be <strong>de</strong>signated as Invariant. TheDocument may conta<strong>in</strong> zero Invariant Sections. If the Documentdoes not i<strong>de</strong>ntify any Invariant Sections then there are none.The Cover Texts are certa<strong>in</strong> short passages of text that arelisted, as Front-Cover Texts or Back-Cover Texts, <strong>in</strong> the noticethat says that the Document is released un<strong>de</strong>r this license. A


356 ANHANG F. GNU LIZENZENFront-Cover Text may be at most 5 words, and a Back-Cover Textmay be at most 25 words.A Transparent copy of the Document means a mach<strong>in</strong>ereadablecopy, represented <strong>in</strong> a format whose specification isavailable to the general public, that is suitable for revis<strong>in</strong>g theDocument straightforwardly with generic text editors or (forimages composed of pixels) generic pa<strong>in</strong>t programs or (for draw<strong>in</strong>gs)some wi<strong>de</strong>ly available draw<strong>in</strong>g editor, and that is suitablefor <strong>in</strong>put to text formatters or for automatic translation toa variety of formats suitable for <strong>in</strong>put to text formatters. A copyma<strong>de</strong> <strong>in</strong> an otherwise Transparent file format whose markup,or absence of markup, has been arranged to thwart or discouragesubsequent modification by rea<strong>de</strong>rs is not Transparent.An image format is not Transparent if used for any substantialamount of text. A copy that is not Transparent is called Opaque.Examples of suitable formats for Transparent copies <strong>in</strong>clu<strong>de</strong>pla<strong>in</strong> ASCII without markup, Tex<strong>in</strong>fo <strong>in</strong>put format, LaTeX <strong>in</strong>putformat, SGML or XML us<strong>in</strong>g a publicly available DTD, andstandard-conform<strong>in</strong>g simple HTML, PostScript or PDF <strong>de</strong>signedfor human modification. Examples of transparent image formats<strong>in</strong>clu<strong>de</strong> PNG, XCF and JPG. Opaque formats <strong>in</strong>clu<strong>de</strong> proprietaryformats that can be read and edited only by proprietary wordprocessors, SGML or XML for which the DTD and/or process<strong>in</strong>gtools are not generally available, and the mach<strong>in</strong>e-generatedHTML, PostScript or PDF produced by some word processors foroutput purposes only.The Title Page means, for a pr<strong>in</strong>ted book, the title page itself,plus such follow<strong>in</strong>g pages as are nee<strong>de</strong>d to hold, legibly, the materialthis license requires to appear <strong>in</strong> the title page. For works<strong>in</strong> formats which do not have any title page as such, TTitle Pagemmeansthe text near the most prom<strong>in</strong>ent appearance of thework’s title, preced<strong>in</strong>g the beg<strong>in</strong>n<strong>in</strong>g of the body of the text.A section Entitled XYZ means a named subunit of the Documentwhose title either is precisely XYZ or conta<strong>in</strong>s XYZ <strong>in</strong>parentheses follow<strong>in</strong>g text that translates XYZ <strong>in</strong> another language.(Here XYZ stands for a specific section name mentionedbelow, such as Acknowledgements, Dedications, Endorsements,or History.) To Preserve the Title of such a sectionwhen you modify the Document means that it rema<strong>in</strong>s a sectionEntitled XYZ accord<strong>in</strong>g to this <strong>de</strong>f<strong>in</strong>ition.


F.2. GNU FREE DOCUMENTATION LICENSE 357The Document may <strong>in</strong>clu<strong>de</strong> Warranty Disclaimers next to thenotice which states that this license applies to the Document.These Warranty Disclaimers are consi<strong>de</strong>red to be <strong>in</strong>clu<strong>de</strong>d by reference<strong>in</strong> this license, but only as regards disclaim<strong>in</strong>g warranties:any other implication that these Warranty Disclaimers mayhave is void and has no effect on the mean<strong>in</strong>g of this license.2. VERBATIM COPYINGYou may copy and distribute the Document <strong>in</strong> any medium,either commercially or noncommercially, provi<strong>de</strong>d that this license,the copyright notices, and the license notice say<strong>in</strong>g this licenseapplies to the Document are reproduced <strong>in</strong> all copies, and thatyou add no other conditions whatsoever to those of this license.You may not use technical measures to obstruct or control theread<strong>in</strong>g or further copy<strong>in</strong>g of the copies you make or distribute.However, you may accept compensation <strong>in</strong> exchange for copies.If you distribute a large enough number of copies you must alsofollow the conditions <strong>in</strong> section 3.You may also lend copies, un<strong>de</strong>r the same conditions statedabove, and you may publicly display copies.3. COPYING IN QUANTITYIf you publish pr<strong>in</strong>ted copies (or copies <strong>in</strong> media that commonlyhave pr<strong>in</strong>ted covers) of the Document, number<strong>in</strong>g more than100, and the Document’s license notice requires Cover Texts, youmust enclose the copies <strong>in</strong> covers that carry, clearly and legibly,all these Cover Texts: Front-Cover Texts on the front cover,and Back-Cover Texts on the back cover. Both covers must alsoclearly and legibly i<strong>de</strong>ntify you as the publisher of these copies.The front cover must present the full title with all words of thetitle equally prom<strong>in</strong>ent and visible. You may add other materialon the covers <strong>in</strong> addition. Copy<strong>in</strong>g with changes limited to thecovers, as long as they preserve the title of the Document andsatisfy these conditions, can be treated as verbatim copy<strong>in</strong>g <strong>in</strong>other respects.If the required texts for either cover are too volum<strong>in</strong>ous to fitlegibly, you should put the first ones listed (as many as fit reasonably)on the actual cover, and cont<strong>in</strong>ue the rest onto adjacentpages.


358 ANHANG F. GNU LIZENZENIf you publish or distribute Opaque copies of the Documentnumber<strong>in</strong>g more than 100, you must either <strong>in</strong>clu<strong>de</strong> a mach<strong>in</strong>ereadableTransparent copy along with each Opaque copy, or state<strong>in</strong> or with each Opaque copy a computer-network location fromwhich the general network-us<strong>in</strong>g public has access to downloadus<strong>in</strong>g public-standard network protocols a complete Transparentcopy of the Document, free of ad<strong>de</strong>d material. If you use the latteroption, you must take reasonably pru<strong>de</strong>nt steps, when youbeg<strong>in</strong> distribution of Opaque copies <strong>in</strong> quantity, to ensure thatthis Transparent copy will rema<strong>in</strong> thus accessible at the statedlocation until at least one year after the last time you distributean Opaque copy (directly or through your agents or retailers) ofthat edition to the public.It is requested, but not required, that you contact the authorsof the Document well before redistribut<strong>in</strong>g any large number ofcopies, to give them a chance to provi<strong>de</strong> you with an updatedversion of the Document.4. MODIFICATIONSYou may copy and distribute a Modified Version of the Documentun<strong>de</strong>r the conditions of sections 2 and 3 above, provi<strong>de</strong>dthat you release the Modified Version un<strong>de</strong>r precisely this license,with the Modified Version fill<strong>in</strong>g the role of the Document,thus licens<strong>in</strong>g distribution and modification of the Modified Versionto whoever possesses a copy of it. In addition, you must dothese th<strong>in</strong>gs <strong>in</strong> the Modified Version:A. Use <strong>in</strong> the Title Page (and on the covers, if any) a title dist<strong>in</strong>ctfrom that of the Document, and from those of previousversions (which should, if there were any, be listed <strong>in</strong> theHistory section of the Document). You may use the sametitle as a previous version if the orig<strong>in</strong>al publisher of thatversion gives permission.B. List on the Title Page, as authors, one or more persons orentities responsible for authorship of the modifications <strong>in</strong>the Modified Version, together with at least five of the pr<strong>in</strong>cipalauthors of the Document (all of its pr<strong>in</strong>cipal authors,if it has fewer than five), unless they release you from thisrequirement.


F.2. GNU FREE DOCUMENTATION LICENSE 359C. State on the Title page the name of the publisher of theModified Version, as the publisher.D. Preserve all the copyright notices of the Document.E. Add an appropriate copyright notice for your modificationsadjacent to the other copyright notices.F. Inclu<strong>de</strong>, immediately after the copyright notices, a licensenotice giv<strong>in</strong>g the public permission to use the Modified Versionun<strong>de</strong>r the terms of this license, <strong>in</strong> the form shown <strong>in</strong>the Ad<strong>de</strong>ndum below.G. Preserve <strong>in</strong> that license notice the full lists of Invariant Sectionsand required Cover Texts given <strong>in</strong> the Document’s licensenotice.H. Inclu<strong>de</strong> an unaltered copy of this license.I. Preserve the section entitled History, Preserve its title, andadd to it an item stat<strong>in</strong>g at least the title, year, new authors,and publisher of the Modified Version as given onthe Title Page. If there is no section entitled History <strong>in</strong> theDocument, create one stat<strong>in</strong>g the title, year, authors, andpublisher of the Document as given on its Title Page, thenadd an item <strong>de</strong>scrib<strong>in</strong>g the Modified Version as stated <strong>in</strong>the previous sentence.J. Preserve the network location, if any, given <strong>in</strong> the Documentfor public access to a Transparent copy of the Document,and likewise the network locations given <strong>in</strong> the Documentfor previous versions it was based on. These maybe placed <strong>in</strong> the History section. You may omit a networklocation for a work that was published at least four yearsbefore the Document itself, or if the orig<strong>in</strong>al publisher ofthe version it refers to gives permission.K. For any section entitled Acknowledgements or Dedications,Preserve the title of the section, and preserve <strong>in</strong> the sectionall the substance and tone of each of the contributoracknowledgements and/or <strong>de</strong>dications given there<strong>in</strong>.L. Preserve all the Invariant Sections of the Document, unaltered<strong>in</strong> their text and <strong>in</strong> their titles. Section numbers orthe equivalent are not consi<strong>de</strong>red part of the section titles.


360 ANHANG F. GNU LIZENZENM. Delete any section entitled Endorsements. Such a sectionmay not be <strong>in</strong>clu<strong>de</strong>d <strong>in</strong> the Modified Version.N. Do not retitle any exist<strong>in</strong>g section to be entitled Endorsementsor to conflict <strong>in</strong> title with any Invariant Section.O. Preserve any Warranty Disclaimers.If the Modified Version <strong>in</strong>clu<strong>de</strong>s new front-matter sections orappendices that qualify as Secondary Sections and conta<strong>in</strong> nomaterial copied from the Document, you may at your option <strong>de</strong>signatesome or all of these sections as <strong>in</strong>variant. To do this, addtheir titles to the list of Invariant Sections <strong>in</strong> the Modified Version’slicense notice. These titles must be dist<strong>in</strong>ct from any othersection titles.You may add a section entitled Endorsements, provi<strong>de</strong>d it conta<strong>in</strong>snoth<strong>in</strong>g but endorsements of your Modified Version by variousparties – for example, statements of peer review or that thetext has been approved by an organization as the authoritative<strong>de</strong>f<strong>in</strong>ition of a standard.You may add a passage of up to five words as a Front-CoverText, and a passage of up to 25 words as a Back-Cover Text, tothe end of the list of Cover Texts <strong>in</strong> the Modified Version. Onlyone passage of Front-Cover Text and one of Back-Cover Text maybe ad<strong>de</strong>d by (or through arrangements ma<strong>de</strong> by) any one entity.If the Document already <strong>in</strong>clu<strong>de</strong>s a cover text for the same cover,previously ad<strong>de</strong>d by you or by arrangement ma<strong>de</strong> by the sameentity you are act<strong>in</strong>g on behalf of, you may not add another; butyou may replace the old one, on explicit permission from the previouspublisher that ad<strong>de</strong>d the old one.The author(s) and publisher(s) of the Document do not by thislicense give permission to use their names for publicity for or toassert or imply endorsement of any Modified Version.5. COMBINING DOCUMENTSYou may comb<strong>in</strong>e the Document with other documents releasedun<strong>de</strong>r this license, un<strong>de</strong>r the terms <strong>de</strong>f<strong>in</strong>ed <strong>in</strong> section 4 abovefor modified versions, provi<strong>de</strong>d that you <strong>in</strong>clu<strong>de</strong> <strong>in</strong> the comb<strong>in</strong>ationall of the Invariant Sections of all of the orig<strong>in</strong>al documents,unmodified, and list them all as Invariant Sections of your comb<strong>in</strong>edwork <strong>in</strong> its license notice, and that you preserve all theirWarranty Disclaimers.


F.2. GNU FREE DOCUMENTATION LICENSE 361The comb<strong>in</strong>ed work need only conta<strong>in</strong> one copy of this license,and multiple i<strong>de</strong>ntical Invariant Sections may be replaced witha s<strong>in</strong>gle copy. If there are multiple Invariant Sections with thesame name but different contents, make the title of each suchsection unique by add<strong>in</strong>g at the end of it, <strong>in</strong> parentheses, the nameof the orig<strong>in</strong>al author or publisher of that section if known, orelse a unique number. Make the same adjustment to the sectiontitles <strong>in</strong> the list of Invariant Sections <strong>in</strong> the license notice of thecomb<strong>in</strong>ed work.In the comb<strong>in</strong>ation, you must comb<strong>in</strong>e any sections entitledHistory <strong>in</strong> the various orig<strong>in</strong>al documents, form<strong>in</strong>g one sectionentitled History; likewise comb<strong>in</strong>e any sections entitled Acknowledgements,and any sections entitled Dedications. You must <strong>de</strong>leteall sections entitled Endorsements.6. COLLECTIONS OF DOCUMENTSYou may make a collection consist<strong>in</strong>g of the Document andother documents released un<strong>de</strong>r this license, and replace the <strong>in</strong>dividualcopies of this license <strong>in</strong> the various documents with as<strong>in</strong>gle copy that is <strong>in</strong>clu<strong>de</strong>d <strong>in</strong> the collection, provi<strong>de</strong>d that youfollow the rules of this license for verbatim copy<strong>in</strong>g of each of thedocuments <strong>in</strong> all other respects.You may extract a s<strong>in</strong>gle document from such a collection, anddistribute it <strong>in</strong>dividually un<strong>de</strong>r this license, provi<strong>de</strong>d you <strong>in</strong>serta copy of this license <strong>in</strong>to the extracted document, and follow thislicense <strong>in</strong> all other respects regard<strong>in</strong>g verbatim copy<strong>in</strong>g of thatdocument.7. AGGREGATION WITHINDEPENDENT WORKSA compilation of the Document or its <strong>de</strong>rivatives with otherseparate and <strong>in</strong><strong>de</strong>pen<strong>de</strong>nt documents or works, <strong>in</strong> or on a volumeof a storage or distribution medium, is called an aggregate if thecopyright result<strong>in</strong>g from the compilation is not used to limit thelegal rights of the compilation’s users beyond what the <strong>in</strong>dividualworks permit. When the Document is <strong>in</strong>clu<strong>de</strong>d <strong>in</strong> an aggregate,this license does not apply to the other works <strong>in</strong> the aggregatewhich are not themselves <strong>de</strong>rivative works of the Document.


362 ANHANG F. GNU LIZENZENIf the Cover Text requirement of section 3 is applicable to thesecopies of the Document, then if the Document is less than onehalf of the entire aggregate, the Document’s Cover Texts may beplaced on covers that bracket the Document with<strong>in</strong> the aggregate,or the electronic equivalent of covers if the Document is <strong>in</strong>electronic form. Otherwise they must appear on pr<strong>in</strong>ted coversthat bracket the whole aggregate.8. TRANSLATIONTranslation is consi<strong>de</strong>red a k<strong>in</strong>d of modification, so you maydistribute translations of the Document un<strong>de</strong>r the terms of section4. Replac<strong>in</strong>g Invariant Sections with translations requiresspecial permission from their copyright hol<strong>de</strong>rs, but you may <strong>in</strong>clu<strong>de</strong>translations of some or all Invariant Sections <strong>in</strong> additionto the orig<strong>in</strong>al versions of these Invariant Sections. You may <strong>in</strong>clu<strong>de</strong>a translation of this license, and all the license notices <strong>in</strong>the Document, and any Warranty Disclaimers, provi<strong>de</strong>d that youalso <strong>in</strong>clu<strong>de</strong> the orig<strong>in</strong>al English version of this license and theorig<strong>in</strong>al versions of those notices and disclaimers. In case of adisagreement between the translation and the orig<strong>in</strong>al versionof this license or a notice or disclaimer, the orig<strong>in</strong>al version willprevail.If a section <strong>in</strong> the Document is entitled Acknowledgements,Dedications, or History, the requirement (section 4) to Preserveits title (section 1) will typically require chang<strong>in</strong>g the actual title.9. TERMINATIONYou may not copy, modify, sublicense, or distribute the Documentexcept as expressly provi<strong>de</strong>d for un<strong>de</strong>r this license. Anyother attempt to copy, modify, sublicense or distribute the Documentis void, and will automatically term<strong>in</strong>ate your rights un<strong>de</strong>rthis license. However, parties who have received copies, or rights,from you un<strong>de</strong>r this license will not have their licenses term<strong>in</strong>atedso long as such parties rema<strong>in</strong> <strong>in</strong> full compliance.10. FUTURE REVISIONS OF THISLICENSE


F.2. GNU FREE DOCUMENTATION LICENSE 363The Free Software Foundation may publish new, revised versionsof the GNU Free Documentation License from time to time.Such new versions will be similar <strong>in</strong> spirit to the present version,but may differ <strong>in</strong> <strong>de</strong>tail to address new problems or concerns. Seehttp://www.gnu.org/copyleft/.Each version of the license is given a dist<strong>in</strong>guish<strong>in</strong>g versionnumber. If the Document specifies that a particular numberedversion of this license or any later version applies to it, you havethe option of follow<strong>in</strong>g the terms and conditions either of thatspecified version or of any later version that has been published(not as a draft) by the Free Software Foundation. If the Documentdoes not specify a version number of this license, you maychoose any version ever published (not as a draft) by the FreeSoftware Foundation.ADDENDUM: How to use this licensefor your documentsTo use this license <strong>in</strong> a document you have written, <strong>in</strong>clu<strong>de</strong> acopy of the license <strong>in</strong> the Document and put the follow<strong>in</strong>g copyrightand license notices just after the title page:Copyright ©YEAR YOUR NAME. Permission is grantedto copy, distribute and/or modify this documentun<strong>de</strong>r the terms of the GNU Free Documentation License,Version 1.2 or any later version published bythe Free Software Foundation; with no Invariant Sections,no Front-Cover Texts, and no Back-Cover Texts.A copy of the license is <strong>in</strong>clu<strong>de</strong>d <strong>in</strong> the section entitledGNU Free Documentation License.If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the with...Texts. l<strong>in</strong>e with this:with the Invariant Sections be<strong>in</strong>g LIST THEIR TIT-LES, with the Front-Cover Texts be<strong>in</strong>g LIST, and withthe Back-Cover Texts be<strong>in</strong>g LIST.


364 ANHANG F. GNU LIZENZENIf you have Invariant Sections without Cover Texts, or someother comb<strong>in</strong>ation of the three, merge those two alternatives tosuit the situation.If your document conta<strong>in</strong>s nontrivial examples of program co<strong>de</strong>,we recommend releas<strong>in</strong>g these examples <strong>in</strong> parallel un<strong>de</strong>ryour choice of free software license, such as the GNU GeneralPublic License, to permit their use <strong>in</strong> free software.


GZeittafelAusführlichere Angaben s<strong>in</strong>d <strong>de</strong>n im Anhang ?? Zum Weiterlesen<strong>in</strong> Abschnitt Geschichte auf Seiete ?? aufgeführten Werkenzu entnehmen. Die meisten Errungenschaften entwickelten sichüber manchmal lange Zeitspannen, so dass vor e<strong>in</strong>ige Jahreszahlenum etwa zu setzen ist.-10E8 Der beliebte Tyrannosaurus hatte zwei F<strong>in</strong>ger an je<strong>de</strong>r Handund rechnete vermutlich im Dualsystem, wenn überhaupt.-2000 Die Babylonier verwen<strong>de</strong>n für beson<strong>de</strong>re Aufgaben e<strong>in</strong>gemischtes Stellenwertsystem zur Basis 60.-400 In Ch<strong>in</strong>a wer<strong>de</strong>n Zählstäbchen zum Rechnen verwen<strong>de</strong>t.20 In <strong>de</strong>r Bergpredigt wird das B<strong>in</strong>ärsystem erwähnt (Matth. 5, 37).Die Römer schieben Rechenste<strong>in</strong>chen (calculi).600 Die In<strong>de</strong>r entwickeln das heute übliche re<strong>in</strong>e Stellenwertsystem,die Null ist jedoch älter. Etwa gleichzeitig entwickeln die Mayas<strong>in</strong> Mittelamerika e<strong>in</strong> Stellenwertsystem zur Basis 20.1200 LEONARDO VON PISA, genannt FIBONACCI, setzt sich für dieE<strong>in</strong>führung <strong>de</strong>s <strong>in</strong>disch-arabischen Systems im Abendland e<strong>in</strong>.1550 Die europäischen Rechenmeister verwen<strong>de</strong>n sowohl die römischeals auch die <strong>in</strong>disch-arabische Schreibweise.1617 JOHN NAPIER erf<strong>in</strong><strong>de</strong>t die Rechenknochen (Napier’s Bones).1623 Erste mechanische Rechenmasch<strong>in</strong>e mit Zehnerübertragungund Multiplikation, von WILHELM SCHICKARD, Tüb<strong>in</strong>gen.1642 Rechenmasch<strong>in</strong>e von BLAISE PASCAL, Paris für kaufmännischeRechnungen se<strong>in</strong>es Vaters.1674 GOTTFRIED WILHELM LEIBNIZ baut e<strong>in</strong>e mechanischeRechenmasch<strong>in</strong>e für die vier Grundrechenarten und befasst sichmit <strong>de</strong>r dualen Darstellung von Zahlen. In <strong>de</strong>r Folgezeittechnische Verbesserungen an vielen Stellen <strong>in</strong> Europa.1714 HENRY MILL erhält e<strong>in</strong> Patent auf e<strong>in</strong>e Schreibmasch<strong>in</strong>e.1801 JOSEPH MARIE JACQUARD erf<strong>in</strong><strong>de</strong>t die Lochkarte undsteuert Webstühle damit.1821 CHARLES BABBAGE stellt <strong>de</strong>r Royal Astronomical Societye<strong>in</strong>e programmierbare mechanische Rechenmasch<strong>in</strong>e vor, diejedoch ke<strong>in</strong>en wirtschaftlichen Erfolg hat. Er <strong>de</strong>nkt auch an365


366 ANHANG G. ZEITTAFELdas Spielen von Schach o<strong>de</strong>r Tic-tac-toe auf Masch<strong>in</strong>en.1840 SAMUEL FINLEY BREEZE MORSE entwickelt e<strong>in</strong>en aus zweiZeichen plus Pausen bestehen<strong>de</strong>n Telegrafenco<strong>de</strong>, <strong>de</strong>r dieBuchstaben entsprechend ihrer Häufigkeit codiert.1847 GEORGE BOOLE entwickelt die symbolische Logik.1861 JOHANN PHILIPP REIS erf<strong>in</strong><strong>de</strong>t das Telephon.1873 ELIPHALET REMINGTON and Sons, NY, stellen außer Gewehrenund Nähmasch<strong>in</strong>en auch Schreibmasch<strong>in</strong>en her. 1886 trennen sie sichvom Schreibmasch<strong>in</strong>enbereich, <strong>de</strong>r später <strong>de</strong>n Namen Rem<strong>in</strong>gton Randund noch später <strong>de</strong>n Namen Sperry Rand trägt.1876 ALEXANDER GRAHAM BELL erhält e<strong>in</strong> Patent auf se<strong>in</strong> Telefon.1877 Gründung <strong>de</strong>r Bell Telephone Company.1885 Aus Bell Telephone Co. wird American Telephone + Telegraph Co.1890 HERMAN HOLLERITH erf<strong>in</strong><strong>de</strong>t die Lochkartenmasch<strong>in</strong>e undsetzt sie bei e<strong>in</strong>er Volkszählung <strong>in</strong> <strong>de</strong>n USA e<strong>in</strong>. Das ist <strong>de</strong>rAnfang von IBM.1894 OTTO LUEGERs Lexikon <strong>de</strong>r gesamten Technik führtunter <strong>de</strong>m Stichwort Elektrizität als Halbleiter Äther,Alkohol, Holz und Papier auf.1895 Erste Übertragungen mittels Radio (ALEXANDER POPOW,GUGLIELMO MARCONI).1896 Gründung <strong>de</strong>r Tabulat<strong>in</strong>g Mach<strong>in</strong>e Company, <strong>de</strong>r späteren IBM.1898 VALDEMAR POULSEN erf<strong>in</strong><strong>de</strong>t die magnetische Aufzeichnungvon Tönen (Telegraphon).1900 01. Januar 1900 00:00:00 GMT Nullpunkt <strong>de</strong>r gegenwärtigenNTP-Ära (e<strong>in</strong>e NTP-Ära umfasst 136 Jahre).1910 Gründung <strong>de</strong>r Deutschen Hollerith Masch<strong>in</strong>en GmbH, Berl<strong>in</strong>,<strong>de</strong>r Vorläufer<strong>in</strong> <strong>de</strong>r IBM Deutschland.1918 Das Enigma-Verschlüsselungsverfahren entwickelt.1924 Aus <strong>de</strong>r Tabulat<strong>in</strong>g Mach<strong>in</strong>e Company von HERMAN HOLLERITH,später <strong>in</strong> Comput<strong>in</strong>g-Tabulat<strong>in</strong>g-Record<strong>in</strong>g Company umbenannt,wird die International Bus<strong>in</strong>ess Mach<strong>in</strong>es (IBM).1930 EDWIN LINK baut – anstatt Pianos und Orgeln wie se<strong>in</strong> Vater –e<strong>in</strong>en mechanischen Flugsimulator für Übungs- und Vergnügungszweckund erhält e<strong>in</strong> Patent darauf. Der L<strong>in</strong>k-Tra<strong>in</strong>er erlangt Verbreitung.1932 Die Firma AEG baut das erste Tonbandgerät mit <strong>de</strong>m NamenMagnetophon. Die Bän<strong>de</strong>r dazu liefert die BASF.1937 ALAN TURING veröffentlicht se<strong>in</strong> Computermo<strong>de</strong>ll.1938 KONRAD ZUSE stellt <strong>de</strong>n programmgesteuerten Rechner Z 1 fertig.E<strong>in</strong> späterer Nachbau schafft 1 Rechenoperation pro Sekun<strong>de</strong>.


367Elektronische b<strong>in</strong>äre Addiermasch<strong>in</strong>e von JOHN VINCENT ATANASOund CLIFFORD BERRY, Iowa State University, zur Lösung l<strong>in</strong>earerGleichungssysteme.1939 KONRAD ZUSE stellt die Z 2 fertig.Gründung <strong>de</strong>r Firma Hewlett-Packard, Palo Alto, Kaliforniendurch WILLIAM HEWLETT und DAVID PACKARD. Ihr erstesProdukt ist e<strong>in</strong> Oszillator für Tonfrequenzen (Messtechnik).1941 KONRAD ZUSE stellt die Z 3 fertig.1942 Die Purdue University beg<strong>in</strong>nt mit <strong>de</strong>r Halbleiterforschung unduntersucht Germaniumkristalle.1943 Der Computer Colossus, Bletchley Park/Buck<strong>in</strong>ghamshire UK,entschlüsselt <strong>de</strong>utsche Militärnachrichten (Enigma).IBM-Chef THOMAS WATSON schätzt <strong>de</strong>n weltweiten Bedarf anComputern auf 5 (fünf) Stück.1944 Die Zuse Z 4 wird fertig (2200 Relais, mechanischer Speicher).Sie arbeitet von 1950 bis 1960 <strong>in</strong> <strong>de</strong>r Schweiz.An <strong>de</strong>r Harvard University bauen HOWARD AIKEN und GRACE HOPdie Mark I <strong>in</strong> Relaistechnik. Die Masch<strong>in</strong>e läuft bis 1959.1945 KONRAD ZUSE entwickelt <strong>de</strong>n Plankalkül, die erste höhereProgrammiersprache.WILLIAM BRADFORD SHOCKLEY startet e<strong>in</strong> Forschungsprojekt zurHalbleiterphysik <strong>in</strong> <strong>de</strong>n Bell-Labs.VANNEVAR BUSH entwickelt e<strong>in</strong> System zur Informationsspeicherunund -suche, das auf Mikrofilmen beruht.1946 JOHN VON NEUMANN veröffentlicht se<strong>in</strong> Computerkonzept.JOHN PRESPER ECKERT und JOHN WILLIAM MAUCHLY bauen <strong>in</strong><strong>de</strong>n USA die ENIAC (Electronic Numerical Integrator andComputer). Die ENIAC rechnet <strong>de</strong>zimal, enthält 18000 Vakuumröhrwiegt 30 t, ist 5,5 m hoch und 24 m lang, braucht für e<strong>in</strong>e Addition0,2 ms, ist an <strong>de</strong>r Entwicklung <strong>de</strong>r Wasserstoffbombe beteiligt undarbeitet bis 1955. Sie ist <strong>de</strong>r Urahne <strong>de</strong>r UNIVAC.1948 CLAUDE ELWOOD SHANNON begrün<strong>de</strong>t die Informationstheorie.JOHN BARDEEN, WALTER HOUSER BRATTAIN undWILLIAM BRADFORD SHOCKLEY entwickeln <strong>in</strong> <strong>de</strong>n Bell-Labs<strong>de</strong>n Transistor, <strong>de</strong>r 10 Jahre später die Vakuumröhre ablöst.1949 Erster Schachcomputer: Manchester MADM. Das Wort Bit kreiert.1950 An <strong>de</strong>r ETH Zürich geht die Zuse Z 4 <strong>in</strong> Betrieb.1952 IBM br<strong>in</strong>gt ihre erste elektronische Datenverarbeitungsanlage,die IBM 701, heraus.1953 IBM baut die erste Magnetbandmasch<strong>in</strong>e zur Datenspeicherung (72


368 ANHANG G. ZEITTAFEL1954 Rem<strong>in</strong>gton-Rand br<strong>in</strong>gt die erste UNIVAC heraus, IBM die 650.Silizium beg<strong>in</strong>nt, das Germanium zu verdrängen.1955 IBM entwickelt die erste höhere Programmiersprache, dieVerbreitung erlangt: FORTRAN (Formula Translator) und verwen<strong>de</strong>tTransistoren <strong>in</strong> ihren Computern.1956 KONRAD ZUSE baut die Z 22, die mit Röhren arbeitet.Sie kommt 1958 auf <strong>de</strong>n Markt. Bis 1961 wer<strong>de</strong>n 50 Stück verkauft.BARDEEN, BRATTAIN und SHOCKLEY erhalten <strong>de</strong>n Nobelpreisfür Physik.IBM stellt die erste Festplatte vor (IBM 350 Disk File für <strong>de</strong>nComputer RAMAC 305), Kapazität 5 MByte, groß wie e<strong>in</strong> Schrank,Gewicht 1 to, bestehend aus 50 Scheiben zu 24 Zoll, 50.000 US-$.1957 Die IBM 709 braucht für e<strong>in</strong>e Multiplikation 0,12 ms.Weltweit arbeiten rund 1300 Computer.Sem<strong>in</strong>ar von Prof. JOHANNES WEISSINGER über ProgrammgesteuerteRechenmasch<strong>in</strong>en im SS 1957 <strong>de</strong>r TH Karlsruhe.KARL STEINBUCH (Firma SEL, später TH Karlsruhe) prägt <strong>de</strong>nBegriff Informatik.Erster Satellit (Sputnik, Sowjetunion) kreist um die Er<strong>de</strong>.1958 Als e<strong>in</strong>e Reaktion auf <strong>de</strong>n Sputnik grün<strong>de</strong>t das us-amerikanischeVerteidigungsm<strong>in</strong>isterium (DoD) die Denkfabrik Advanced ResearchProjects Agency (ARPA), die später das ARPANET aufbaut.MARVIN LEE MINSKY prägt <strong>de</strong>n Begriff Artificial Intelligence.Die TH Karlsruhe erhält ihren ersten Computer, e<strong>in</strong>e ZUSE Z 22,f<strong>in</strong>anziert vom Land Ba<strong>de</strong>n-Württemberg.Die Masch<strong>in</strong>e verwen<strong>de</strong>t 400 Vakuumröhren und wiegt 1 t. DerArbeitsspeicher fasst 16 Wörter zu 38 Bits, d. h. 76 Byte. DerMassenspeicher, e<strong>in</strong>e Magnettrommel, fasst rund 40 KByte. E<strong>in</strong>eGleitkommaoperation dauert 70 ms. Das System versteht nurMasch<strong>in</strong>ensprache (Freiburger Co<strong>de</strong>) und läuft bis 1972.Im SS 1958 hält Priv.-Doz. KARL NICKEL (Institut für Angew.Mathematik) e<strong>in</strong>e Vorlesung Programmieren mathematischer undtechnischer Probleme für die elektronische Rechenmasch<strong>in</strong>e Z 22.Die Programmiersprache ALGOL 58 kommt heraus.Bei Texas Instruments baut JACK ST. CLAIR KILBY <strong>de</strong>n ersten IC;im Jahr 2000 erhält er dafür <strong>de</strong>n Nobelpreis für Physik.1959 Im SS 1959 hält Priv.-Doz. KARL NICKEL erstmals dieVorlesung Programmieren I, im WS 1959/60 die VorlesungProgrammieren II. Erstes Werk von Hewlett-Packard <strong>in</strong>Deutschland. Siemens baut die Siemens 2002.


3691960 Programmieren steht noch <strong>in</strong> ke<strong>in</strong>em Studienplan, son<strong>de</strong>rnist freiwillig. Die Karlsruher Z 22 arbeitet Tag und Nacht.Die Programmiersprache COBOL wird veröffentlicht.E<strong>in</strong> Computerspiel namens Spacewar läuft auf e<strong>in</strong>erDigital Equipment Corporation (DEC) PDP-1 im MIT.ALAN SHUGART entwickelt e<strong>in</strong> Verfahren zur Aufzeichnung vonDaten auf e<strong>in</strong>er magnetisch beschichteten Scheibe.1961 Die TH Karlsruhe erhält im Zuge <strong>de</strong>r Berufungsverhandlungen vonProf. Nickel e<strong>in</strong>e Zuse Z 23, die mit 2400 Transistoren arbeitet.Ihr Hauptspeicher fasst 240 Wörter zu 40 Bits.E<strong>in</strong>e Gleitkommaoperation dauert 15 ms. Außer Masch<strong>in</strong>enspracheversteht sie ALGOL.Weltweit arbeiten etwa 7300 Computer.1962 Die TH Karlsruhe erhält e<strong>in</strong>en SEL ER 56, <strong>de</strong>r bis 1968 läuft.An <strong>de</strong>r Purdue University wird die erste Fakultät für Informatik(Department of Computer Science) gegrün<strong>de</strong>t.Texas Instruments und Fairchild nehmen die Serienproduktion von(Chips) auf.JOSEPH CARL ROBNETT LICKLIDER hat zwei Visionen: <strong>de</strong>n <strong>in</strong>terakComputer und das galaktische Netz (wenn schon, <strong>de</strong>nn schon). Er wDirektor <strong>in</strong> <strong>de</strong>r ARPA und geht an die Verwirklichung se<strong>in</strong>er Visione1963 Weltweit arbeiten etwa 16.500 Computer.Erster geostationärer Satellit (Syncom).IVAN E. SUTHERLAND entwickelt <strong>in</strong> se<strong>in</strong>er Doktorarbeit am MITdas Sketchpad, e<strong>in</strong>en grafischen Bildschirm mit Lichtgriffel, undwird damit zum Vater <strong>de</strong>r Computergrafik.1964 Die Programmiersprache BASIC ersche<strong>in</strong>t.DOUGLAS CARL ENGELBART erf<strong>in</strong><strong>de</strong>t am Stanford Research Institudie Maus und die Fenstertechnik.IBM legt das Byte zu 8 Bits fest (IBM 360).E<strong>in</strong> Chip enthält auf 0,5 cm 2 10 Transistoren.1965 Beg<strong>in</strong>n <strong>de</strong>s Betriebssystems MULTICS bei MIT, Bell undGeneral Electric. Aus <strong>de</strong>ssen Misserfolg erwächst später UNIX.1966 Die TH Karlsruhe erhält e<strong>in</strong>e Electrologica X 8, die bis1973 betrieben wird. Gründung <strong>de</strong>s Karlsruher Rechenzentrums.Hewlett-Packard steigt <strong>in</strong> die Computerei e<strong>in</strong> (HP 2116 A).1967 Erster elektronischer Taschenrechner (Texas Instruments).IVAN E. SUTHERLAND entwickelt an <strong>de</strong>r Harvard University e<strong>in</strong>enHelm mit b<strong>in</strong>okularem Display und br<strong>in</strong>gt damit die Virtual Realitye<strong>in</strong> gutes Stück voran.


370 ANHANG G. ZEITTAFEL1968 Am 26. Februar entschei<strong>de</strong>n sich maßgeben<strong>de</strong> Vertreter <strong>de</strong>rComputerwissenschaft im <strong>de</strong>utschsprachigen Raum im Anschluss ane<strong>in</strong> <strong>in</strong>ternationales Kolloquium <strong>in</strong> Dres<strong>de</strong>n für die BezeichnungInformatik nach französischem Beispiel.Die Programmiersprache PASCAL kommt heraus. Die Firma Intelgegrün<strong>de</strong>t. Hewlett-Packard baut <strong>de</strong>n ersten wissenschaftlichenprogrammierbaren Tischrechner (HP 9100 A).1969 In Karlsruhe wird am 1. Januar das Institut für Informatikgegrün<strong>de</strong>t, Direktor KARL NICKEL. Im WS 1969/70 beg<strong>in</strong>nt <strong>in</strong>Karlsruhe die Informatik als Vollstudium mit 91 Erstsemestern.Gründung <strong>de</strong>r Gesellschaft für Informatik (GI) <strong>in</strong> Bonn.In <strong>de</strong>n Bell Labs UNIX <strong>in</strong> Assembler auf e<strong>in</strong>er DEC PDP 7.Beg<strong>in</strong>n <strong>de</strong>s ARPANET-Projektes, erste Teilnehmer U. of California atLos Angeles, Stanford Research Institute, U. of California atSanta Barbara und U. of Utah, allesamt mit DEC PDP-10 Masch<strong>in</strong>en.RFC 0001: Host Software, von STEVE CROCKER.1970 Die Universität Karlsruhe erhält e<strong>in</strong>e UNIVAC 1108,die bis 1987 läuft und damit <strong>de</strong>n hiesigen Rekord an Betriebsjahrenhält. Preis 23 MDM, 3 Zentrale<strong>in</strong>heiten, 256 Kilo-Wörter zuje 36 Bits Arbeitsspeicher, 20 Bildschirme.Die Karlsruher Fakultät für Informatik wird gegrün<strong>de</strong>t.Am 01. Januar 1970 00:00:00 GMT beg<strong>in</strong>nt die UNIX-Uhr zu laufen.1971 UNIX auf C umgeschrieben, erster Mikroprozessor (Intel 4004).ALAN SHUGART entwickelt bei IBM die Floppy Disk.Die Internet-Protokolle FTP (RFC 114) und Telnet (RFC 137) wer<strong>de</strong>nvorgeschlagen und diskutiert.1972 IBM entwickelt das Konzept <strong>de</strong>s virtuellen Speichers undstellt die 8-Zoll-Floppy-Disk vor. Xerox (ROBERT METCALFE),DEC und Intel entwickeln <strong>de</strong>n Ethernet-Standard.Das ARPANET wird <strong>de</strong>r Öffentlichkeit vorgestellt.E<strong>in</strong> Stu<strong>de</strong>nt namens STEPHAN G. WOZNIAK lötet sich e<strong>in</strong>enComputer zusammen, <strong>de</strong>r <strong>de</strong>n Smoke-Test nicht übersteht.In <strong>de</strong>r Bun<strong>de</strong>srepublik arbeiten rund 8.200 Computer.Erster wissenschaftlicher Taschenrechner (Hewlett-Packard 35).1973 Erste <strong>in</strong>ternationale Teilnehmer am ARPANET: NORSAR(Norwegian Seismic Array), Norwegen und U. College of London.1974 Der erste programmierbare Taschenrechner kommt auf <strong>de</strong>nMarkt (Hewlett-Packard 65), Preis 2500 DM.1975 UNIX wird veröffentlicht (Version 6), Beg<strong>in</strong>n <strong>de</strong>r BSD-Entwicklung.Die Zeitschrift Byte wird gegrün<strong>de</strong>t.


371Erste, mäßig erfolgreiche Personal Computer (Xerox, Altair).Die Firma Microsoft Corporation von WILLIAM HENRY GATES III.und PAUL ALLEN gegrün<strong>de</strong>t.1976 STEVEN P. JOBS und STEPHAN G. WOZNIAK grün<strong>de</strong>ndie Firma Apple und bauen <strong>de</strong>n Apple I. Er kostet 666,66 Dollar.ALAN SHUGART stellt die 5,25-Zoll-Diskette vor.Die nichtprozedurale Datenbanksprache SQL – entwickelt vonEDGAR F. CODD bei IBM – wird veröffentlicht.WHITFIELD DIFFIE und MARTIN E. HELLMANN veröffentlichendie erste Arbeit über unsymmetrische Verschlüsselung.1977 ROBERT E. KAHN und VINTON GRAY CERF veröffentlichendas Konzept von TCP/IP, anfangs Kahn-Cerf-Protokolle genannt.1978 In <strong>de</strong>r Bun<strong>de</strong>srepublik arbeiten rund 170.000 Computer.Der Commodore PET 2001 – e<strong>in</strong> Vorläufer <strong>de</strong>s C64 – kommt heraus,4 bis 32 kbyte Arbeitsspeicher, Bildschirm 25 Zeilen zu 40 Zeichen.Erste Tabellenkalkulation Visicalc, für <strong>de</strong>n Apple II,von DAN BRICKLIN und BOB FRANKSTON, Harvard University.Erste Fassung von TEX (DONALD ERVIN KNUTH) veröffentlicht.Das Network Time Protocol (NTP) wird <strong>in</strong> Gebrauch genommen.1979 Faxdienst <strong>in</strong> Deutschland e<strong>in</strong>geführt.Beg<strong>in</strong>n <strong>de</strong>s Usenet <strong>in</strong> <strong>de</strong>r Duke University und <strong>de</strong>r University ofNorth Carol<strong>in</strong>a auf <strong>de</strong>r Basis von uucp-Verb<strong>in</strong>dungen.Die Zusammenarbeit von Apple mit Rank Xerox führt zur AppleLisa, e<strong>in</strong> Mißerfolg, aber <strong>de</strong>r Wegbereiter für <strong>de</strong>n Mac<strong>in</strong>tosh.Plattenherstellerfirma Seagate gegrün<strong>de</strong>t.Gründung <strong>de</strong>r Satelliten-Kommunikations-Firma Inmarsat.BJARNE STROUSTRUP beg<strong>in</strong>nt mit <strong>de</strong>r Entwicklung von <strong>C++</strong>.Programmiersprache Ada veröffentlicht.Betriebssystem DOS für Intel 8086/8088 von Fa. Seattle ComputerProducts entwickelt, später von Microsoft erworben.1980 Erster Jugendprogrammier-Wettbewerb <strong>de</strong>r GI.Erster Home-Computer: S<strong>in</strong>clair ZX-80, für rund 500 DM.Sony führt die 3,5-Zoll-Diskette e<strong>in</strong>. In <strong>de</strong>n Folgejahren entwickelnan<strong>de</strong>re Firmen auch Disketten mit Durchmessern von 3 bis 4 Zoll.Microsoft br<strong>in</strong>gt Xenix, e<strong>in</strong> UNIX für PCs, heraus.1981 Die Universität Karlsruhe erhält e<strong>in</strong>e Siemens 7881 alszentralen Rechner.IBM br<strong>in</strong>gt <strong>in</strong> <strong>de</strong>n USA <strong>de</strong>n IBM-PC heraus mit PC-DOS 1.0(MS DOS) als wichtigstem Betriebssystem.In Berl<strong>in</strong> wird <strong>de</strong>r Chaos Computer Club gegrün<strong>de</strong>t.


372 ANHANG G. ZEITTAFELXanadu-Projekt von TED NELSON, e<strong>in</strong> Vorläufer <strong>de</strong>s Web.1982 Die Firma Sun Microsystems wird gegrün<strong>de</strong>t, entschei<strong>de</strong>t sich fürUNIX und baut die ersten Workstations.JIM CLARK grün<strong>de</strong>t Silicon Graphics, Inc. (SGI)Beg<strong>in</strong>n <strong>de</strong>s EuNETs, e<strong>in</strong>er <strong>de</strong>r ersten <strong>de</strong>utschen Internet-Provi<strong>de</strong>r,an <strong>de</strong>r Universität Dortmund.WILLIAM GIBSON prägt das Wort Cyberspace.MORTON HEILIG präsentiert e<strong>in</strong>en Spielautomaten für MotorradundAuto-Simulationen mit Stereotonfilm, Gebläse, Gerüchen undvibrieren<strong>de</strong>n Sitzen, echt multimedial, aber erfolglos, da zu teuer.1983 Die Universität Karlsruhe erhält e<strong>in</strong>en Vektorrechner Cyber 205und e<strong>in</strong>e Siemens 7865. Die Cyber leistet 400 Mio. Flops.Beg<strong>in</strong>n <strong>de</strong>s Lokalen Informatiknetzes Karlsruhe (LINK), ab 1984Xl<strong>in</strong>k, <strong>in</strong> <strong>de</strong>r Fakultät für Informatik <strong>de</strong>r Universität Karlsruhe.IBM br<strong>in</strong>gt <strong>de</strong>n PC auf <strong>de</strong>n <strong>de</strong>utschen Markt.UNIX kommt als System V von AT&T <strong>in</strong> <strong>de</strong>n Han<strong>de</strong>l,die erste Ausgabe <strong>de</strong>r Zeitschrift Computertechnik (c’t) ersche<strong>in</strong>t(Nr. 12/83 vom Oktober 1983).Gründung <strong>de</strong>r X/Open-Gruppe.MS-DOS 2.0 (PC-DOS 2.0) und Novell Netware kommen heraus.Microsoft W<strong>in</strong>dows wird angekündigt.Das ARPAnet wechselt von NCP auf TCP/IP.1984 Der erste Apple Mac<strong>in</strong>tosh (128K) und <strong>de</strong>r Hewlett-Packard Th<strong>in</strong>kjet,<strong>de</strong>r erste T<strong>in</strong>tenstrahldrucker, kommen auf <strong>de</strong>n Markt.GNU-Projekt von RICHARD MATTHEW STALLMAN gegrün<strong>de</strong>t.Der IBM PC/AT mit Prozessor Intel 80 286 und MS-DOS 3.0kommen heraus.Siemens steigt <strong>in</strong> UNIX (S<strong>in</strong>ix) e<strong>in</strong>.Die Universität Karlsruhe wird Email-Relay für Deutschlandzum Computer Science Net (CSNet) <strong>in</strong> <strong>de</strong>n USA. Als erste Mailerhält Prof. ZORN, U. Karlsruhe, e<strong>in</strong>en Gruß vom CSNet.Entwicklung <strong>de</strong>s X W<strong>in</strong>dow Systems am MIT.1985 MS-W<strong>in</strong>dows 1.0, IBM 3090 und IBM Token R<strong>in</strong>g Netz.XL<strong>in</strong>k an <strong>de</strong>r Universität Karlsruhe stellt als erstes <strong>de</strong>utschesNetz e<strong>in</strong>e Verb<strong>in</strong>dung zum nordamerikanischen ARPANET her.Hewlett-Packard br<strong>in</strong>gt <strong>de</strong>n ersten Laserjet-Drucker heraus.1986 Weltweit etwa e<strong>in</strong>e halbe Million UNIX-Systeme und3000 öffentliche Datenbanken.Mit <strong>de</strong>m Computer-Investitionsprogramm <strong>de</strong>s Bun<strong>de</strong>s und <strong>de</strong>rLän<strong>de</strong>r (CIP) kommen mehrere HP 9000/550 unter UNIX an


373die Universität Karlsruhe.1987 Microsoft XENIX (e<strong>in</strong> UNIX) für <strong>de</strong>n IBM PC/ATIBM br<strong>in</strong>gt die PS/2-Reihe unter MS-OS/2 heraus.Weltweit mehr als 5 Millionen Apple Computer und etwa100 Millionen PCs nach Vorbild von IBM.Das MIT veröffentlicht das X W<strong>in</strong>dow System Version 11 (X11).In Berkeley wird die RAID-Technologie entwickelt.Beg<strong>in</strong>n <strong>de</strong>s ba<strong>de</strong>n-württembergischen BelWue-Netzes.1988 JARKKO OIKARINEN, F<strong>in</strong>nland, entwickelt <strong>de</strong>n IRC.Das Karlsruher Campusnetz KARLA wird durch das GlasfasernetzKLICK ersetzt. VBN-Strecke Karlsruhe - Stuttgart im BelWue-NetzFrankreich geht ans Internet (INRIA, Rocquencourt bei Paris).Gründung <strong>de</strong>r Open Software Foundation (OSF) und <strong>de</strong>r UNIXInternational Inc. MS-DOS 4.0 für PCs.E<strong>in</strong> Internet-Wurm namens Morris geht auf die Reise, daraufh<strong>in</strong> Gründung <strong>de</strong>s Computer Emergency Response Teams (CERT).Erster Hoax (2400-baud-Mo<strong>de</strong>m-Hoax) im Internet, siehe CIAC.Erstes landmobiles Satellitensystem für Datenfunk (Inmarsat-C).1989 Das NFSNET löst das ARPANET als Backbone <strong>de</strong>s Internet ab.UNIX System V Release 4 vere<strong>in</strong>heitlicht System V, BSD und XenixIm Rechenzentrum Karlsruhe löst die IBM 3090 dieSiemens 7881 ab. ISDN <strong>in</strong> Deutschland e<strong>in</strong>geführt.Erster <strong>de</strong>utscher Internet-Direktanschluss via Xl<strong>in</strong>k, Karlsruhe.1990 Zunehmen<strong>de</strong> Vernetzung, Anschluss an weltweite Netze.Die Internet Society (ISOC) schätzt das Internet auf 500.000 KnotenComputer-Kommunikation mittels E-Mail, Btx und Fax vomArbeitsplatz aus. Optische Speichermedien (CD-ROM, WORM).Das Web (URL, HTTP, HTML) von TIMOTHY BERNERS-LEE undROBERT CAILLIAU am CERN <strong>in</strong> Genf entwickelt.UNIX System V Version 4.Die mittlere Computerdichte <strong>in</strong> technisch orientierten Instituten unFamilien erreicht 1 pro Mitglied.1991 Das UNIX-System OSF/1 mit <strong>de</strong>m Mach-Kernel <strong>de</strong>r Carnegie-Mellon-Universität kommt heraus.17. Sep.: Anfang von LINUX (LINUS BENEDICT TORVALDS).Erster Web-Server <strong>in</strong> <strong>de</strong>n USA: Stanford L<strong>in</strong>ear Accelerator Center.MS-DOS 5.0 für PCs. Anfänge von Microsoft W<strong>in</strong>dows NT.Das DE-NIC an <strong>de</strong>r Universität Dortmund gegrün<strong>de</strong>t.IBM, Apple und Motorola kooperieren mit <strong>de</strong>m Ziel, e<strong>in</strong>enPower PC zu entwickeln.


374 ANHANG G. ZEITTAFEL1992 Die Universität Karlsruhe nimmt <strong>de</strong>n massiv parallelenComputer MasPar 1216A mit 16000 Prozessoren <strong>in</strong> Betrieb.Novell übernimmt von AT&T die UNIX-Aktivitäten (USL).FORTRAN 90 verabschie<strong>de</strong>t.E<strong>in</strong>e Million Knoten im Internet. Weltweit etwa 50 Web-Server.Erster <strong>de</strong>utscher Web-Server, am DESY <strong>in</strong> Hamburg.1993 MS-DOS Version 6.0. Microsoft kündigt W<strong>in</strong>dows-NT an.DEC stellt PC mit Alpha-Prozessor vor, 150 MHz, 14.000 DM.Novell tritt das Warenzeichen UNIX an die X/Open-Gruppe ab.MARC ANDREESSEN, NCSA, schreibt e<strong>in</strong>en Web-Browser für dasX W<strong>in</strong>dow System mit <strong>de</strong>r Möglichkeit, farbige Grafiken darzustellen.PATRICK VOLKERDING stellt die L<strong>in</strong>ux-Distribution Slackwarezusammen, die erste Distribution von e<strong>in</strong>iger Verbreitung.IAN MURDOCK, Stu<strong>de</strong>nt an <strong>de</strong>r Purdue University, stellt am 16. Augustdas Debian-Projekt vor. Gegen Jahresen<strong>de</strong> Debian GNU/L<strong>in</strong>ux Version 0Weltweit etwa 250 Web-Server.Das DE-NIC zieht ans Rechenzentrum <strong>de</strong>r Universität Karlsruhe.1994 Weltweit 10 Mio. <strong>in</strong>stallierte UNIX-Systeme prognostiziert.L<strong>in</strong>ux 1.0 veröffentlicht.Das Internet umfasst etwa 4 Mio. Knoten und 20 Mio. Benutzer.Erste Spam-Mail (Canter + Siegel). Erste Banner-Werbung (Wired).MARC ANDREESSEN und JIM CLARK grün<strong>de</strong>n die Firma Netscape.1995 Kommerzielle Netze lösen <strong>in</strong> <strong>de</strong>n USA das NFSNET als Backbone ab.Die X/Open-Gruppe führt die Bezeichnung UNIX 95 für Systemee<strong>in</strong>, die <strong>de</strong>r S<strong>in</strong>gle UNIX Specification genügen.Die Universität Karlsruhe ermöglicht <strong>in</strong> Zusammenarbeitmit <strong>de</strong>m Oberschulamt nordbadischen Schulen <strong>de</strong>n Zugang zumInternet. Ähnliche Projekte wer<strong>de</strong>n auch an e<strong>in</strong>igen an<strong>de</strong>renHoch- und Fachhochschulen durchgeführt.Die Programmiersprache JAVA wird von Sun veröffentlicht.Onl<strong>in</strong>e-Auktionshaus Ebay als Sammlerbörse <strong>in</strong> <strong>de</strong>n USA gegrün<strong>de</strong>t.Weltweit etwa 50000 Web-Server.1996 Die Massen und Medien ent<strong>de</strong>cken das Internet.Debian GNU/L<strong>in</strong>ux Version 1.1 (buzz) wird veröffentlicht, zumJahresen<strong>de</strong> folgt Version 1.2 (rex).FORTRAN 95, e<strong>in</strong>e revidierte Fassung von FORTRAN 90, fertig.Die Open Software Foundation (OSF) und X/Open schließen sich zurOpen Group zusammen.1997 100-Ethernet ist erschw<strong>in</strong>glich gewor<strong>de</strong>n, über das Gigabit-Ethernetwird gere<strong>de</strong>t. In Deutschland gibt es rund 20 Mio. PCs und


3751 Mio. Internetanschlüsse (Quelle: Fachverband InformationstechniDebian GNU/L<strong>in</strong>ux Version 1.3 (bo) freigegeben, rund 1000 Pakete.S<strong>in</strong>gle UNIX Specification Version 2 im Web veröffentlicht.HTML 4.0 freigegeben.Der Buchversen<strong>de</strong>r Amazon mel<strong>de</strong>t e<strong>in</strong> Patent an <strong>de</strong>rgestalt, dass mmit e<strong>in</strong>em Mausklick im Internet e<strong>in</strong>e Ware bestellt.1998 Compaq übernimmt die Digital Equipment Corporation (DEC).IBM br<strong>in</strong>gt DOS 2000 heraus, Microsoft kündigt W<strong>in</strong>dows 2000 an.Debian GNU/L<strong>in</strong>ux Version 2.0 (hamm) freigegeben, 1500 Pakete.KDE 1.0 veröffentlicht. 9-GB-Festplatten kosten 500 DM.Gigabit-Ethernet-Standard IEEE 802.3z verabschie<strong>de</strong>t.JONATHAN B. POSTEL, e<strong>in</strong>er <strong>de</strong>r Apostel <strong>de</strong>s Internet und Autorvieler RFCs, gestorben. Siehe RFC 2441: Work<strong>in</strong>g with Jon undRFC 2468: I Remember IANA.1999 Das Y2K-Problem – die Jahrtausendwen<strong>de</strong> – beschäftigt die Gemüteweil die Programmierer früherer Jahrzehnte mit <strong>de</strong>n Bits knauserteDer RFC 2550 löst auch gleich das Y10K-Problem.Debian GNU/L<strong>in</strong>ux Version 2.1 (sl<strong>in</strong>k) kommt heraus.Betreiber großer Suchmasch<strong>in</strong>en schätzen die Anzahl <strong>de</strong>rWeb-Seiten weltweit auf 1 Milliar<strong>de</strong>.LINUS B. TORVALDS wird Ehrendoktor <strong>de</strong>r Universität Stockholm.2000 Das Y2K-Problem hat sich praktisch nicht ausgewirkt.Den 29. Februar 2000 haben wir auch gut überstan<strong>de</strong>n, e<strong>in</strong>en Schaltnach e<strong>in</strong>er Regel, die nur alle 400 Jahre angewen<strong>de</strong>t wird.Debian GNU/L<strong>in</strong>ux Version 2.2 (potato) kommt heraus, 6500 PaketeMicrosoft W<strong>in</strong>dows 2000 ist erhältlich. E<strong>in</strong> Macro-Virus namensLove Letter sorgt für Aufregung – außerhalb <strong>de</strong>r L<strong>in</strong>ux/UNIX-Welt.Der Intel Pentium kommt bei e<strong>in</strong>er Taktfrequenz von 1,5 GHz an.Zum Jahresen<strong>de</strong> 2 Mio. Internet-Hosts <strong>in</strong> Deutschland (Quelle: RIPE2001 CLAUDE ELWOOD SHANNON gestorben, gilt als Erf<strong>in</strong><strong>de</strong>r <strong>de</strong>s Bitsund Begrün<strong>de</strong>r <strong>de</strong>r Informationstheorie.In <strong>de</strong>n USA starten JIMMY DONAL WALES und LAWRENCE MARK Se<strong>in</strong>e <strong>in</strong>ternationale Onl<strong>in</strong>e-Enzyklopädie auf <strong>de</strong>r Grundlage e<strong>in</strong>es W2002 Die E<strong>in</strong>führung <strong>de</strong>r Euro-Währung führt zu e<strong>in</strong>em neuen Zeichen<strong>in</strong> <strong>in</strong>ternationalen Zeichensätzen.Im Herbst befällt <strong>de</strong>r Wurm Slapper zahlreiche Webserver unter L<strong>in</strong>Debian GNU/L<strong>in</strong>ux Version 3.0 (woody) wird als stabil freigegeben.Die Distribution umfasst 8700 Pakete.2004 PCs wer<strong>de</strong>n zunehmend ohne Floppy-Laufwerk ausgeliefert.Politische Überlegungen, die Patentierung von Software zuzulassen,


376 ANHANG G. ZEITTAFELbedrohen die Open Source Welt.2005 Anfang Juni wird Debian GNU/L<strong>in</strong>ux Version 3.1 (sarge) nach reiflicherÜberlegung als stabil freigegeben und löst 3.0r6 (woody) ab;die Distribution umfasst rund 15.000 Pakete. Woody wird damitzur Old-stable-Version, etch rückt zur Test<strong>in</strong>g-Version auf.In Frankfurt (M) f<strong>in</strong><strong>de</strong>t die Wikimania 2005 statt, die erste <strong>in</strong>ternationaWikimedia-Konferenz.Die <strong>de</strong>utsche Wikipedia nähert sich <strong>de</strong>r Marke von 300.000 E<strong>in</strong>trägen.Internet-Telefonie (Voice over IP) ist stark im Kommen.Prof. KARL STEINBUCH gestorben.En<strong>de</strong> <strong>de</strong>s Jahres kommt X11R7 heraus.Der weltweit leistungsfähigste Rechner – e<strong>in</strong> IBM Blue Gene – läuftunter e<strong>in</strong>em L<strong>in</strong>ux (Quelle: http://www.top500.org/).2006 Die englische Wikipedia überschreitet die Marke von 1 Mio. E<strong>in</strong>trägen,die <strong>de</strong>utsche die 400.000, die französische die 300.000.Laut http://www.netcraft.com/ s<strong>in</strong>d die am häufigsten besuchten WGoogle, Yahoo, Microsoft, BBC, CNN, Ebay, Fox News, Amazon und WikiDas Deutsche Forschungsnetz nimmt das X-W<strong>in</strong> <strong>in</strong> Betrieb, e<strong>in</strong>e Netz<strong>in</strong>fmit Anschlüssen bis zu 10 Gigabit/s und 43 Kernstandorten.Mitte <strong>de</strong>s Jahres gibt es 10 Mio. E<strong>in</strong>träge unter <strong>de</strong>r Top Level Doma<strong>in</strong> .dsie ist damit weltweit nach .com die zweitumfangreichste.Debian stellt <strong>de</strong>n Sicherheitssupport für woody e<strong>in</strong> und erklärtzum Jahresen<strong>de</strong> die Version 4.0 (etch) mit Kern 2.6.17 als stabil.


HZum WeiterlesenDie Auswahl ist subjektiv und enthält Werke, die wir noch lesenwollen, schon gelesen haben o<strong>de</strong>r sogar oft benutzen.1. Lexika, Glossare, Wörterbücher– Newsgruppen:news.answers<strong>de</strong>.etc.listsnews.lists– RFC 1392 (FYI 18): Internet Users’ Glossaryftp://ftp.nic.<strong>de</strong>/pub/rfc/rfc1392.txt1993, 53 S.– Du<strong>de</strong>n InformatikDu<strong>de</strong>nverlag, Mannheim, 1993, 800 S.Nachschlagewerk, sorgfältig gemacht, theorielastig,Begriffe wie Ethernet, LAN, SQL, Internet fehlen.– Fachausdrücke <strong>de</strong>r Informationsverarbeitung Englisch –Deutsch,Deutsch – EnglischIBM Deutschland, Form-Nr. Q12-1044, 1698 S.Wörterbuch und Glossar– IBM Term<strong>in</strong>ologyhttp://www-3.ibm.com/ibm/term<strong>in</strong>ology/W. <strong>Alex</strong> Abkürzungs-Liste ABKLEX (Informatik, Telekommunikation)http://www.ciw.uni-karlsruhe.<strong>de</strong>/abklex.htmlhttp://www.ciw.uni-karlsruhe.<strong>de</strong>/abklex.pdfRund 9000 Abkürzungen aus Informatik und TelekommunikationM. Broy, O. Spaniol Lexikon Informatik und KommunikationstechnikSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1999, 863 S.377


378 ANHANG H. ZUM WEITERLESENE. Kajan Information Technology Encyclopedia andAcronymsSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2002, 720 S.E. S. Raymond The New Hacker’s DictionaryThe MIT Press, Cambridge, 1996, 547 S.Siehe auch http://www.ciw.uni-karlsruhe.<strong>de</strong>/kopien/jargonBegriffe aus <strong>de</strong>m Netz, die nicht im Du<strong>de</strong>n stehen2. Informatik– Newsgruppen:comp.* (alles, was mit Computer Science zu tun hat,mehrerehun<strong>de</strong>rt Untergruppen)<strong>de</strong>.comp.* (dito, <strong>de</strong>utschsprachig)alt.comp.*W. Coy Aufbau und Arbeitsweise von RechenanlagenVieweg, Braunschweig, 1992, 367 S.Digitale Schaltungen, Rechnerarchitektur, BetriebssystemeamBeispiel von UNIXT. Flik, H. Liebig MikroprozessortechnikSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1998, 585 S.CISC, RISC, Systemaufbau, Assembler und CW. K. Giloi RechnerarchitekturSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1999, 488 S.G. Goos Vorlesungen über InformatikBand 1: Grundlagen und funktionales Programmieren,Spr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1997, 394 S.Band 2: Objektorientiertes Programmieren und Algorithmen,Spr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1999, 396 S.Band 3: Berechenbarkeit, formale Sprachen, Spezifikationen,Spr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1997, 284 S.Band 4: Paralleles Rechnen und nicht-analytischeLösungsverfahren,Spr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1998, 292 S.i44www.<strong>in</strong>fo.uni-karlsruhe.<strong>de</strong>/˜i44www/goos-buch.html


379D. E. Knuth The Art of Computer Programm<strong>in</strong>g, 3 Bän<strong>de</strong>Addison-Wesley, Boston,Klassiker, stellenweise mathematisch, 7 Bän<strong>de</strong> geplant,Band 4 soll 2004 fertig se<strong>in</strong>, Band 5 im Jahr 2009,Homepage<strong>de</strong>s Meisters: www-cs-staff.stanford.edu/˜uno/<strong>in</strong><strong>de</strong>x.htmW. Schiffmann, R. Schmitz Technische InformatikSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1993/94, 1. Teil Grundlagen<strong>de</strong>rdigitalen Elektronik, 282 S.; 2. Teil Grundlagen <strong>de</strong>rComputertechnik, 283 S.K. W. Wagner E<strong>in</strong>führung <strong>in</strong> die Theoretische InformatikSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1994, 238 S.Grundlagen, Berechenbarkeit, Komplexität, BOO-LEscheFunktionen, Automaten, Grammatiken, FormaleSprachen3. Algorithmen, Numerische Mathematik– Newsgruppen:sci.math.*J. L. Bentley Programm<strong>in</strong>g PearlsAddison-Wesley, Boston, 1999, 256 S.Pfiffige Algorithmen und Programmieri<strong>de</strong>enG. Engeln-Müllges, F. Reutter Formelsammlung zurNumerischen Mathematik mit C-ProgrammenBI-Wissenschaftsverlag, Mannheim, 1990, 744 S.Algorithmen und Formeln <strong>de</strong>r Numerischen Mathematiksamt C-Programmen.G. Engeln-Müllges, F. Uhlig Numerical Algorithms withCSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1996, 596 S.D. E. Knuth Algorithmen(<strong>de</strong>utsche Übersetzung von Fundamental Algorithms)Spr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2004, 700 S.


380 ANHANG H. ZUM WEITERLESENK. Loudon Master<strong>in</strong>g Algorithms <strong>in</strong> CO’Reilly, Sebastopol, 1999, 560 S.T. Ottmann, P. Widmayer Algorithmen und DatenstrukturenBI-Wissenschafts-Verlag, Mannheim, 1993, 755 S.W. H. Press u. a. Numerical Recipes <strong>in</strong> CCambridge University Press, 1993, 994 S.H. R. Schwarz Numerische MathematikTeubner, Stuttgart, 1993, 575 S.R. Sedgewick Algorithmen <strong>in</strong> CAddison-Wesley, Bonn, 1992, 742 S.Erklärung gebräuchlicher Algorithmen und Umsetzung<strong>in</strong> CR. Sedgewick Algorithmen <strong>in</strong> <strong>C++</strong>Addison-Wesley, Bonn, 1992, 742 S.J. Stoer, R. Bulirsch Numerische MathematikSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1. Teil 1999, 378 S.,2. Teil 2000, 375 S.4. Betriebssysteme– Newsgruppen:comp.os.*<strong>de</strong>.comp.os.*L. Bic, A. C. Shaw BetriebssystemeHanser, München, 1990, 420 S.Allgeme<strong>in</strong>er als Tanenbaum + WoodhullA. S. Tanenbaum, A. S. Woodhull Operat<strong>in</strong>g Systems,Design and ImplementationPrentice-Hall, London, 1997, 939 S.E<strong>in</strong>führung <strong>in</strong> Betriebssysteme am Beispiel von UNIXA. S. Tanenbaum Mo<strong>de</strong>rn Operat<strong>in</strong>g SystemsPrentice-Hall, London, 1992, 728 S.Allgeme<strong>in</strong>er und mo<strong>de</strong>rner als vorstehen<strong>de</strong>s Buch;erläutert MS-DOS, UNIX, MACH und AmoebaA. S. Tanenbaum Distributed Operat<strong>in</strong>g SystemsPrentice-Hall, London, 1994, 648 S.


381H. Wettste<strong>in</strong> SystemarchitekturHanser, München, 1993, 514 S.Grundlagen, ke<strong>in</strong> bestimmtes Betriebssystem5. L<strong>in</strong>ux/UNIX allgeme<strong>in</strong>– Newsgruppen:comp.unix.*comp.sources.unixcomp.std.unix<strong>de</strong>.comp.os.unixalt.unix.wizardsM. J. Bach Design of the UNIX Operat<strong>in</strong>g SystemPrentice-Hall, London, 1987, 512 S.Dateisystem und Prozesse, wenig zur ShellS. R. Bourne Das UNIX System V (The UNIX V Environment)Addison-Wesley, Bonn, 1988, 464 S.E<strong>in</strong>führung <strong>in</strong> UNIX und die Bourne-ShellP. H. Ganten, W. <strong>Alex</strong> Debian GNU/L<strong>in</strong>uxSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2004, 970 S.E<strong>in</strong>richtung, Konfiguration und Betrieb von DebianGNU/L<strong>in</strong>uxJ. Gulb<strong>in</strong>s, K. Obermayr, Snoopy L<strong>in</strong>uxSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2003, 900 S.Benutzung von L<strong>in</strong>ux/UNIX, geht <strong>in</strong> E<strong>in</strong>zelheiten <strong>de</strong>rKommandosH. Hahn A Stu<strong>de</strong>nt’s Gui<strong>de</strong> to UNIXMcGraw-Hill, New York, 1993, 633 S.E<strong>in</strong>führen<strong>de</strong>s Lehrbuch, mit Internet-DienstenB. W. Kernighan, R. Pike Der UNIX-WerkzeugkastenHanser, München, 1986, 402 S.Gebrauch vieler UNIX-KommandosM. Kofler L<strong>in</strong>ux – Installation, Konfiguration, AnwendungAddison-Wesley, Bonn, 2000, 1108 S.5. Auflage, spricht für das Buch.D. G. Korn, M. I. Bolsky The Kornshell, Command andProgramm<strong>in</strong>g Language


382 ANHANG H. ZUM WEITERLESEN<strong>de</strong>utsch: Die KornShell, Hanser, München, 1991E<strong>in</strong>führung <strong>in</strong> UNIX und die Korn-ShellA. Robb<strong>in</strong>s UNIX <strong>in</strong> a NutshellO’Reilly, Sebastopol, 2000, 632 S.Nachschlagewerk zu <strong>de</strong>n meisten UNIX-Kommandos,im UNIX CD Bookshelf enthalten. Auch auf Englisch.M. J. Rochk<strong>in</strong>d Advanced UNIX Programm<strong>in</strong>gAddison-Wesley, Boston, 2004, 719 S.Beschreibung <strong>de</strong>r wichtigsten UNIX System CallsK. Rosen u. a. UNIX: The Complete ReferenceOsborne/McGraw-Hill, Berkeley, 1999, 1302 S.Fast würfelförmiges Nachschlagewerk, <strong>in</strong>sbeson<strong>de</strong>rezu L<strong>in</strong>ux, Solaris und HP-UX; breites ThemenspektrumE. Siever et al. LINUX <strong>in</strong> a NutshellO’Reilly, Sebastopol, 2001, 880 S.Nachschlagewerk zu <strong>de</strong>n meisten LINUX-KommandosW. R. Stevens Advanced Programm<strong>in</strong>g <strong>in</strong> the UNIX EnvironmentAddison-Wesley, Boston, 1992, 744 S.Ähnlich wie Rochk<strong>in</strong>d6. L<strong>in</strong>ux/UNIX VerwaltungÆ. Frisch Essential System Adm<strong>in</strong>istrationO’Reilly, Sebastopol, 1995, 760 S.Übersicht für Benutzer auf <strong>de</strong>m Weg zum Sysadm<strong>in</strong>.K. Heuer, R. Sippel UNIX-Systemadm<strong>in</strong>istrationSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2004, 800 S.E. Nemeth, G. Sny<strong>de</strong>r, S. Seebass, T. R. He<strong>in</strong> UNIXSystemAdm<strong>in</strong>istration HandbookPrentice-Hall, Englewood-Cliffs, 2001, 835 S.Auf <strong>de</strong>n neuesten Stand gebrachte Hilfe für Sysadm<strong>in</strong>s,viel Stoff.R. U. Rehman HP Certified – HP-UX System Adm<strong>in</strong>istration


383Prentice Hall PTR, Upper Saddle River, 2000, 800 S.Begleitbuch zu e<strong>in</strong>em Kurs, E<strong>in</strong>führung <strong>in</strong> und Verwaltungvon HP-UXM. Welsh, M. K. Dalheimer, L. Kaufmann Runn<strong>in</strong>g L<strong>in</strong>uxO’Reilly, Sebastopol, 1999, 750 S.E<strong>in</strong>richtung und Betrieb e<strong>in</strong>es LINUX-PCs7. L<strong>in</strong>ux/UNIX E<strong>in</strong>zelthemen– Newsgruppen:comp.unix.*A. V. Aho, B. W. Kernighan, P. J. We<strong>in</strong>berger TheAWKProgramm<strong>in</strong>g LanguageAddison-Wesley, Boston, 1988, 210 S.Standardwerk zum AWKD. Cameron, B. Rosenblatt Learn<strong>in</strong>g GNU EmacsO’Reilly, Sebastopol, 1991, 442 S.D. Dougherty, A. Robb<strong>in</strong>s sed & awkO’Reilly, Sebastopol, 1997, 407 S.H. Herold L<strong>in</strong>ux Unix Profitools: awk, sed, lex, yacc undmakeAddison-Wesley, München, 1998, 890 S.L. Lamb, A. Robb<strong>in</strong>s Textbearbeitung mit <strong>de</strong>m vi-EditorO’Reilly, Köln, 1999, 333 S.A. Oram, S. Talbott Manag<strong>in</strong>g Projects with makeO’Reilly, Sebastopol, 1993, 149 S.L. Wall, T. Christiansen, J. Orwant Programm<strong>in</strong>g PerlO’Reilly, Sebastopol, 2000, 1067 S.8. X W<strong>in</strong>dow System (X11), Motif, Gnome, KDE– Newsgruppen:comp.w<strong>in</strong>dows.x.*– OSF/Motif Users’s Gui<strong>de</strong>OSF/Motif Programmer’s Gui<strong>de</strong>


384 ANHANG H. ZUM WEITERLESENOSF/Motif Programmer’s ReferencePrentice-Hall, Englewood Cliffs, 1990F. Culw<strong>in</strong> An X/Motif Programmer’s PrimerPrentice-Hall, New York, 1994, 344 S.T. + M. K. Dalheimer KDE Anwendung und ProgrammierungO’Reilly, Sebastopol, 1999, 321 S.K. Gottheil u. a. X und MotifSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1992, 694 S.N. Mansfield The Joy of XAddison-Wesley, Boston, 1993, 368 S.Als E<strong>in</strong>stieg für Anwen<strong>de</strong>r geeignet.A. Nye XLib Programm<strong>in</strong>g ManualO’Reilly, Sebastopol, 1990, 635 S.E<strong>in</strong>führung <strong>in</strong> X11 und <strong>de</strong>n Gebrauch <strong>de</strong>r XLibV. Quercia, T. O’Reilly X W<strong>in</strong>dow System Users Gui<strong>de</strong>O’Reilly, Sebastopol, 1990, 749 S.E<strong>in</strong>führung <strong>in</strong> X11 für Anwen<strong>de</strong>rR. J. Rost X and Motif Quick Reference Gui<strong>de</strong>Digital Press, Bedford, 1993, 400 S.9. Textverarbeitung mit LaTeXK. Braune, J. Lammarsch, M. Lammarsch LaTeXSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2004, 700 S.M. K. Dalheimer LaTeX kurz & gutO’Reilly, Köln, 2000, 72 S.H. Kopka LaTeX, 3 Bän<strong>de</strong>Band 1: E<strong>in</strong>führungAddison-Wesley, Bonn, 2000, 520 S.Band 2: ErgänzungenAddison-Wesley, Bonn, 1997, 456 S.Band 3: ErweiterungenAddison-Wesley, Bonn, 1996, 512 S.Standardwerk im <strong>de</strong>utschen SprachraumL. Lamport Das LaTeX-HandbuchAddison-Wesley, Bonn, 1995, 360 S.


385H. Partl u. a. LaTeX-Kurzbeschreibungftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/latex/lkurftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/latex/lkur1990, 46 S., Postscript und LaTeX-QuellenE<strong>in</strong>führung, mit <strong>de</strong>utschsprachigen Beson<strong>de</strong>rheiten(Umlaute)10. Multimedia (Grafik, Sound)– Newsgruppen:comp.graphics.*alt.graphics.*J. D. Foley Computer Graphics – Pr<strong>in</strong>ciples and PracticeAddison-Wesley, Boston, 1992, 1200 S.Standardwerk zur Computer-Raster-GrafikR. F. Ferraro Programmer’s Gui<strong>de</strong> to the EGA and VGACardsAddison-Wesley, Boston, 1990, 1040 S.Viele Grundlagen, die über EGA und VGA h<strong>in</strong>ausgehenK. Kylan<strong>de</strong>r, O. S. Kylan<strong>de</strong>r GIMPMITP-Verlag, Bonn, 1999, 700 S.Benutzerhandbuch zum GNU Image ManipulationProgram11. Programmieren allgeme<strong>in</strong>– Newsgruppen:comp.programm<strong>in</strong>gcomp.unix.programmercomp.lang.*comp.software.*comp.software-engcomp.compilers<strong>de</strong>.comp.lang.*A. V. Aho u. a. Compilers, Pr<strong>in</strong>ciples, Techniques andToolsAddison-Wesley, Boston, 1986, 796 S.B. Beizer Software Test<strong>in</strong>g TechniquesVan Nostrand-Re<strong>in</strong>hold, 1990, 503 S.


386 ANHANG H. ZUM WEITERLESENF. P. Brooks jr. The Mythical Man-MonthAddison-Wesley, Boston, 1995, 322 S.Organisation großer Software-ProjekteM. K. Dalheimer L<strong>in</strong>ux – Wegweiser zu Programmierung+ EntwicklungO’Reilly, Sebastopol, 1997, 580 S.Software-Entwicklung unter LINUX, Werkzeugeftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/misc/pgui<strong>de</strong>.txN. Ford Programmer’s Gui<strong>de</strong>1989, 31 S., ASCIIallgeme<strong>in</strong>e Programmierh<strong>in</strong>weise, Shareware-KonzeptT. Grams Denkfallen und ProgrammierfehlerSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1990, 159 S.PASCAL-Beispiele, gelten aber auch für C-ProgrammeD. Gries The Science of Programm<strong>in</strong>gSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1981, 366 S.Grundsätzliches zu Programmen und ihrer Prüfung,mit praktischer Be<strong>de</strong>utung.R. H. Güt<strong>in</strong>g, M. Erwig ÜbersetzerbauSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1999, 368 S.M. Marcotty, H. Ledgard The World of Programm<strong>in</strong>gLanguagesSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1987, 360 S.S. Pfleeger Software Eng<strong>in</strong>eer<strong>in</strong>g: The Production of QualitySoftwareMacmillan, 1991, 480 S.I. W. Ricketts Manag<strong>in</strong>g Your Software Project –A Stu<strong>de</strong>nt’s Gui<strong>de</strong>Spr<strong>in</strong>ger, London, 1998, 103 S.Detaillierte Anweisung an Stu<strong>de</strong>nten zur Planung,Durchführungund Überwachung von Projekten.R. W. Sebesta Concepts of Programm<strong>in</strong>g LanguagesBenjam<strong>in</strong>/Cumm<strong>in</strong>gs, Redwood City, 1993, 560 S.


I. Sommerville Software Eng<strong>in</strong>eer<strong>in</strong>gAddison-Wesley, Boston, 1992, 688 S.Wie man e<strong>in</strong> Programmierprojekt organisiert;Werkzeuge, Metho<strong>de</strong>n; sprachenunabhängig387N. Wirth Systematisches ProgrammierenTeubner, Stuttgart, 1993, 160 S.Allgeme<strong>in</strong>e E<strong>in</strong>führung <strong>in</strong>s Programmieren, PASCALnahe12. Programmieren <strong>in</strong> C/<strong>C++</strong>/Objective C– Newsgruppen:comp.lang.ccomp.std.ccomp.lang.objectcomp.lang.c++comp.lang.objective-ccomp.std.c++<strong>de</strong>.comp.lang.c<strong>de</strong>.comp.lang.c++G. Booch Object-Oriented Analysis and Design with ApplicationsBenjam<strong>in</strong> + Cumm<strong>in</strong>gs, Redwood City, 1994, 590 S.U. Breymann Design<strong>in</strong>g Components with the <strong>C++</strong> STLAddison-Wesley, Boston, 2000, 320 S.B. J. Cox, A. J. Novobilski Object-Oriented Programm<strong>in</strong>gAddison-Wesley, Boston, 1991, 270 S.Objective CP. A. Darnell, P. E. Margolis C: A Software Eng<strong>in</strong>eer<strong>in</strong>gApproachSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1996, 500 S.H. M. Deitel, P. J. Deitel C How to ProgramPrentice Hall, Englewood Cliffs, 1994, 926 S.Enthält auch <strong>C++</strong>. Ausgeprägtes Lehrbuch.J. Hanly, E. Koffman Problem Solv<strong>in</strong>g and Program Design<strong>in</strong> CAddison-Wesley, Boston, 1999, 276 S.


388 ANHANG H. ZUM WEITERLESENJ. Hanly, E. Koffman C Program Design for Eng<strong>in</strong>eersAddison-Wesley, Boston, 2001, 679 S.S. P. Harbison, G. L. Steele C – A Reference ManualPrentice Hall, Englewood Cliffs, 1995, 470 S.Vielfach empfohlenes Nachschlagewerk, K+R und AN-SI/ISO.T. Jensen A Tutorial on Po<strong>in</strong>ters and Arrays <strong>in</strong> Chttp://www.netcom.com/ tjensen/ptr/po<strong>in</strong>ters.htmN. M. Josuttis The <strong>C++</strong> Standard Library – A Tutorialand ReferenceAddison-Wesley, Boston, 1999, 832 S.http://www.josuttis.<strong>de</strong>/libbook/B. W. Kernighan, D. M. Ritchie The C Programm<strong>in</strong>gLanguageDeutsche Übersetzung: Programmieren <strong>in</strong> CZweite Ausgabe, ANSI CHanser Verlag, München, 1990, 283 S.Standardwerk zur Programmiersprache C, LehrbuchR. Klatte u. a. C-XSCSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1993, 269 S.<strong>C++</strong>-Klassenbibliothek für wissenschaftliches RechnenA. Koenig Accelerated <strong>C++</strong>: Practical Programm<strong>in</strong>g byExampleAddison-Wesley, Boston, 2000, 352 S.S. Kuhl<strong>in</strong>s, M. Scha<strong>de</strong>r Die <strong>C++</strong>-StandardbibliothekSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2002, 421 S.E<strong>in</strong>führung <strong>in</strong> die <strong>C++</strong> Standard Library e<strong>in</strong>schl. <strong>de</strong>rSTLD. Lew<strong>in</strong>e POSIX Programmer’s Gui<strong>de</strong>O’Reilly, Sebastopol, 1991, 634 S.Mit Referenz <strong>de</strong>r ANSI-C- und <strong>de</strong>r POSIX-FunktionenD. Libes Obfuscated C and Other MysteriesWiley, New York, 1993, 413 S.S. Lippman, J. Lajoie <strong>C++</strong> PrimerAddison-Wesley, Boston, 3. Aufl. 1998, 1296 S.


389Verbreitetes Lehrbuch für Anfänger, enthält auchANSI-CN. Matthew, R. Stones Beg<strong>in</strong>n<strong>in</strong>g L<strong>in</strong>ux Programm<strong>in</strong>gWrox Press, Chicago, 1999, 950 S.N. Matthew, R. Stones Professional L<strong>in</strong>ux Programm<strong>in</strong>gWrox Press, Chicago, 2000, 1155 S.Betriebssystemnahe Fragen <strong>de</strong>r Programmierung <strong>in</strong>C/<strong>C++</strong>T. Misfeldt et al. The Elements of <strong>C++</strong> StyleCambridge University Press, 2004, 182 S.Regeln für gute <strong>C++</strong>-ProgrammeS. Ouall<strong>in</strong>e Practical C Programm<strong>in</strong>gO’Reilly, Sebastopol, 1997, 451 S.S. Ouall<strong>in</strong>e Practical <strong>C++</strong> Programm<strong>in</strong>gO’Reilly, Sebastopol, 1995, 581 S.P. J. Plauger, J. Brodie Referenzhandbuch Standard CVieweg, Braunschweig, 1990, 236 S.P. J. Plauger The Standard C LibraryPrentice-Hall, Englewood Cliffs, 1991, 498 S.Die Funktionen <strong>de</strong>r C-Standardbibliothek nach ANSIP. J. Plauger The Draft Standard <strong>C++</strong> LibraryPrentice-Hall, Englewood Cliffs, 1994, 590 S.Die Funktionen <strong>de</strong>r <strong>C++</strong>-Standardbibliothek nach AN-SIR. Robson Us<strong>in</strong>g the STLSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1998, 421 S.M. Scha<strong>de</strong>r, S. Kuhl<strong>in</strong>s Programmieren <strong>in</strong> <strong>C++</strong>Spr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1998, 386 S.Lehrbuch und Nachschlagewerk, mit ÜbungsaufgabenK. Schmaranz Softwareentwicklung <strong>in</strong> CSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2002, 400 S.K. Schmaranz Softwareentwicklung <strong>in</strong> <strong>C++</strong>Spr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2003, 570 S.B. Stroustrup The <strong>C++</strong> Programm<strong>in</strong>g Languagebzw. Die <strong>C++</strong> ProgrammierspracheAddison-Wesley, Boston/Bonn, 2000, 1024 S.Lehrbuch für Fortgeschrittene, <strong>de</strong>r Klassiker für <strong>C++</strong>


390 ANHANG H. ZUM WEITERLESEN13. Netze allgeme<strong>in</strong> (Internet, OSI)– Newsgruppen:comp.<strong>in</strong>fosystems.*comp.<strong>in</strong>ternet.*comp.protocols.*alt.best.of.<strong>in</strong>ternetalt.bbs.<strong>in</strong>ternetalt.<strong>in</strong>ternet.*<strong>de</strong>.comm.<strong>in</strong>ternet<strong>de</strong>.comp.<strong>in</strong>fosystems– EFF’s Gui<strong>de</strong> to the Internethttp://www.eff.org/pub/Publications/EFF\_Net\_Gui<strong>de</strong>/E<strong>in</strong>führung <strong>in</strong> die Dienste <strong>de</strong>s InternetS. Carl-Mitchell, J. S. Quarterman Practical Internetwork<strong>in</strong>gwith TCP/IP and UNIXAddison-Wesley, Boston, 1993, 432 S.D. E. Comer Internetwork<strong>in</strong>g with TCP/IP (4 Bän<strong>de</strong>)Prentice-Hall, Englewood Cliffs, I. Band 1991, 550 S.II. Band 1991, 530 S., 88 DM; IIIa. Band (BSD) 1993,500 S.IIIb. Band (AT&T) 1994, 510 S.Pr<strong>in</strong>zipien, Protokolle und Architektur <strong>de</strong>s InternetH. Hahn, R. Stout The Internet Complete ReferenceOsborne MacGraw-Hill, Berkeley, 1994, 818 S.Das Netz und se<strong>in</strong>e Dienste von Mail bis WWW; Lehrbuchund Nachschlagewerk für Benutzer <strong>de</strong>s InternetC. Hunt TCP/IP Netzwerk-Adm<strong>in</strong>istrationO’Reilly, Sebastopol, 1998, 632 S.B. P. Kehoe Zen and the Art of the Internetftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/net/general/ze1992, 100 S., PostscriptE<strong>in</strong>führung <strong>in</strong> die Dienste <strong>de</strong>s InternetO. Kirch, T. Dawson L<strong>in</strong>ux Network Adm<strong>in</strong>istrator’sGui<strong>de</strong>O’Reilly, Sebastopol, 2000, 500 S.


391E. Krol The Hitchhikers Gui<strong>de</strong> to the Internetftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/net/genera1987, 16 S., ASCIIErklärung e<strong>in</strong>iger Begriffe aus <strong>de</strong>m InternetE. Krol The Whole InternetO’Reilly, Sebastopol, 1992, 376 S.J. F. Kurose, K. W. Ross Computer Network<strong>in</strong>gAddison-Wesley, Boston, 2003, 784 S.M. Scheller u. a. Internet: Werkzeuge und DiensteSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1994, 280 S.http://www.ask.uni-karlsruhe.<strong>de</strong>/books/<strong>in</strong>etwd.htmlA. S. Tanenbaum Computer NetworksPrentice-Hall, London, 1996, 848 S.E<strong>in</strong>führung <strong>in</strong> Netze mit Schwerpunkt auf <strong>de</strong>m OSI-Mo<strong>de</strong>ll14. Netzdienste E<strong>in</strong>zelthemen– Newsgruppen:comp.theory.<strong>in</strong>fo-retrievalcomp.databases.*P. Albitz, C. Liu DNS and BINDO’Reilly, Sebastopol, 1998, 482 S.Internet-Adressen und -Namen, Name-ServerB. Costales, E. Allman sendmailO’Reilly, Sebastopol, 1997, 1021 S.Das wichtigste netzseitige Email-Programm (MTA)ausführlichdargestellt, ke<strong>in</strong>e leichte Kost, aber unentbehrlichJ. E. Hellbusch Barrierefreies Web<strong>de</strong>signKnowWare, www.knowware.<strong>de</strong>/, 2001, 86 S.H<strong>in</strong>weise zur Gestaltung von Webseiten, kompakt undverständlichP. J. Lynch, S. Horton Web Style Gui<strong>de</strong>Yale University Press, New Haven, 1999, 165 S.Gestaltung und Organisation von Webseiten, wenigTechnik


392 ANHANG H. ZUM WEITERLESENC. Me<strong>in</strong>el, H. Sack WWWSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2004, 1200 S.Internet-Grundlagen, HTTP, HTML, CSS, XML, CGIS. Münz, W. Nefzger HTML 4.0 HandbuchFranzis, München, 1999, 992 S.Deutsches Standardwerk zum Schreiben von Webseiten,abgewan<strong>de</strong>lt auch unter <strong>de</strong>m Titel Selfhtml anmehreren Stellen im Netz verfügbar.J. Nie<strong>de</strong>rst Web Design <strong>in</strong> a NutshellO’Reilly, Sebastopol, 1999, 560 S.Das gesamte Web zum Nachschlagen, viel TechnikA. Schwartz Manag<strong>in</strong>g Mail<strong>in</strong>g ListsO’Reilly, Sebastopol, 1998, 320 S.Majordomo, Listserv, List Processor und SmartlistS. Spa<strong>in</strong>hour, R. Eckste<strong>in</strong> Webmaster <strong>in</strong> a NutshellO’Reilly, Sebastopol, 1999, 523 S.HTML, CSS, XML, JavaScript, CGI und Perl, PHP,HTTP, ApacheW. R. Stevens UNIX Network Programm<strong>in</strong>gVol. 1: Network<strong>in</strong>g APIs: Sockets and XTIPrentice Hall, Englewood Cliffs, 1998, 1009 S.Vol. 2: Interprocess CommunicationPrentice Hall, Englewood Cliffs, 1999, 592 S.C-Programme für Clients und Server <strong>de</strong>r Netzdienste15. Sicherheit– Newsgruppen:comp.security.*comp.virussci.cryptalt.security.*alt.comp.virus<strong>de</strong>.comp.security– RFC 1244 (FYI 8): Site Security Handbookftp://ftp.nic.<strong>de</strong>/pub/rfc/rfc1244.txt1991, 101 S., ASCIISicherheits-Ratgeber für Internet-Benutzer


393– Department of Defense Trusted Computer SystemsEvaluation Criteria (Orange Book)ftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/net/secur/1985, 120 S., ASCII. Abgelöst durch:Fe<strong>de</strong>ral Criteria for Information Technology Securityftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/net/secur/ftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/net/secur/1992, 2 Bän<strong>de</strong> mit zusammen 500 S., PostscriptDie amtlichen amerikanischen Sicherheitsvorschriften– L<strong>in</strong>ux Hacker’s Gui<strong>de</strong>Markt + Technik, München, 1999, 816 S.F. L. Bauer KryptologieSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1994, 369 S.R. L. Brand Cop<strong>in</strong>g with the Threat of Computer SecurityInci<strong>de</strong>ntsA Primer from Prevention through Recoveryftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/net/secur/1990, 44 S., PostscriptD. A. Curry Improv<strong>in</strong>g the Security of Your UNIX Systemftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/net/secur/1990, 50 S., PostscriptHilfe für UNIX-System-Verwalter, mit ChecklisteS. Garf<strong>in</strong>kel, G. Spafford Practical Unix + Internet SecurityO’Reilly, Sebastopol, 1996, 971 S.Breit angelegte, verständliche E<strong>in</strong>führung <strong>in</strong> SicherheitsthemenB. Schneier Angewandte KryptographieAddison-Wesley, Bonn, 1996, 844 S.M. Schumacher, U. Roedig, M.-L. Moschgath HackerContestSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2003, 300 S.16. Computerrecht– Newsgruppen:comp.society.privacycomp.privacy


394 ANHANG H. ZUM WEITERLESENcomp.patentsalt.privacy<strong>de</strong>.soc.recht<strong>de</strong>.soc.datenschutz– World Intellectual Property Organization (WIPO)http://www/wipo.<strong>in</strong>t/– Juristisches Internetprojekt Saarbrückenhttp://www.jura.uni-sb.<strong>de</strong>/– Netlaw Library (Universität Münster)http://www.jura.uni-muenster.<strong>de</strong>/netlaw/– Onl<strong>in</strong>e-Recht http://www.onl<strong>in</strong>e-recht.<strong>de</strong>/– Computerrecht (Beck-Texte)Beck, München, 1994U. Dammann, S. Simitis Bun<strong>de</strong>sdatenschutzgesetzNomos Verlag, Ba<strong>de</strong>n-Ba<strong>de</strong>n, 1993, 606 S.BDSG mit Lan<strong>de</strong>sdatenschutzgesetzen und InternationalenVorschriften; Texte, ke<strong>in</strong> KommentarG. v. Gravenreuth Computerrecht von A – Z (BeckRechtsberater)Beck, München, 1992H. Hubmann, M. Rehb<strong>in</strong><strong>de</strong>r Urheber- und VerlagsrechtBeck, München, 1991, 319 S.A. Junker Computerrecht. Gewerblicher Rechtsschutz,Mängelhaftung, Arbeitsrecht. Reihe Recht und PraxisNomos Verlag, Ba<strong>de</strong>n-Ba<strong>de</strong>n, 1988, 267 S.F. Koch Handbuch Software- und Datenbank-RechtSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2003, 1000 S.D. Kröger, M. A. Gimmy Handbuch zum InternetrechtSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2. Auflage 2002, 1000 S.17. Geschichte <strong>de</strong>r Informatik– Newsgruppen:comp.society.folklorealt.folklore.computers<strong>de</strong>.alt.folklore.computer


– Kle<strong>in</strong>e Chronik <strong>de</strong>r IBM Deutschland1910 – 1979, Form-Nr. D12-0017, 138 S.1980 – 1991, Form-Nr. D12-0046, 82 S.Reihe: Über das Unternehmen, IBM Deutschland395– Die Geschichte <strong>de</strong>r masch<strong>in</strong>ellen DatenverarbeitungBand 1Reihe: Enzyklopädie <strong>de</strong>r InformationsverarbeitungIBM Deutschland, 228 S., Form-Nr. D12-0028– 100 Jahre Datenverarbeitung Band 2Reihe: Über die InformationsverarbeitungIBM Deutschland, 262 S., Form-Nr. D12-0040– Open SourceO’Reilly, Köln, 1999, 70 S.P. E. Ceruzzi A History of Mo<strong>de</strong>rn Comput<strong>in</strong>gMIT Press, Cambridge/USA, 1998, 400 S.Computergeschichte seit 1945 aus nordamerikanischerSichtO. A. W. Dilke Mathematik, Maße und Gewichte <strong>in</strong><strong>de</strong>r Antike (Universalbibliothek Nr. 8687 [2])Reclam, Stuttgart, 1991, 135 S.M. Hauben, R. Hauben Netizens – On the History andImpact of Usenet and the InternetIEEE Computer Society Press, Los Alamitos, 1997, 345S.www.columbia.edu/˜hauben/netbook/A. Hodges Alan Tur<strong>in</strong>g, EnigmaKammerer & Unverzagt, Berl<strong>in</strong>, 1989, 680 S.D. M. Lehmann Der EDV-Pionier Nikolaus Joachim LehmannDr. Hänsel-Hohenhausen, Frankfurt (M), 2002,S. Levy Hackers – Heroes of the Computer RevolutionPengu<strong>in</strong> Books, London, 1994, 455 S.R. Oberliesen Information, Daten und SignaleDeutsches Museum, rororo Sachbuch Nr. 7709 (vergriffen)D. Shasha, C. Lazere Out of Their M<strong>in</strong>ds


396 ANHANG H. ZUM WEITERLESENSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1995, 295 S.Biografien berühmter ComputerpioniereD. Siefkes u. a. Pioniere <strong>de</strong>r InformatikSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1998, 160 S.Interviews mit fünf europäischen ComputerpionierenB. Sterl<strong>in</strong>g A short history of the Internetftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/history/orig<strong>in</strong>1993, 6 S., ASCIIK. Zuse Der Computer - Me<strong>in</strong> LebenswerkSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 3. Aufl. 1993, 220 S.Autobiografie Konrad Zuses18. Allgeme<strong>in</strong>wissen und Philosophie– Newsgruppen:comp.ai.philosophysci.philosophy.techalt.fan.hofstadterE. Dyson Release 2.1 – A Design for Liv<strong>in</strong>g <strong>in</strong> the DigitalAgePetersen, Hamburg, 2000, 370 S.D. R. Hofstadter Gö<strong>de</strong>l, Escher, Bach - e<strong>in</strong> EndlosesGeflochtenes Banddtv/Klett-Cotta, München, 1992, 844 S.J. Ladd Computer, Informationen und Verantwortung<strong>in</strong>: Wissenschaft und Ethik, herausgegeben von H.LenkReclam-Band 8698, Ph. Reclam, StuttgartH. Lenk Chancen und Probleme <strong>de</strong>r Mikroelektronik,und:Können Informationssysteme moralisch verantwortlichse<strong>in</strong>?<strong>in</strong>: Hans Lenk, Macht und Machbarkeit <strong>de</strong>r TechnikReclam-Band 8989, Ph. Reclam, Stuttgart, 1994, 152S.P. Schefe u. a. Informatik und PhilosophieBI Wissenschaftsverlag, Mannheim, 1993, 326 S.18 Aufsätze verschie<strong>de</strong>ner Themen und Me<strong>in</strong>ungen


K. Ste<strong>in</strong>buch Die <strong>de</strong>s<strong>in</strong>formierte GesellschaftBusse + Seewald, Herford, 1989, 269 S. (vergriffen)397J. Weizenbaum Die Macht <strong>de</strong>r Computer und die Ohnmacht<strong>de</strong>r Vernunft (Computer Power and Human Reason.From Judgement to Calculation)Suhrkamp Taschenbuch Wissenschaft 274, Frankfurt(Ma<strong>in</strong>),1990, 369 S.H. Zemanek Das geistige Umfeld <strong>de</strong>r InformationstechnikSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1992, 303 S.Zehn Vorlesungen über Technik, Geschichte und Philosophie<strong>de</strong>s Computers, von e<strong>in</strong>em <strong>de</strong>r Pioniere19. Zeitschriften– c’tVerlag He<strong>in</strong>z Heise, Hannover, vierzehntägig,für alle Fragen <strong>de</strong>r Computerei, technisch.http://www.ix.<strong>de</strong>/– IXVerlag He<strong>in</strong>z Heise, Hannover, monatlich,für Anwen<strong>de</strong>r von Multi-User-Systemen, technisch.http://www.ix.<strong>de</strong>/– The C/<strong>C++</strong> Users JournalMiller Freeman Inc., USA, monatlich,http://www.cuj.com/– Dr. Dobb’s JournalMiller Freeman Inc., USA, monatlich,http://www.ddj.com/Software Tools for the Professional Programmer; vielC und <strong>C++</strong>Und noch e<strong>in</strong>ige Verlage:• Addison-Wesley, Bonn,http://www.addison-wesley.<strong>de</strong>/


398 ANHANG H. ZUM WEITERLESEN• Addison Wesley Longman, USA,http://www.awl.com/• Computer- und Literaturverlag, Vaterstetten,http://www.cul.<strong>de</strong>/• Carl Hanser Verlag, München,http://www.hanser.<strong>de</strong>/• Verlag He<strong>in</strong>z Heise, Hannover,http://www.heise.<strong>de</strong>/• International Thomson Publish<strong>in</strong>g, Stamford,http://www.thomson.com/• Klett-Verlag, Stuttgart,http://www.klett.<strong>de</strong>/• MITP-Verlag, Bonn,http://www.mitp.<strong>de</strong>/• R. Ol<strong>de</strong>nbourg Verlag, München,http://www.ol<strong>de</strong>nbourg.<strong>de</strong>/• O’Reilly, Deutschland,http://www.ora.<strong>de</strong>/• O’Reilly, Frankreich,http://www.editions-oreilly.fr/• O’Reilly, USA,http://www.ora.com/• Osborne McGraw-Hill, USA,http://www.osborne.com/• Prentice-Hall, USA,http://www.prenhall.com/• Sams Publish<strong>in</strong>g (Macmillan Computer Publish<strong>in</strong>g), USA,http://www.mcp.com/• Spr<strong>in</strong>ger-Verlag, Berl<strong>in</strong>, Hei<strong>de</strong>lberg, New York usw.,http://www.spr<strong>in</strong>ger.<strong>de</strong>/• Wrox Press, Chicago, Birm<strong>in</strong>gham, Paris,http://www.wrox.com/


Und über allem, me<strong>in</strong> Sohn, laß dich warnen;<strong>de</strong>nn <strong>de</strong>s vielen Büchermachens ist ke<strong>in</strong> En<strong>de</strong>,und viel Studieren macht <strong>de</strong>n Leib mü<strong>de</strong>.Prediger 12, 12399


400 ANHANG H. ZUM WEITERLESEN


PersonenverzeichnisAiken, H. 365Andreessen, M. 374Atanasoff, J. V. 365Babbage, C. 365Backus, J. 78Bar<strong>de</strong>en, J. 365Berners-Lee, T. 365Berry, C. 365Boole, G. 365Bratta<strong>in</strong>, W. H. 365Brickl<strong>in</strong>, D. 365Cailliau, R. 365Cerf, V. G. 371Codd, E. F. 371Crocker, S. 365Diffie, W. 371Eckert, J. P. 365Engelbart, D. C. 365Fibonacci 365Frankston, B. 365Gibson, W. 365Heilig, M. 365Hellmann, M. E. 371Hewlett, W. 365Hollerith, H. 365Hopper, G. 365Hopper, G. M. 12Jacquard, J. M. 365Jobs, S. P. 371Kahn, R. E. 371Kemeny, J. 13Kernighan, B. 14, 26Kernighan, B. W. 381Kilby, J. St. C. 365Knuth, D. E. 365, 379Kurtz, T. 13Lamport, L. 384Leibniz, G. W. 365Lickli<strong>de</strong>r, J. C. R. 365L<strong>in</strong>k, E. 365Mauchly, J. W. 365Metcalfe, R. 365Mill, H. 365M<strong>in</strong>sky, M. L. 365Morse, S. F. B. 365Murdock, I. 374Napier, J. 365Nassi, I. 29Naur, P. 78Nelson, T. 365Neumann, J. von 365Nickel, K. 368–370Oikar<strong>in</strong>en, J. 373Packard, D. 365Pascal, B. 365Pisa, L. von 365Plauger, P. J. 26Postel, J. B. 365Poulsen, W. 365Reis, J. P. 365Rem<strong>in</strong>gton, E. 365Ritchie, D. 14Sanger, L. M. 375401


402 PERSONENVERZEICHNISSchickard, W. 365Shannon, C. E. 365, 375Shnei<strong>de</strong>rman, B. 29Shockley, W. B. 365Shugart, A. 371Stallman, R. M. 365Ste<strong>in</strong>buch, K. 365, 376, 397Stroustrup, B. 15, 365, 389Sutherland, I. E. 365Tanenbaum, A. S. 380, 391Thompson, K. 14Tichy, W. F. 48Torvalds, L. B. 365Tur<strong>in</strong>g, A. 365Volkerd<strong>in</strong>g, P. 374Wales, J. D. 375Weiss<strong>in</strong>ger, J. 365Wirth, N. 13, 387Wozniak, S. G. 371Zemanek, H. 397Zuse, K. 365, 396


Sachverzeichnis/lib/libc.a 171/usr/<strong>in</strong>clu<strong>de</strong>/limits.h83/usr/lib/libcurses.a 176#<strong>de</strong>f<strong>in</strong>e 213, 327#if<strong>de</strong>f 218#ifn<strong>de</strong>f 218#<strong>in</strong>clu<strong>de</strong> 215, 327#un<strong>de</strong>f 215$? 132$Hea<strong>de</strong>r$ (RCS) 49$Id$ (RCS) 49$Log$ (RCS) 49& (C) 110&& (C) 11064-Bit-Masch<strong>in</strong>e 85a.out 33, 74Abstrakter Datentyp 181access 64action (HTML) 272Adaptor 193adb 40adm<strong>in</strong> 55Adresskonstante 97Adressübergabe 138ALGOL 13, 282Algorithmus 289Alias-Anweisung(FORTRAN) 62Allgeme<strong>in</strong>heit 289ANSI-C 14AnweisungAlias-A. (FORTRAN) 62C-A. 122, 226Compiler-A. 62, 146<strong>de</strong>f<strong>in</strong>e-A. 213<strong>in</strong>clu<strong>de</strong>-A. 215Kontrollanweisung 123leere A. (C) 122Präprozessor-A. 213ar 44ar(1) 178Archiv (Datei) 43, 169argc 151argc 63Argumentvektor 151Argumentzähler 151argv 151argv 63ArrayA. of characters 90A. von Funktionspo<strong>in</strong>tern137, 251Array 90In<strong>de</strong>x 90l<strong>in</strong>earisieren 90mehrdimensionales A. 90Name 90Subarray 197ASCIIGerman-ASCII 305Steuerzeichen 305Zeichensatz 291Assembler 5, 10, 11, 19, 161Assoziativität 121AusdruckAusdruck (C) 108ausführbar 19Ausgabe 116, 202Ausgang (Schleife) 125Auswahl (C) 124403


404 SACHVERZEICHNISauto (C) 105Backus-Naur-Form 78BASIC 13BCD-System 291Beautifier 35Bed<strong>in</strong>gte Bewertung 113Bed<strong>in</strong>gte Kompilation 218Bed<strong>in</strong>gung (C) 124Bezug 143Bibliothek 43, 169b<strong>in</strong>är-kompatibel 19B<strong>in</strong>ary 19B<strong>in</strong>dung, dynamische 20B<strong>in</strong>dung, statische 20Block 226Botschaft (<strong>C++</strong>) 181Bottom-up-Entwurf 27break (C) 124, 129Bubblesort 48Buil<strong>de</strong>r 35CC 14<strong>C++</strong> 8, 15Obfuscated C. 278Objective C 16<strong>C++</strong> 8, 15C-XSC 17, 195C9X 14calloc(3) 258case (C) 124cast-Operator 119cb 22, 35, 75cc 19, 33CC 19ccom 19c<strong>de</strong>cl 84cflow 46, 75Chaos Computer Club 365char (C) 87chatr 69chmod 75ci (RCS) 49close 64, 116co (RCS) 49COBOL 12Codierung (Programm) 17, 23Common Gateway Interface271compact (Speichermo<strong>de</strong>ll)178Compiler 4, 18, 32Compiler-Treiber 19Compilerbau 7compress(1) 223Computer Ai<strong>de</strong>d SoftwareEng<strong>in</strong>eer<strong>in</strong>g 56Concurrent Versions System55Configuration Management56configure (make) 38const (C) 83Constructor 182Conta<strong>in</strong>er 193cont<strong>in</strong>ue (C) 127, 129Contra vermes 41core 74creat 75Cross-Compiler 19ctime 61curses(3) 176, 233curses.h 176, 233cxref 47, 75DateiDatei 226Deskriptor 116Inclu<strong>de</strong>-D. 215, 326Kennung 19


SACHVERZEICHNIS 405Mo<strong>de</strong> 69mtime 35Po<strong>in</strong>ter 117Strukturtyp 92System 280Datenaustausch 28Datenstruktur 28, 82Debuggerabsoluter D. 40symbolischer D. 40<strong>de</strong>fault (C) 124Def<strong>in</strong>ition 82Deklaration 82<strong>de</strong>krementieren 109, 115<strong>de</strong>lta 55<strong>de</strong>referenzieren 96, 115DIN 66230 222Disassembler 20do-while-Schleife (C) 126Dokumentation 221Dotprecision 199double (C) 86Doxygen 223Dualsystem 291dynamische B<strong>in</strong>dung 20dynamischeSpeicherverwaltung258Editoremacs(1) 32nedit(1) 32vi(1) 32E<strong>in</strong><strong>de</strong>utigkeit 289E<strong>in</strong>gabe 116, 202E<strong>in</strong>gang (Schleife) 125Endlichkeit 289Entscheidbarkeit 290enum (C) 94envp 63etch 376Euro 375exit(2) 129Exponent 86Exten<strong>de</strong>d ScientificComput<strong>in</strong>g 195extern (C) 105, 106, 280f77 33f90 33fclose 117fcntl.h 64FehlerDenkfehler 40Fehlerfreiheit 21, 230Fehlermeldung 39Grammatik-F. 39Laufzeit-F. 39logischer F. 40Mo<strong>de</strong>ll-F. 40semantischer F. 40Syntax-F. 39Zaunpfahl-F. 129Flag (Variable) 264float (C) 86Flussdiagramm 29fopen 117for-Schleife (C) 127fork 69FORM-Element 272Formatstr<strong>in</strong>g 157FORTRAN 11, 81Fortsetzungszeile (C) 76fpr<strong>in</strong>tf 75fputs 117free(3) 258Freiburger Co<strong>de</strong> 11FunktionStr<strong>in</strong>gfunktion 172Funktion (C)


406 SACHVERZEICHNISArray vonFunktionspo<strong>in</strong>tern 137Bibliothek 43, 169Def<strong>in</strong>ition 136E<strong>in</strong>sprungadresse 97Funktion 136, 226grafische F. 176Input/Output-F. 172mathematische F. 174Po<strong>in</strong>ter auf F. 137Prototyp 136Speicherklasse 105Standardfunktion 57, 171,321virtuelle F. 184Xlib-F. 265gcc 34gdb 40Geltungsbereich 106get 55get (HTML) 272gets(3) 172getut 76Gleichung 108gmtime 59gnats 56GNU-Projekt 38GNU Free DocumentationLicense 354GNU General Public License345goto (C) 129gprof 42Grafik 251gzip(1) 223HASKELL 8Hexa<strong>de</strong>zimalsystem 291HP SoftBench 56huge (Speichermo<strong>de</strong>ll) 179IEEE Std 1063-1987 222if (C) 124if - else (C) 124Inclu<strong>de</strong>-Datei 215<strong>in</strong>fo(1) 225Initialisierung 82, 280<strong>in</strong>krementieren 109, 115Ino<strong>de</strong>Informationen aus <strong>de</strong>r I.64INRIA 373<strong>in</strong>t (C) 85Interface (Sprachen) 63Internet 174Interpreter 18ISO/IEC 14882 15ISO/IEC 9899 14Iteration 157Iterator 193JAVA 8, 17K&R-C 14KarlsruheBeg<strong>in</strong>n <strong>de</strong>r Informatik <strong>in</strong>K. 365Informatikstudium <strong>in</strong> K.365Rechenzentrum <strong>de</strong>rUniversität K. 365ZUSE Z 22 365Karlsruher Test 329Klammer (C) 120Klasse (<strong>C++</strong>) 181Klasse, abstrakte 184Komma-Operator 119, 127,128Kommandozeile 151KommentarC 76, 78, 213, 222, 227<strong>C++</strong> 80, 180


SACHVERZEICHNIS 407make 35KonstanteKonstante 76Literal 83symbolische K. 83, 213Kontrollanweisung 123Kreuzreferenz 47l-Wert 108Label (C) 129Langzahl-Arithmetik 200large (Speichermo<strong>de</strong>ll) 179ld 33LebensdauerOperand 82, 105, 107libQt 205l<strong>in</strong>ken (Programme) 33, 169L<strong>in</strong>ker 6, 19l<strong>in</strong>t 34, 72LISP 8Literal 76long (C) 85long double (C) 86ls 75lseek 64magic 64magic.h 64Magic Number 64ma<strong>in</strong>() 226ma<strong>in</strong>() 63, 151, 152make 35, 74make(1) 255Makefile 35MakroC 137, 214make 35malloc(3) 258man(1) 223man-Seite 223MANPATH 223Mantisse 86Masch<strong>in</strong>enco<strong>de</strong> 18, 19Masch<strong>in</strong>ensprache 5Masch<strong>in</strong>enwort 85, 93math.h 174medium (Speichermo<strong>de</strong>ll)178Member Access Specifier 182Meta Object Compiler 206method (HTML) 272Metho<strong>de</strong> (<strong>C++</strong>) 181M<strong>in</strong>us, unäres 279mknod 69moc 206Modul 33MODULA 13Modulus 109, 237monitor 43Motif 177NAG-Bibliothek 177NameName (C) 76, 80, 280Operan<strong>de</strong>n-N. 82Programm-N. 225Nassi-Shnei<strong>de</strong>rman-Diagramm29Nebenwirkung 131Negation 279Newton-Verfahren 203nm 75nroff(1) 223NULL 97, 243Nullpo<strong>in</strong>ter 97, 238, 243, 280Obfuscated C 278Objective C 16Objekt (<strong>C++</strong>) 181Objekt (Variable) 82Objektco<strong>de</strong> 5, 19


408 SACHVERZEICHNISOktalsystem 291open 64, 116open(2) 172Operand 82Operationarithmetische O. 109Bit-O. 114, 280Grund-O. 27logische O. 110Modulo-O. 85Po<strong>in</strong>ter-O. 115Relations-O. 112zulässige O. 83Operator (Zeichen) 76, 108,320Optimierung 230Parameteraktueller P. 137formaler P. 137Übergabe 137PASCAL 13Patch 21pc 33Pflichtenheft 25Platzhalter 137Po<strong>in</strong>terdangl<strong>in</strong>g P. 243Darstellung 280far P. 179huge P. 179near P. 179Nullpo<strong>in</strong>ter 97, 243, 280P.-Arithmetik 97P. auf Funktion 137, 251P. auf void 89, 243Po<strong>in</strong>ter 82, 94, 115, 242portieren 280POSIX 57post (HTML) 272Präprozessor 4, 19, 76Präprozessor (C) 213, 327Primzahl 210, 246pr<strong>in</strong>tf 117, 121pr<strong>in</strong>tf(3) 172, 326Private Member 182Problem Management 56prof 43Profiler 41ProgrammAufgabenstellung 23, 25benutzerfreundliches P. 22Bottom-up-Entwurf 27Codierung 17, 23, 26Dokumentation 221Effizienz 22Entwurf 23fehlerfreies P. 21Grund-Operation 27Hauptprogramm 226P. än<strong>de</strong>rn 21Patch 21Pflege 23Programm 226programmiererfreundlichesP.22Prototyp 28robustes P. 21Struktur 26, 28Test 23Top-down-Entwurf 26Version 21ProgrammierspracheALGOL 13algorithmische P. 8Assembler 10, 11BASIC 13C 14<strong>C++</strong> 8, 15


SACHVERZEICHNIS 409COBOL 12<strong>de</strong>klarative P. 8FORTRAN 11Freiburger Co<strong>de</strong> 11funktionale P. 8HASKELL 8imperative P. 8JAVA 8LISP 8logische P. 8masch<strong>in</strong>enorientierte P.10Masch<strong>in</strong>ensprache 10Mischen von P. 139MODULA 13objektorientierte P. 8Paradigma 8PASCAL 13prädikative P. 8problemorientierte P. 10PROLOG 8prozedurale P. 8SCHEME 8SMALLTALK 8Sprachenfamilie 8SQL 8Programmierstil 22Programmiertechnik 23Programmierumgebung 56Programmquelle 3PROLOG 8Pro nescia 41Public Member 182Quasar-Toolkit 205Quellco<strong>de</strong> 18Qu<strong>in</strong>e 280r-Wert 108rand(3C) 237random(3M) 237ranlib 43read 64, 116read(2) 172realloc(3) 258Referenzebene 102referenzieren 96, 115register (C) 105Rekursion 159relozierbar 19reserviertes Wort 81return (C) 131Revision Control System 48Richtl<strong>in</strong>ien (C) 22Rienne-Vaplus, Höhle von R.39rlog (RCS) 49robust 21Rückgabewert 131, 138, 227Rundungsfehler 87sarge 376scanf 117scanf(3) 172, 326SCHEME 8Schleife (C) 125Schleife, abweisen<strong>de</strong> 125Schleife, nichtabweisen<strong>de</strong>126Schleifenzähler 129Schlüsselwort 57, 76, 81Schlüsselwort 317sdb 40Seed 238Sequenz 123Shared Library 33shift (C) 114short (C) 85Signal (Qt) 205S<strong>in</strong>gle UNIX Specification225


410 SACHVERZEICHNISsize 75sizeof-Operator 120Skalarprodukt 199Slapper 375Slot 205small (Speichermo<strong>de</strong>ll) 178SMALLTALK 8, 17, 81Software ConfigurationManagement 56Software Eng<strong>in</strong>eer<strong>in</strong>g 23Source Co<strong>de</strong> Control System55Speicherdynamische Verwaltung258Register 105Segmentierung 178Speichermo<strong>de</strong>ll 33, 178Speicherbedarf 83Speicherklasse (C)auto 105, 107extern 105register 105static 105, 107Speicherplatz (C) 82spl<strong>in</strong>t 34Sprung (C) 129srand(3C) 237srandom(3M) 237Standard-C-Bibliothek 171Standard-Mathematik-Bibliothek174Standardbibliothek 170, 178Standard Template Library193stat 64static (C) 105, 239statische B<strong>in</strong>dung 20stdio.h 172, 215, 237stdlib.h 237str<strong>in</strong>g 64Str<strong>in</strong>g 90, 98, 257Str<strong>in</strong>g-Deskriptor 61str<strong>in</strong>g.h 172Str<strong>in</strong>gfunktion 172str<strong>in</strong>gs 48, 75strip 75strncmp 64struct (C) 91Structured Query Language8StrukturDatenstruktur 28, 82Programmstruktur 26, 28Strukturverweis (C) 115Subarray 197switch (C) 124Syntax-Diagramm 77Syntax-Prüfer 34sys/stat.h 64Systemaufruf 57, 172, 314Target (make) 35Template 193term<strong>in</strong>fo(4) 233Tex<strong>in</strong>fo 225Textfile 76time 41, 59, 75time(2) 237time.h 237times 43t<strong>in</strong>y (Speichermo<strong>de</strong>ll) 178Token 76Top-down-Entwurf 26TreiberCompilertreiber 33Trennzeichen (C) 76Typabstrakter Datentyp 181


SACHVERZEICHNIS 411alphanumerischer T. 87Array 90Attribut 83Aufzählungstyp 94Bitfeld 93, 280boolescher T. 89cdotprecision 199char 87character 280cidotprecision 199cimatrix 196c<strong>in</strong>terval 196civector 196cmatrix 196complex 196const 83cvector 196dotprecision 199double 86e<strong>in</strong>facher Typ 85erklären (c<strong>de</strong>cl) 84externer T. 106float 86ganze Zahl 85Gleitkommazahl 86idotprecision 199imatrix 196<strong>in</strong>t 85<strong>in</strong>terval 196ivector 196long 85long double 86Po<strong>in</strong>ter 94real 196rmatrix 196rvector 196short 85Struktur 91T. e<strong>in</strong>es Operan<strong>de</strong>n 82, 83Typumwandlung 108, 119,231Union 93unsigned 85void 89volatile 83zusammengesetzter T. 90type<strong>de</strong>f (C) 103types.h 64Überladung 110Übersichtlichkeit 21, 214,230Uhr 59Umgehung 21union (C) 93unsigned (C) 85Unterprogramm 57utime 75utmp 76varargs 153Variableglobale V. 105lokale V. 105register-V. 105Vere<strong>in</strong>barung 82Vererbung (Klassen) 184Vergleich 112Version 21Versionskontrolle 48Verzweigung (C) 124void (C) 89volatile (C) 83Vorrang (C) 120Waterfall approach 23Wert 82Wertebereich 83Wertübergabe 138while-Schleife (C) 125


412 SACHVERZEICHNISwho 76Widget 176, 205W<strong>in</strong>dows (Microsoft) 205woody 375Wort, reserviertes 81Wortsymbol 81write 116write(2) 172xdb 40, 74Xlib 176xstr 48Xt 176X W<strong>in</strong>dow System 205Zahlganze Z. 85Gleitkommazahl 86komplexe Z. 17, 287Primzahl 210, 246Pseudo-Zufallszahl 242Zufallszahl 237Zahlensystem 291ZeichensatzASCII 298EBCDIC 298IBM-PC 298Lat<strong>in</strong>-1 306ROMAN8 298Zeilenkommentar (<strong>C++</strong>) 80Ziel (make) 35Zirkel<strong>de</strong>f<strong>in</strong>ition 159Zirkelschluss 159Zufallszahl 237ZUSE Z22 11ZUSE Z 22 365Zuweisung 108, 123Zweierkomplement 279

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!