13.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...

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

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


Copyright 2000–2008 by Wulf <strong>Alex</strong>, KarlsruhePermission is granted to copy, distribute and/or modify this document un<strong>de</strong>r the terms ofthe GNU Free Documentation License, Version 1.2 or any later version published by theFree 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 entitled GNU Free DocumentationLicense on page 218.Ausgabedatum: 18. November 2008.Email:alex-we<strong>in</strong>garten@t-onl<strong>in</strong>e.<strong>de</strong>Dies ist e<strong>in</strong> Skriptum. Es ist unvollständig und enthält Fehler.Geschützte Namen wie UNIX o<strong>de</strong>r PostScript s<strong>in</strong>d nicht gekennzeichnet.Geschrieben mit <strong>de</strong>m Texteditor vi, formatiert mit L A TEX unter Debian GNU/L<strong>in</strong>ux.Die Skripten liegen unter folgen<strong>de</strong>n URLs zum Herunterla<strong>de</strong>n bereit:http://www.alex-we<strong>in</strong>garten.<strong>de</strong>/skripten/http://www.abklex.<strong>de</strong>/skripten/Besuchen Sie auch die Seiten zu me<strong>in</strong>en Büchern:http://www.alex-we<strong>in</strong>garten.<strong>de</strong>/<strong>de</strong>bian/http://www.abklex.<strong>de</strong>/<strong>de</strong>bian/Von <strong>de</strong>m Skriptum gibt es neben <strong>de</strong>r Normalausgabe e<strong>in</strong>e Ausgabe <strong>in</strong> kle<strong>in</strong>erer Schrift (9Punkte), <strong>in</strong> großer Schrift (14 Punkte) sowie e<strong>in</strong>e Textausgabe für Leseprogramme (Screenrea<strong>de</strong>r).


There 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.VorwortDie Skripten richten sich an Leser mit wenigen Vorkenntnissen <strong>in</strong> <strong>de</strong>r ElektronischenDatenverarbeitung; sie sollen – wie FRITZ REUTERS Urgeschicht von Meckelnborg – ok förSchaulk<strong>in</strong>ner tau bruken s<strong>in</strong>. Für die wissenschaftliche Welt zitiere ich aus <strong>de</strong>m Vorwort zue<strong>in</strong>em Buch <strong>de</strong>s Mathematikers RICHARD COURANT: Das Buch wen<strong>de</strong>t sich an e<strong>in</strong>en weitenKreis: an Schüler und Lehrer, an Anfänger und Gelehrte, an Philosophen und Ingenieure. DasLernziel 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 Programmiersprache C/<strong>C++</strong> und <strong>de</strong>m weltumspannen<strong>de</strong>n Internet, die so weit reicht,dass <strong>de</strong>r Leser mit <strong>de</strong>r Praxis beg<strong>in</strong>nen und sich selbständig weiterbil<strong>de</strong>n kann. Ausgelernthat man nie.Zusammen bil<strong>de</strong>ten die Skripten die Grundlage für das Buch UNIX. C und Internet, imJahr 1999 <strong>in</strong> zweiter Auflage im Spr<strong>in</strong>ger-Verlag erschienen (ISBN 3-540-65429-1). Das Buchist vergriffen und wird auch nicht weiter gepflegt, da ich mich auf Debian GNU/L<strong>in</strong>ux konzentriere.Me<strong>in</strong>e Debian-Bücher (ISBN 3-540-43267-1 und 3-540-23786-0) s<strong>in</strong>d ebenfalls beiSpr<strong>in</strong>ger erschienen, aber nicht im Netz veröffentlicht. Die Skripten dagegen bleiben weiterh<strong>in</strong>im Netz verfügbar und wer<strong>de</strong>n bei Gelegenheit immer wie<strong>de</strong>r überarbeitet.Warum e<strong>in</strong> L<strong>in</strong>ux/UNIX? Die Betriebssysteme <strong>de</strong>r Gattung UNIX laufen auf e<strong>in</strong>er Vielzahlvon Computertypen. Unter <strong>de</strong>n verbreiteten Betriebssystemen s<strong>in</strong>d sie die ältesten undausgereift. Die UNIXe haben sich lange ohne kommerzielle E<strong>in</strong>flüsse entwickelt und tun dasteilweise heute noch, siehe L<strong>in</strong>ux, FreeBSD, NetBSD, OpenBSD und an<strong>de</strong>re. Programmierer,nicht das Market<strong>in</strong>g, haben die Ziele gesetzt. Die UNIXe haben von Anfang an gemischteHardware und die Zusammenarbeit mehrerer Benutzer unterstützt. In Verb<strong>in</strong>dung mit <strong>de</strong>mX W<strong>in</strong>dow System, e<strong>in</strong>em netzfähigen Fenstersystem, s<strong>in</strong>d die UNIXe unter <strong>de</strong>n Betriebssystemenmittlerer Größe die leistungsfähigsten. L<strong>in</strong>ux/UNIX-Rechner waren von Anbeg<strong>in</strong>n imInternet dabei und haben se<strong>in</strong>e Entwicklung bestimmt.Warum C/<strong>C++</strong>? Die universelle Programmiersprache C mit ihrer mächtigen Erweiterung<strong>C++</strong> ist – im Vergleich zu BASIC etwa – ziemlich e<strong>in</strong>heitlich. Der Anfang ist leicht, an dieGrenzen stoßen wenige Benutzer. Das Zusammenspiel zwischen C/<strong>C++</strong>-Programmen und L<strong>in</strong>ux/UNIXfunktioniert reibungslos.Warum das Internet? Das Internet ist das größte Computernetz dieser Er<strong>de</strong>, e<strong>in</strong> Zusammenschlussvieler regionaler Netze. Ursprünglich auf Hochschulen und Behör<strong>de</strong>n beschränkt,s<strong>in</strong>d mittlerweile auch Industrie, Han<strong>de</strong>l und Privatpersonen beteiligt. Unser beruflichesLeben und zunehmend unser privates Dase<strong>in</strong> wer<strong>de</strong>n vom Internet berührt. E<strong>in</strong>eEmail-Anschrift ist so wichtig gewor<strong>de</strong>n wie e<strong>in</strong> Telefonanschluss. Als Informationsquelle istdas Netz unentbehrlich.Bei <strong>de</strong>r Stoffauswahl habe ich mich von me<strong>in</strong>er Arbeit als Benutzer, Verwalter und Programmiererleiten lassen. Beson<strong>de</strong>rer Wert wird auf die Erläuterung <strong>de</strong>r zahlreichen Fachbegriffegelegt, die <strong>de</strong>m Anfänger das Leben erschweren. Die typische Frage, vor <strong>de</strong>r auch ichimmer wie<strong>de</strong>r stehe, lautet: Was ist XYZ und wozu kann man es gebrauchen? H<strong>in</strong>sichtlichvieler E<strong>in</strong>zelheiten verweise ich auf die Referenz-Handbücher zu <strong>de</strong>n Rechenanlagen undProgrammiersprachen o<strong>de</strong>r auf Monografien, um <strong>de</strong>n Text nicht über die Maßen aufzublähen;er ist e<strong>in</strong> Kompromiss aus 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 das Warum e<strong>in</strong>. Von Zeit zuZeit sollte man <strong>de</strong>n Blick weg von <strong>de</strong>n Wellen auf das Meer richten, sonst erwirbt man nurkurzlebiges Wissen.Man kann <strong>de</strong>n Gebrauch e<strong>in</strong>es Betriebssystems, e<strong>in</strong>er Programmiersprache o<strong>de</strong>r <strong>de</strong>riii


ivNetzdienste nicht alle<strong>in</strong> aus Büchern erlernen – 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-Packard 9000/712 unterHP-UX 10.20 und e<strong>in</strong>em PC <strong>de</strong>r Marke We<strong>in</strong>gartener Katzenberg Auslese unter DebianGNU/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>rBeispiele stehen im Netz.Dem Text liegen eigene Erfahrungen aus fünf Jahrzehnten zugrun<strong>de</strong>. Se<strong>in</strong>e Wurzeln gehenzurück auf e<strong>in</strong>e Erste Hilfe für Benutzer <strong>de</strong>r Hewlett-Packard 9000 Mo<strong>de</strong>ll 550 unter HP-UX, im Jahr 1986 aus zwanzig Aktenordnern <strong>de</strong>stilliert, die die Masch<strong>in</strong>e begleiteten. Gegenwärtigverschiebt sich <strong>de</strong>r Schwerpunkt <strong>in</strong> Richtung Debian GNU/L<strong>in</strong>ux. Ich habe auchfrem<strong>de</strong> Hilfe beansprucht und danke Kollegen <strong>in</strong> <strong>de</strong>n Universitäten Karlsruhe und Lyonsowie Mitarbeitern <strong>de</strong>r Firmen IBM und Hewlett-Packard für schriftliche Unterlagen undmündlichen Rat sowie zahlreichen Stu<strong>de</strong>nten für Anregungen und Diskussionen. Darüberh<strong>in</strong>aus habe ich fleißig das Internet angezapft und viele dort umlaufen<strong>de</strong> Gui<strong>de</strong>s, Primers,HOWTOs, Tutorials und Sammlungen von Frequently Asked Questions (FAQs) verwen<strong>de</strong>t.We<strong>in</strong>garten (Ba<strong>de</strong>n), 15. Februar 2006Wulf <strong>Alex</strong>


Übersicht1 Programmieren <strong>in</strong> C/<strong>C++</strong> 2A Zahlensysteme 180B Zeichensätze 185C UNIX-Systemaufrufe 196D C-Lexikon 198E Karlsruher Test 206F GNU Lizenzen 214G Zeittafel 225H Zum Weiterlesen 234v


viiiINHALT1.7.3 C-XSC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1181.7.3.1 Was ist C-XSC? . . . . . . . . . . . . . . . . . . . . . . . . . . . 1181.7.3.2 Datentypen, Operatoren und Funktionen . . . . . . . . . . . . 1181.7.3.3 Teilfel<strong>de</strong>r von Vektoren und Matrizen . . . . . . . . . . . . . . 1191.7.3.4 Genaue Auswertung von Ausdrücken . . . . . . . . . . . . . . 1201.7.3.5 Dynamische Langzahl-Arithmetik . . . . . . . . . . . . . . . . 1211.7.3.6 E<strong>in</strong>- und Ausgabe <strong>in</strong> C-XSC . . . . . . . . . . . . . . . . . . . . 1221.7.3.7 C-XSC-Numerikbibliothek . . . . . . . . . . . . . . . . . . . . . 1221.7.3.8 Beispiel Intervall-Newton-Verfahren . . . . . . . . . . . . . . . 1231.7.4 X11-Programmierung mit <strong>de</strong>m Qt-Toolkit . . . . . . . . . . . . . . . . . . 1241.8 Überla<strong>de</strong>n von Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1271.9 Präprozessor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1291.9.1 <strong>de</strong>f<strong>in</strong>e-Anweisungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1291.9.2 <strong>in</strong>clu<strong>de</strong>-Anweisungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1301.9.3 Bed<strong>in</strong>gte Kompilation (#if<strong>de</strong>f) . . . . . . . . . . . . . . . . . . . . . . . . . 1321.9.4 Memo Präprozessor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1341.9.5 Übung Präprozessor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1341.10 Dokumentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1341.10.1 Zweck . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1341.10.2 Anfor<strong>de</strong>rungen (DIN 66 230) . . . . . . . . . . . . . . . . . . . . . . . . . . 1351.10.3 Erstellen e<strong>in</strong>er man-Seite . . . . . . . . . . . . . . . . . . . . . . . . . . . 1361.11 Weitere C-Programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1371.11.1 Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1371.11.2 Aufbau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1371.11.3 Fehlersuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1391.11.4 Optimierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1401.11.5 curses – Fluch o<strong>de</strong>r Segen? . . . . . . . . . . . . . . . . . . . . . . . . . . . 1411.11.6 Mehr o<strong>de</strong>r weniger zufällig . . . . . . . . . . . . . . . . . . . . . . . . . . . 1441.11.7 E<strong>in</strong> Herz für Po<strong>in</strong>ter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1471.11.7.1 Nullpo<strong>in</strong>ter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1481.11.7.2 Po<strong>in</strong>ter auf Typ void . . . . . . . . . . . . . . . . . . . . . . . . 1481.11.7.3 Arrays und Po<strong>in</strong>ter . . . . . . . . . . . . . . . . . . . . . . . . . 1501.11.7.4 Arrays von Funktionspo<strong>in</strong>tern . . . . . . . . . . . . . . . . . . 1531.11.8 Verarbeitung von Str<strong>in</strong>gs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1571.11.9 Dynamische Speicherverwaltung (malloc) . . . . . . . . . . . . . . . . . . 1581.11.10 X W<strong>in</strong>dow System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1621.11.11 cgi-Programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1671.12 Obfuscated C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1711.13 Portieren von Programmen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1731.13.1 Regeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1731.13.2 Übertragen von ALGOL nach C . . . . . . . . . . . . . . . . . . . . . . . . 1741.13.3 Übertragen von FORTRAN nach C . . . . . . . . . . . . . . . . . . . . . . 1751.14 Exkurs über Algorithmen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178A Zahlensysteme 180B Zeichensätze 185B.1 EBCDIC, ASCII, Roman8, IBM-PC . . . . . . . . . . . . . . . . . . . . . . . . 185B.2 German-ASCII . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189B.3 ASCII-Steuerzeichen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190B.4 Lat<strong>in</strong>-1 (ISO 8859-1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191C UNIX-Systemaufrufe 196


INHALTixD C-Lexikon 198D.1 Schlüsselwörter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198D.2 Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200D.3 Standardfunktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201D.4 pr<strong>in</strong>tf(3), scanf(3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204D.5 Inclu<strong>de</strong>-Dateien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204D.6 Präprozessor-Anweisungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205E Karlsruher Test 206F GNU Lizenzen 214F.1 GNU General Public License . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214F.2 GNU Free Documentation License . . . . . . . . . . . . . . . . . . . . . . . . 218G Zeittafel 225H Zum Weiterlesen 234


Abbildungen1.1 Flussdiagramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171.2 Nassi-Shnei<strong>de</strong>rman-Diagramm . . . . . . . . . . . . . . . . . . . . . . . . . . 171.3 Syntax-Diagramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47x


Tabellen1.1 Länge von Datentypen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51xi


Programme und an<strong>de</strong>re Quellen1.1 LISP-Programm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.2 SCHEME-Programm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.3 PROLOG-Programm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.4 Programm Z 22 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.5 COBOL-Programm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.6 JAVA-Programm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.7 Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211.8 Erweitertes Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221.9 C-Programm mit Funktionsbibliothek . . . . . . . . . . . . . . . . . . . . . . 261.10 C-Funktion Mittelwert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271.11 C-Funktion Varianz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271.12 Makefile zum Sortierprogramm . . . . . . . . . . . . . . . . . . . . . . . . . . 301.13 Inclu<strong>de</strong>-Datei zum Sortierprogramm . . . . . . . . . . . . . . . . . . . . . . . 301.14 C-Programm Sortieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311.15 C-Funktion Bubblesort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321.16 C-Programm Systemzeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361.17 FORTRAN-Programm Systemzeit . . . . . . . . . . . . . . . . . . . . . . . . . 361.18 C-Programm Datei-Informationen . . . . . . . . . . . . . . . . . . . . . . . . . 401.19 C-Programm Fork-Bombe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411.20 C-Programm mit Fehlern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431.21 C-Programm Kommentar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481.22 C-Programm character und <strong>in</strong>teger . . . . . . . . . . . . . . . . . . . . . . . . 531.23 C-Programm Po<strong>in</strong>terarithmetik . . . . . . . . . . . . . . . . . . . . . . . . . . 601.24 C-Programm Bitweise Negation . . . . . . . . . . . . . . . . . . . . . . . . . . 671.25 C-Programm Bitoperationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 681.26 C-Programm Ausgabe per Systemaufruf . . . . . . . . . . . . . . . . . . . . . 701.27 C-Programm Ausgabe per Standardfunktion . . . . . . . . . . . . . . . . . . 711.28 C-Programm e<strong>in</strong>fache for-Schleife . . . . . . . . . . . . . . . . . . . . . . . . . 761.29 C-Programm zusammengesetzte for-Schleife . . . . . . . . . . . . . . . . . . 761.30 C-Programm mit goto, grauenvoll . . . . . . . . . . . . . . . . . . . . . . . . . 781.31 C-Programm, verbessert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 781.32 C-Programm return-Anweisungen . . . . . . . . . . . . . . . . . . . . . . . . 801.33 C-Programm Funktionsprototyp . . . . . . . . . . . . . . . . . . . . . . . . . . 811.34 C-Funktion Parameterübergabe by value . . . . . . . . . . . . . . . . . . . . 831.35 C-Funktion Parameterübergabe by reference . . . . . . . . . . . . . . . . . . 831.36 FORTRAN-Funktion Parameterübergabe by reference . . . . . . . . . . . . . 831.37 PASCAL-Funktion Parameterübergabe by value . . . . . . . . . . . . . . . . 841.38 PASCAL-Funktion Parameterübergabe by reference . . . . . . . . . . . . . . 841.39 C-Programm Parameterübergabe an C-Funktionen . . . . . . . . . . . . . . 851.40 C-Programm Parameterübergabe an FORTRAN-Funktion . . . . . . . . . . 851.41 C-Programm Parameterübergabe an PASCAL-Funktionen . . . . . . . . . . 851.42 FORTRAN-Programm Parameterübergabe an C-Funktionen . . . . . . . . . 861.43 FORTRAN-Programm Parameterübergabe an FORTRAN-Fkt. . . . . . . . . 871.44 FORTRAN-Programm Parameterübergabe an PASCAL-Fkt. . . . . . . . . . 871.45 PASCAL-Programm Parameterübergabe an C-Funktionen . . . . . . . . . . 881.46 PASCAL-Programm Parameterübergabe an FORTRAN-Funktion . . . . . . 881.47 PASCAL-Programm Parameterübergabe an PASCAL-Funktionen . . . . . . 891.48 PASCAL-Funktion Parameterübergabe by value . . . . . . . . . . . . . . . . 891.49 PASCAL-Funktion Parameterübergabe by reference . . . . . . . . . . . . . . 901.50 Shellscript Parameterübergabe . . . . . . . . . . . . . . . . . . . . . . . . . . 90xii


Programme und an<strong>de</strong>re Quellenxiii1.51 C-Programm Parameterübernahme von Shellscript . . . . . . . . . . . . . . 901.52 C-Programm Kommandozeilenargumente . . . . . . . . . . . . . . . . . . . . 911.53 C-Funktion Wechseln<strong>de</strong> Anzahl von Argumenten . . . . . . . . . . . . . . . . 941.54 C-Programm Quadratwurzel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 951.55 C-Programm ggT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 961.56 C-Programm Fakultät . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 971.57 C-Programm Selbstaufruf ma<strong>in</strong>() . . . . . . . . . . . . . . . . . . . . . . . . . 971.58 C-Programm, Fakultäten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1001.59 Assemblerfunktion Addition 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1011.60 C-Programm Str<strong>in</strong>gverarbeitung . . . . . . . . . . . . . . . . . . . . . . . . . 1051.61 C-Programm Mathematische Funktionen . . . . . . . . . . . . . . . . . . . . 1061.62 <strong>C++</strong>-Programm Hallo, Welt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1091.63 <strong>C++</strong>-Programm Umrechnung UTC-MEZ . . . . . . . . . . . . . . . . . . . . . 1111.64 <strong>C++</strong>-Programm Geometrische Formen . . . . . . . . . . . . . . . . . . . . . . 1151.65 C-XSC-Funktion <strong>de</strong>fect() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1211.66 C-XSC-Programm e<strong>in</strong>facher Genauigkeit . . . . . . . . . . . . . . . . . . . . 1211.67 C-XSC-Programm mehrfacher Genauigkeit . . . . . . . . . . . . . . . . . . . 1221.68 C-XSC-Programm mit E<strong>in</strong>- und Ausgabe . . . . . . . . . . . . . . . . . . . . . 1221.69 C-XSC-Programm Intervall-Newton-Verfahren . . . . . . . . . . . . . . . . . 1241.70 Makefile zu qhello.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1251.71 Inclu<strong>de</strong>-Datei zu qhello.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1251.72 <strong>C++</strong>-Programm qhello.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1261.73 <strong>C++</strong>-Programm Primzahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1291.74 Inclu<strong>de</strong>-Datei /usr/<strong>in</strong>clu<strong>de</strong>/stdio.h . . . . . . . . . . . . . . . . . . . . . . . . . 1321.75 C-Programm Umrechnung Zahlenbasis . . . . . . . . . . . . . . . . . . . . . 1341.76 C-Programm, m<strong>in</strong>imal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1371.77 C-Programm, e<strong>in</strong>fachst . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1381.78 C-Programm, e<strong>in</strong>fach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1381.79 C-Programm, fortgeschritten . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1381.80 C-Programm, Variante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1391.81 C-Programm, E<strong>in</strong>gabe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1391.82 C-Programm Dateiputzete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1421.83 C-Programm, curses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1431.84 C-Programm Zufallszahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1451.85 C-Programm Zufallszahlen, mit Funktion . . . . . . . . . . . . . . . . . . . . 1461.86 C-Funktion Zufallszahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1461.87 PASCAL-Programm Zufallszahlen, mit Funktion . . . . . . . . . . . . . . . . 1471.88 C-Programm, void-Po<strong>in</strong>ter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1501.89 C-Programm Primzahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1531.90 C-Programm Array von Funktionspo<strong>in</strong>tern . . . . . . . . . . . . . . . . . . . 1551.91 C-Funktion bil<strong>de</strong>r.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1561.92 Makefile zu schiff.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1571.93 C-Programm Dynamische Speicherverwaltung . . . . . . . . . . . . . . . . . 1581.94 C-Programm Sortieren nach Du<strong>de</strong>n . . . . . . . . . . . . . . . . . . . . . . . . 1621.95 C-Programm X W<strong>in</strong>dow System/Xlib . . . . . . . . . . . . . . . . . . . . . . . 1661.96 Webseite cgi_test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1671.97 Inclu<strong>de</strong>-Datei cgi.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1681.98 C-Programm cgi_test.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1681.99 C-Funktionen cgi.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1711.100 ALGOL-Programm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1741.101 C-Programm ggT nach Euklid . . . . . . . . . . . . . . . . . . . . . . . . . . . 1751.102 FORTRAN-Programm Quadratische Gleichung . . . . . . . . . . . . . . . . . 1761.103 C-Programm Quadratische Gleichung . . . . . . . . . . . . . . . . . . . . . . 178


xivProgramme 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 Zitate o<strong>de</strong>r wörtliche Re<strong>de</strong> wer<strong>de</strong>nim 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>en fett.• 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 Bildschirm wer<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 sich das 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> Klammern die Nummer <strong>de</strong>r betroffenenSektion <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, sof<strong>in</strong><strong>de</strong>n Sie diese bei <strong>de</strong>r erstmaligen Erlä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>r französischen Fachwortes,so f<strong>in</strong><strong>de</strong>n Sie e<strong>in</strong>en Verweis im Sach- und Namensverzeichnis.• UNIX wird hier immer als die Gattung <strong>de</strong>r aus <strong>de</strong>m bei AT&T um 1970 entwickeltenUnix ähnlichen Betriebssysteme verstan<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 Lesersei sich aber bewußt, dass sich sowohl Inhalte wie Adressen (URLs) än<strong>de</strong>rn. BeiVerweisen auf Webseiten (URLs) ist die Angabe <strong>de</strong>s Protokolls http:// weggelassen.• Unter Benutzer, Programmierer, Verwalter usw. wer<strong>de</strong>n sowohl männliche wie weiblicheErsche<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 und im Netz das Du üblich ist.Gegenwärtig ersche<strong>in</strong>t mir diese Wahl passen<strong>de</strong>r.1


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 Computernarbeitet, braucht Grundkenntnisse im Programmieren, um die richtigen Vorstellungen von<strong>de</strong>m Geschehen h<strong>in</strong>ter <strong>de</strong>m Bildschirm zu haben. Nicht je<strong>de</strong>r Masch<strong>in</strong>enbauer muss e<strong>in</strong>enKolbenmotor konstruieren können, aber er muss wissen, wie e<strong>in</strong>e Kolbenmasch<strong>in</strong>e aufgebautist und funktioniert, und er sollte mit e<strong>in</strong>em Schraubenschlüssel umgehen können. H<strong>in</strong>zukommt, dass häufig kle<strong>in</strong>ere Anpassungen o<strong>de</strong>r Ergänzungen <strong>de</strong>r Software erfor<strong>de</strong>rlich s<strong>in</strong>d,für die man nicht immer e<strong>in</strong>en Spezialisten hat.Wenn es ernst wird, bezieht man se<strong>in</strong>e Kenntnisse aus drei Quellen, nämlich aus:• e<strong>in</strong>em Lehrbuch wie diesem,• e<strong>in</strong>er Referenz zum Nachschlagen, siehe das Verzeichnis am En<strong>de</strong> <strong>de</strong>s Buches,• e<strong>in</strong>er Sammlung von Frequently Asked Questions aus <strong>de</strong>m Internet, hier zu <strong>de</strong>n ThemenC und <strong>C++</strong>.Das Lehrbuch sorgt für <strong>de</strong>n Überblick, die Referenz vermittelt E<strong>in</strong>zelheiten, die FAQ beantwortetdie 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>r Newsgruppe 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/,• 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 mansollte 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 bis zu <strong>de</strong>n Nullen und E<strong>in</strong>senim Befehlsregister <strong>de</strong>s Prozessors ist e<strong>in</strong> weiter Weg. Wir wollen diesen Weg schrittweise anHand e<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 200Programmiersprachen 1 f<strong>in</strong><strong>de</strong>n sich bei <strong>de</strong>r Louisiana Tech University unter:http://www.latech.edu/~acm/HelloWorld.shtmlAls erstes das Programm, so wie es e<strong>in</strong> C-Programmierer schreibt:1 Unter www.ionet.net/˜timtroyr/funhouse/beer.html liegt e<strong>in</strong>e ähnliche Sammlung.2


1.1. GRUNDBEGRIFFE 3/* 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 durchdie Leute, die die Sprache C entwickelt haben. Diese Form <strong>de</strong>s Programmes wird von geübtenProgrammierern verstan<strong>de</strong>n und Programmquelle (source) genannt. Die Masch<strong>in</strong>e kannnichts damit anfangen.Damit das Programm von e<strong>in</strong>er Masch<strong>in</strong>e ausgeführt wer<strong>de</strong>n kann, muss es übersetztwer<strong>de</strong>n. Hierzu wird e<strong>in</strong> weiteres Programm, e<strong>in</strong> Compiler, herangezogen. Im Fall von Cläuft <strong>de</strong>r Übersetzungsvorgang <strong>in</strong> mehreren Schritten ab, ohne dass <strong>de</strong>r Benutzer etwasdavon 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. Imersten Schritt (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 entferntund die mit e<strong>in</strong>em Doppelkreuz beg<strong>in</strong>nen<strong>de</strong>n Präprozessor-Anweisungen ausgeführt.Das Ergebnis sieht 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<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ügt hat. Im Pr<strong>in</strong>zip könntedas auch <strong>de</strong>r Programmierer machen, 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"


4 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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> erfahrener Programmierer nochvon Hand schreiben. Früher gab es nichts an<strong>de</strong>res. Im Großen und Ganzen entspricht e<strong>in</strong>eAnweisung <strong>in</strong> C o<strong>de</strong>r FORTRAN vier Assembler-Anweisungen. Die Assembler-Befehle wer<strong>de</strong>nzu e<strong>in</strong>em wesentlichen Teil durch <strong>de</strong>n Hersteller <strong>de</strong>r CPU bestimmt, hier also durchIntel. Das Assembler-Programm ist an die Hardware und das Betriebssystem gebun<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 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>n e<strong>in</strong>e Standard-Funktion pr<strong>in</strong>tf() zur Ausgabe auf <strong>de</strong>n Bildschirm. Auch h<strong>in</strong>ter <strong>de</strong>m Wörtchen ma<strong>in</strong> verbirgtsich e<strong>in</strong>iges. Deren Co<strong>de</strong> muß noch h<strong>in</strong>zugefügt wer<strong>de</strong>n, dann kann die Masch<strong>in</strong>e loslegenmit <strong>de</strong>r Begrüßung. Diesen letzten Schritt vollzieht <strong>de</strong>r L<strong>in</strong>ker. Der Anfang <strong>de</strong>s ausführbarenProgrammes hallo.exe sieht nicht besser aus als vorher, <strong>de</strong>r Umfang <strong>de</strong>s Programmfilesist 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öheren Programmiersprachen.Als Kontrast dazu e<strong>in</strong> kurzes Beispiel e<strong>in</strong>er problemangepassten, masch<strong>in</strong>enfernen Sprache(SQL). Die Aufgabe sei die Abfrage e<strong>in</strong>er Datenbank, die ihre Daten <strong>in</strong> Form von Tabellenmit Spalten und Zeilen hält:2 Genauer: Das Rück-Übersetzen ist möglich, das Ergebnis jedoch praktisch unbrauchbar,wenn es um mehr als triviale Programme geht.


1.1. GRUNDBEGRIFFE 5select 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, Vornamen und Telefonnummer aus<strong>de</strong>r Tabelle mitarbeiter herausziehen und dabei nur die Mitarbeiter berücksichtigen, <strong>de</strong>renWohnort Karlsruhe ist. Die Liste soll an erster Stelle nach <strong>de</strong>m Nachnamen alphabetischsortiert se<strong>in</strong>, bei gleichem Nachnamen nach <strong>de</strong>m Vornamen. E<strong>in</strong>facher lässt sich e<strong>in</strong>e Aufgabekaum formulieren.E<strong>in</strong>e Programmiersprache wird von zwei Seiten her entwickelt. Von oben, <strong>de</strong>n zu programmieren<strong>de</strong>nAufgaben aus <strong>de</strong>r realen Welt her, kommen die Anfor<strong>de</strong>rungen an die Sprache.Von unten, <strong>de</strong>r Hardware (CPU) und <strong>de</strong>m Betriebssystem her kommen die Möglichkeiten zurLö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>rElektronik abspielt, hoffentlich noch etwas mit <strong>de</strong>r ursprünglichen Aufgabe zu tun hat. DerCompilerbauer muss sowohl das Problem wie die Hardware samt Betriebssystem im Augehaben, wenn er beispielsweise e<strong>in</strong>en C-Compiler für das Betriebssystem PC-DOS auf e<strong>in</strong>emIntel-Prozessor schreibt. Wer sich näher für Compiler <strong>in</strong>teressiert, kann mit <strong>de</strong>m Buch vonALFRED V. AHO – genannt das Dragon-Book – beg<strong>in</strong>nen. Die Thematik geht über <strong>de</strong>n Bauvon Compilern h<strong>in</strong>aus und erstreckt sich ganz allgeme<strong>in</strong> auf die Analyse und Verarbeitungvon Zeichenfolgen.1.1.3 SprachenfamilienHat man e<strong>in</strong>e Aufgabe, e<strong>in</strong> Problem zu lösen, so kann man drei Abschnitte auf <strong>de</strong>m Wegunterschei<strong>de</strong>n:• Aufgabenstellung,• Lösungsweg,• Ergebnis.Das Ergebnis ist nicht bekannt, sonst wäre die Aufgabe bereits gelöst. Die Aufgabenstellungund erfor<strong>de</strong>rlichenfalls e<strong>in</strong>en Lösungsweg sollten wir kennen.Mithilfe <strong>de</strong>r bekannten Programmiersprachen von BASIC bis <strong>C++</strong> beschreiben wir <strong>de</strong>nLösungsweg <strong>in</strong> e<strong>in</strong>er für <strong>de</strong>n Computer geeigneten Form. Diese Programmiersprachen wer<strong>de</strong>nals algorithmische o<strong>de</strong>r prozedurale Programmiersprachen im weiteren S<strong>in</strong>n bezeichnet,weil die Programme aus Prozeduren bestehen, die Anweisungen an <strong>de</strong>n Computer enthalten(late<strong>in</strong>isch proce<strong>de</strong>re = vorangehen). Diese Familie wird unterteilt <strong>in</strong> die imperativeno<strong>de</strong>r prozeduralen Sprachen im engeren S<strong>in</strong>ne e<strong>in</strong>erseits und die objektorientierten Sprachenan<strong>de</strong>rerseits (late<strong>in</strong>isch imperare = befehlen).Bequemer wäre es jedoch, wir könnten uns mit <strong>de</strong>r Beschreibung <strong>de</strong>r Aufgabe begnügenund 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>utend wachsen. Die noch nicht sehr verbreiteten <strong>de</strong>klarativen Programmiersprachengehen 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 man dazu kommt. Die <strong>de</strong>klarativen Sprachenunterteilt man <strong>in</strong> die funktionalen und die logischen o<strong>de</strong>r prädikativen Sprachen.


6 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Wir haben also folgen<strong>de</strong> E<strong>in</strong>teilung (wobei die tatsächlich benutzten Sprachen Mischl<strong>in</strong>ges<strong>in</strong>d und die E<strong>in</strong>ordnung ihrem am stärksten ausgeprägten Charakterzug folgt):• Prozedurale Sprachen im weiteren S<strong>in</strong>n– imperative, algorithmische, operative o<strong>de</strong>r im engeren S<strong>in</strong>n prozedurale Sprachen(BASIC, FORTRAN, COBOL, C, PASCAL)– objektorientierte Sprachen (SMALLTALK, <strong>C++</strong>, Java)• Deklarative Sprachen– funktionale o<strong>de</strong>r applikative Sprachen (LISP, SCHEME, HASKELL)– logische o<strong>de</strong>r prädikative Sprachen (PROLOG)Diese Sprachentypen wer<strong>de</strong>n auch Paradigmen (Beispiel, Muster) genannt. Auf imperativeund objektorientierte Sprachen gehen wir bald ausführlich e<strong>in</strong>. Zuerst e<strong>in</strong> kurzer Blick auffunktionale und prädikative Sprachen.Programme <strong>in</strong> funktionalen Programmiersprachen wie LISP o<strong>de</strong>r SCHEME bestehen ausDef<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)))und 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.1 : LISP-Programm Hello, WorldQuelle 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 dieProgramme zu e<strong>in</strong>fach, um die Eigenheiten <strong>de</strong>r Sprachen zu erkennen. Die Sprache C isttrotz <strong>de</strong>r Verwendung <strong>de</strong>s Funktionsbegriffes ke<strong>in</strong>e funktionale Programmiersprache, da ihrKonzept nicht an<strong>de</strong>rs als <strong>in</strong> FORTRAN o<strong>de</strong>r PASCAL auf <strong>de</strong>r sequentiellen Ausführung vonAnweisungen beruht.Programmen <strong>in</strong> logischen o<strong>de</strong>r prädikativen Sprachen wie PROLOG wer<strong>de</strong>n Fakten undRegeln zum Folgern mitgegeben, sie beantworten dann die Anfrage, ob e<strong>in</strong>e Behauptung mit<strong>de</strong>n Fakten und Regeln verträglich (wahr) ist o<strong>de</strong>r nicht. Viele Denksportaufgaben legen e<strong>in</strong>esolche 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>res geht über das Erlernen e<strong>in</strong>erneuen Sprache h<strong>in</strong>aus und bee<strong>in</strong>flusst die 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 historischeEntwicklung spiegelt:


1.1. GRUNDBEGRIFFE 7• 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 ausgerichtete und unbequeme Masch<strong>in</strong>ensprache,wir haben e<strong>in</strong>e Kostprobe gesehen. Assembler s<strong>in</strong>d e<strong>in</strong> erster Schritt <strong>in</strong> Richtungauf die Probleme und die Programmierer zu. Höhere Sprachen wie FORTRAN s<strong>in</strong>dvon <strong>de</strong>r Hardware schon ziemlich losgelöst und <strong>in</strong> diesem Fall an mathematische Problemeangepasst. Es gibt aber für spezielle Aufgaben wie Str<strong>in</strong>gverarbeitung, Datenbankabfragen,Statistik o<strong>de</strong>r Grafik Sprachen, die <strong>in</strong> ihrer Anpassung noch weiter gehen. Auch die zur Formatierung<strong>de</strong>s vorliegen<strong>de</strong>n Textes benutzte Sammlung von LaTeX-Makros stellt e<strong>in</strong>e problemangepassteSprache dar. Der Preis für die Erleichterungen ist 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 dieseAusdrucksweise unangebracht. Zum Glück s<strong>in</strong>d die Zeiten, als man die Bits e<strong>in</strong>zeln von Hand<strong>in</strong> die Lochstreifen schlug, vorbei.Die nächste Stufe war die Zusammenfassung mehrerer Bits zu Gruppen, die man mitBuchstaben und Ziffern bezeichnen konnte. E<strong>in</strong> Ausschnitt e<strong>in</strong>es Programmes für die ZUSEZ 22 im Freiburger 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 warauch mühsam, aber diese Art <strong>de</strong>r Programmierung gibt es heute noch unter <strong>de</strong>m NamenAssemblerprogrammierung. Man braucht sie, wenn man die Hardware fest im Griff habenwill, also an <strong>de</strong>n Grenzen Software - Hardware (Treiberprogramme). Darüber h<strong>in</strong>auss<strong>in</strong>d gute Assemblerprogramme schnell, 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 Microsofte<strong>in</strong>e Komb<strong>in</strong>ation von Quick C 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 zu programmieren. Wer unbed<strong>in</strong>gt<strong>de</strong>n herben Reiz <strong>de</strong>r Assemblerprogrammierung kennenlernen will, hat es mit dieserKomb<strong>in</strong>ation e<strong>in</strong>fach.Die meisten Programmierer wollen jedoch nicht Speicher<strong>in</strong>halte verschieben, son<strong>de</strong>rnGleichungen lösen o<strong>de</strong>r Wörter suchen 3 . Schon Mitte <strong>de</strong>r fünfziger Jahre entstand daherbei <strong>de</strong>r Firma IBM die erste höhere Programmiersprache, und zwar zum Bearbeiten mathematischerAufgaben. Die Sprache war daher stark an die Ausdrucksweise <strong>de</strong>r Mathematikangelehnt und zum<strong>in</strong><strong>de</strong>st für die mathematisch gebil<strong>de</strong>te Welt e<strong>in</strong>igermaßen bequem. Siewur<strong>de</strong> als formula translator, abgekürzt FORTRAN bezeichnet. FORTRAN wur<strong>de</strong> im Laufe<strong>de</strong>r Jahrzehnte weiter entwickelt – zur Zeit ist FORTRAN 90 bzw. 95 aktuell – und ist auchheute noch die <strong>in</strong> <strong>de</strong>r Technik am weitesten verbreitete Programmiersprache. Ke<strong>in</strong> Ingenieurkommt 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 82.3 Recht betrachtet, will man auch ke<strong>in</strong>e Gleichungen, son<strong>de</strong>rn Aufgaben wie die Dimensionierunge<strong>in</strong>es Masch<strong>in</strong>enteils o<strong>de</strong>r das Zusammenstellen e<strong>in</strong>es Sachregisters lösen.


8 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Die Kaufleute hatten mit Mathematik weniger am Hut, dafür aber große Datenmengen.Sie erfan<strong>de</strong>n En<strong>de</strong> <strong>de</strong>r fünfziger Jahre ihre eigene Programmiersprache COBOL, das heißtCommon Bus<strong>in</strong>ess Oriented Language. Dass Leutnant GRACE M. HOPPER (e<strong>in</strong>e Frau, zuletztim Admiralsrang) sowohl <strong>de</strong>n ersten Bug erlegt 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üstlich und gilt heutenoch als die am weitesten verbreitete Programmiersprache. Ke<strong>in</strong> Wirtschaftswissenschaftlerkommt an COBOL vorbei. E<strong>in</strong> COBOL-Programm liest sich wie gebrochenes Englisch: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.Quelle 1.5 : COBOL-Programm Hello, WorldAls die Computer <strong>in</strong> die Reichweite gewöhnlicher Stu<strong>de</strong>nten kamen, entstand das Bedürfnisnach e<strong>in</strong>er e<strong>in</strong>fachen Programmiersprache fü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 und THOMAS KURTZ vom DartmouthCollege <strong>in</strong> <strong>de</strong>n USA erfüllten 1964 mit BASIC diesen Bedarf. Der Gebrauch von BA-SIC 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-Dialekte gibt, dass BASIC die Unterschie<strong>de</strong> zwischen Betriebssystemund Programmiersprache verwischt und dass die meisten BASIC-Dialekte ke<strong>in</strong>eor<strong>de</strong>ntliche Programmstruktur ermöglichen und daher nur für kurze Programme brauchbars<strong>in</strong>d. Richtig ist aber auch, dass mo<strong>de</strong>rne BASIC-Dialekte wie HP-BASIC o<strong>de</strong>r Quick-BASIC von Microsoft über alle Hilfsmittel zur Strukturierung verfügen und dass <strong>in</strong> ke<strong>in</strong>eran<strong>de</strong>ren gängigen Programmiersprache die 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 Kenntnis von GW-BASIC auf <strong>de</strong>m PCreicht für e<strong>in</strong>en Programmierer nicht aus, aber für viele Aufgaben ist e<strong>in</strong> mo<strong>de</strong>rnes BASICe<strong>in</strong> brauchbares Werkzeug.Anfang <strong>de</strong>r sechziger Jahre wur<strong>de</strong> ALGOL 60 aufgrund theoretischer Überlegungen entwickeltund nach e<strong>in</strong>er umfangreichen Überarbeitung als ALGOL 68 veröffentlicht. DieseProgrammiersprache ist 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 heutigen Programmiersprachen beziehungsweise dieheutigen Fassungen älterer Sprachen. Viele Konzepte gehen auf ALGOL zurück.En<strong>de</strong> <strong>de</strong>r sechziger Jahre hatte sich das Programmieren vom Kunsthandwerk zur Wissenschaftentwickelt, und NIKLAUS WIRTH von <strong>de</strong>r ETH Zürich brachte PASCAL heraus,um se<strong>in</strong>en Stu<strong>de</strong>nten e<strong>in</strong>en anständigen Programmierstil anzugewöhnen. PASCAL ist e<strong>in</strong>estrenge und logisch aufgebaute Sprache, daher gut zum Lernen geeignet. Turbo-PASCAL4 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 nennenswerte Möglichkeiten zur Verarbeitungvon Str<strong>in</strong>gs.


1.1. GRUNDBEGRIFFE 9von Borland ist auf PCs weit verbreitet. E<strong>in</strong> PASCAL-Beispiel f<strong>in</strong><strong>de</strong>t sich <strong>in</strong> Abschnitt 1.4.3Parameterübergabe auf Seite 82. E<strong>in</strong>e Weiterentwicklung von PASCAL ist MODULA.Die Sprache C wur<strong>de</strong> von BRIAN KERNIGHAN, DENNIS RITCHIE und KEN THOMPSON <strong>in</strong><strong>de</strong>n siebziger Jahren entwickelt, um das Betriebssystem UNIX damit portabel zu gestalten.Lange Zeit h<strong>in</strong>durch gab das Buch <strong>de</strong>r bei<strong>de</strong>n Erstgenannten <strong>de</strong>n Standard vor 6 . In <strong>de</strong>nAchtzigern hat das American National Standards Institute (ANSI) an e<strong>in</strong>em Standard für Cgearbeitet, <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 ANSI/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 Standard ANSI/ISO/IEC 9899:1999 7veröffentlicht, <strong>de</strong>r auch als C9X bezeichnet wird. 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>en neuen Standard voll unterstützen.Das ANSI-C von 1990 ist im wesentlichen e<strong>in</strong>e Übermenge von K&R-C; die Nachführung<strong>de</strong>r Programme – wenn überhaupt erfor<strong>de</strong>rlich – macht ke<strong>in</strong>e Schwierigkeiten. ANSI-C kennte<strong>in</strong> Schlüsselwort von K&R nicht mehr (entry) und dafür mehrere neue.C ist allgeme<strong>in</strong> verwendbar, konzentriert, lässt <strong>de</strong>m Programmierer große Freiheiten (hav<strong>in</strong>gthe best parts of FORTRAN and assembly language <strong>in</strong> one place) und führt <strong>in</strong> <strong>de</strong>r Regelzu schnellen Programmen, da vielen C-Anweisungen unmittelbar Assembler-Anweisungenentsprechen (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-Programmegelten als unübersichtlich, aber das ist e<strong>in</strong>e Frage <strong>de</strong>s Programmierstils, nicht <strong>de</strong>r Sprache 8 .Auf UNIX-Systemen hat man mit C die wenigsten Schwierigkeiten. Für DOS-PCs gibt es vonMicrosoft das preiswerte Quick-C und aus <strong>de</strong>m GNU-Projekt e<strong>in</strong>en kostenlosen C-Compilerim Quellco<strong>de</strong> und betriebsklar kompiliert.Aus C hat BJARNE STROUSTRUP von 1979 bis 1989 e<strong>in</strong>e Sprache <strong>C++</strong> entwickelt, dieebenfalls 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 Lernphase e<strong>in</strong>planen muss,mehr als bei e<strong>in</strong>em Übergang von PASCAL nach C. Da sich ANSI-C und <strong>C++</strong> gleichzeitigentwickelt haben, 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 dasPrototyp<strong>in</strong>g. E<strong>in</strong> ANSI-C-Programm sollte von je<strong>de</strong>m <strong>C++</strong>-Compiler verstan<strong>de</strong>n wer<strong>de</strong>n; dasUmgekehrte gilt nicht. 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>, wagten sich die Programmierer ankomplexere und umfangreichere Aufgaben 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 Erfahrung und nicht auf Programmebeschränkt. Die Strukturierung e<strong>in</strong>er Aufgabe 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, verbreiteten sich.Um 1980 herum war die Komplexität wie<strong>de</strong>r so angewachsen, dass nach neuen Wegen zuihrer 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 preiswert herzustellen und dabe<strong>in</strong>och <strong>de</strong>ren Zuverlässigkeit sicherzustellen, ähnlich wie heutzutage Autos produziert wer-6 Das vergleichsweise schlanke Buch von K&R ist die erste Lektüre, sobald man e<strong>in</strong>facheC-Programme schreiben kann. Über die Beschreibung von C h<strong>in</strong>aus birgt es wertvolleallgeme<strong>in</strong>e H<strong>in</strong>weise zum Programmieren. Anmerkungen hat STEVE SUMMIT unterhttp://www.eskimo.com/˜scs/cclass/knotes/top.html veröffenlicht.7 Den Standard kann man sich bei www.ansi.org gegen 18 US-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>em Fall: Pr<strong>in</strong>ted <strong>in</strong> Karlsruhe.Hoffentlich geht das nicht so weiter.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übersichtlichsteC-Programm, siehe Abschnitt 1.12 Obfuscated C auf Seite 171.


10 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong><strong>de</strong>n. Zwei Schlagwörter kamen auf: Objektorientierung und Software Eng<strong>in</strong>eer<strong>in</strong>g. Entklei<strong>de</strong>tman sie <strong>de</strong>r merkantilen Übertreibungen, bleibt immer noch e<strong>in</strong> brauchbarer Kernvon I<strong>de</strong>en übrig.Der Typbegriff wur<strong>de</strong> zur Klasse erweitert. E<strong>in</strong>e Klasse enthält Variable und zugehörigeFunktionen, die nun Metho<strong>de</strong>n genannt wer<strong>de</strong>n. Klassen können im Gegensatz zumTyp 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, wobei höhere KlassenEigenschaften an niedrigere vererben. Klassen haben 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, ist bekannt,wie sie es tun, geht nieman<strong>de</strong>n etwas an. Diese scharfe Trennung von Innen und Außen istwesentlich 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>em großen Teil im Schreiben vonKlassen. Wie e<strong>in</strong>e Variable die Verwirklichung (Realisierung, Instantiierung) e<strong>in</strong>es Typs ist,so ist 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önnen beliebig viele Objekteabgeleitet wer<strong>de</strong>n. Klassen und <strong>de</strong>ren Objekte s<strong>in</strong>d die Bauste<strong>in</strong>e e<strong>in</strong>es objektorientiertenProgramms. <strong>C++</strong> hieß anfangs C mit Klassen.Neben <strong>C++</strong> ist e<strong>in</strong>e zweite objektorientierte Erweiterung von C entstan<strong>de</strong>n, die unter <strong>de</strong>mNamen Objective C <strong>in</strong> Verb<strong>in</strong>dung mit <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> wie Objective C, ansonsten istes ziemlich still gewor<strong>de</strong>n um diese Sprache.Es kommen noch e<strong>in</strong> paar D<strong>in</strong>ge h<strong>in</strong>zu, um das Programmieren zu erleichtern, aber dasWesentliche am objektorientierten Programmieren ist, dass die Aufgabe nicht mehr <strong>in</strong> Modulezerlegt wird, die aus Anweisungen bestehen, son<strong>de</strong>rn <strong>in</strong> vone<strong>in</strong>an<strong>de</strong>r unabhängige Objekte,die sich Mitteilungen o<strong>de</strong>r Botschaften schicken. Die Objektorientierung setzt bei <strong>de</strong>rAufgabenanalyse e<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>e neue, von C völlig unabhängigeSprache sei. An<strong>de</strong>re wie<strong>de</strong>rum betrachten <strong>C++</strong> als e<strong>in</strong>e umfangreiche Erweiterung vonC. Auf je<strong>de</strong>n Fall s<strong>in</strong>d die Kenntnisse, die man beim Lernen von C erworben hat, auch <strong>in</strong><strong>C++</strong> nützlich und ke<strong>in</strong>esfalls überholt. <strong>C++</strong>-Compiler übersetzen die meisten C-Programmeanstandslos. Zu fe<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 Karlsruhe um e<strong>in</strong>e Klassenbibliotheknamens C-XSC (Exten<strong>de</strong>d Scientific Calculation) mit Datentypen wie komplexen Zahlen,Vektoren, Matrizen und Intervallen samt <strong>de</strong>n zugehörigen Operationen ergänzt wor<strong>de</strong>n,siehe das Buch von RUDI KLATTE et al.SMALLTALK ist e<strong>in</strong>e von Grund auf neu entwickelte, streng objektorientierte 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 109 kennen):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 waren vermutlich C-Programmierer.Auf die übrigen 989 Programmiersprachen 10 soll aus Platzgrün<strong>de</strong>n nicht e<strong>in</strong>gegangenwer<strong>de</strong>n. Braucht man überhaupt mehrere Sprachen? E<strong>in</strong>ige Sprachen wie FORTRAN und9 SMALLTALK ist ungewohnt und sehr <strong>in</strong>teressant, auch für LINUX verfügbar.Näheres siehe www.software.ibm.com/ad/smalltalk/, www.exept.<strong>de</strong>/,www.cetus-l<strong>in</strong>ks.org/oo_smalltalk.html o<strong>de</strong>r www.gsug.org/.10 Real programmers can write FORTRAN programs <strong>in</strong> any language.


1.1. GRUNDBEGRIFFE 11COBOL s<strong>in</strong>d historisch bed<strong>in</strong>gt und wer<strong>de</strong>n wegen ihrer weiten Verbreitung noch lange leben.An<strong>de</strong>re Sprachen wie BASIC und C wen<strong>de</strong>n sich an unterschiedliche Benutzerkreise.Wie<strong>de</strong>rum an<strong>de</strong>re eignen sich für spezielle Aufgaben besser als allgeme<strong>in</strong>e Sprachen. Mit e<strong>in</strong>ere<strong>in</strong>zigen Sprache wird man auch <strong>in</strong> <strong>de</strong>r Zukunft nicht auskommen. Die Schwierigkeitenbeim Programmieren liegen 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 Formulierung und 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? Es gibt e<strong>in</strong>en Interpreter o<strong>de</strong>r Compilerfür diese Sprache auf diesem System (Hardware plus Betriebssystem). Die BezeichnungFORTRAN-Compiler für UNIX reicht nicht, da es UNIX für verschie<strong>de</strong>ne Hardware und zu<strong>de</strong>m<strong>in</strong> verschie<strong>de</strong>nen Versionen gibt. 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 geschriebene Programme wer<strong>de</strong>nals 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 nicht ausführbar. Der Quellco<strong>de</strong>muss mithilfe <strong>de</strong>s Computers und e<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 Programmierer nichts mehr anfangen.Es gibt zwei Arten von Übersetzern. Interpreter übersetzen das Programm je<strong>de</strong>smal,wenn es aufgerufen wird. Die Übersetzung wird nicht auf Dauer gespeichert. Da <strong>de</strong>r Quellco<strong>de</strong>zeilenweise bearbeitet wird, lassen sich Än<strong>de</strong>rungen schnell und e<strong>in</strong>fach ausprobieren.An<strong>de</strong>rerseits kostet die Übersetzung Zeit. Interpreter f<strong>in</strong><strong>de</strong>t man vorwiegend auf Home-Computern für BASIC, aber auch LISP-Programme, Shellscripts und awk-Scripts wer<strong>de</strong>n<strong>in</strong>terpretiert.Compiler übersetzen <strong>de</strong>n Quellco<strong>de</strong> e<strong>in</strong>es Programms als Ganzes und speichern dieÜbersetzung auf e<strong>in</strong>em permanenten Medium. Zur Ausführung <strong>de</strong>s Programms wird dieÜbersetzung aufgerufen. Bei <strong>de</strong>r kle<strong>in</strong>sten Än<strong>de</strong>rung muss das gesamte Programm erneutkompiliert 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 Programme laufen also schneller ab als <strong>in</strong>terpretierte. Es gibt auch Mischformenvon Interpretern und Compilern, zum Beispiel für JAVA. Wie wir e<strong>in</strong>gangs <strong>de</strong>s Kapitelsgesehen 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 die Präprozessor-Anweisungen (siehe Abschnitt1.9 Präprozessor auf Seite 129) aus. Ruft man <strong>de</strong>n Compiler mit <strong>de</strong>r Option -P auf, soerhält man die Ausgabe <strong>de</strong>s Präprozessors <strong>in</strong> e<strong>in</strong>er lesbaren 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, lesbarenAssemblerco<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>mal das 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 -c erhält man <strong>de</strong>n Masch<strong>in</strong>enco<strong>de</strong> (Objektco<strong>de</strong>, relocatableco<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, die e<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ührbaren Programm 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>enicht lesbare Datei mit <strong>de</strong>r Kennung .o.Unter UNIX wer<strong>de</strong>n üblicherweise Präprozessor, Compiler, Assembler und L<strong>in</strong>ker vone<strong>in</strong>em Compilertreiber aufgerufen, so dass <strong>de</strong>r Benutzer nichts von <strong>de</strong>n vier Schritten bemerkt.Man arbeitet mit <strong>de</strong>m Treiber cc(1), gcc(1) o<strong>de</strong>r CC(1) und erhält e<strong>in</strong> ausführbaresProgramm. Im Alltag me<strong>in</strong>t man <strong>de</strong>n Treiber, wenn man vom Compiler spricht.


12 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Üblicherweise erzeugt e<strong>in</strong> Compiler Masch<strong>in</strong>enco<strong>de</strong> für die Masch<strong>in</strong>e, auf <strong>de</strong>r er selbstläuft. Cross-Compiler h<strong>in</strong>gegen erzeugen Masch<strong>in</strong>enco<strong>de</strong> für an<strong>de</strong>re Systeme. Das ist gelegentlichnützlich.Der Name <strong>de</strong>s Programms im C-Quellco<strong>de</strong> hat die Kennung .c, <strong>in</strong> FORTRAN und PAS-CAL entsprechend .f und .p. Das kompilierte, aber noch nicht gel<strong>in</strong>kte Programm wird alsObjektco<strong>de</strong> o<strong>de</strong>r relozierbar (relocatable) bezeichnet, <strong>de</strong>r Date<strong>in</strong>ame hat die Kennung .oo<strong>de</strong>r .obj. Das lauffähige Programm heiß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 Programme durch .com o<strong>de</strong>r .exegekennzeichnet. E<strong>in</strong> kompiliertes Programm 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>ren System, wenn es <strong>in</strong> se<strong>in</strong>erausführbaren Form unter bei<strong>de</strong>n läuft.Hat sich e<strong>in</strong> Programm anstandslos kompilieren lassen und erzeugt beim Aufruf die FehlermeldungFile not found, dann liegt das fast immer daran, dass das Arbeitsverzeichnisnicht im Befehlspfad enthalten ist. Man ruft dann das neue Programm mit e<strong>in</strong>em Punkt alsPfadangabe auf:./myprogramund veranlasst so die Shell, das Programm im Arbeitsverzeichnis zu suchen. Alternativ könnteman auch <strong>de</strong>n Punkt <strong>in</strong> <strong>de</strong>n Pfad aufnehmen.Bei <strong>de</strong>n Operan<strong>de</strong>n spielt es e<strong>in</strong>e Rolle, ob ihre Eigenschaften vom Übersetzer bestimmtwer<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 Weg wird als statischeB<strong>in</strong>dung bezeichnet, <strong>de</strong>r dritte als dynamische B<strong>in</strong>dung. Die Größe e<strong>in</strong>er Ganzzahl (2 Bytes,4 Bytes) ist durch <strong>de</strong>n Compiler gegeben. Die Größe e<strong>in</strong>es Arrays könnte im Programmfestgelegt se<strong>in</strong> o<strong>de</strong>r während <strong>de</strong>r Ausführung berechnet wer<strong>de</strong>n. Es ist auch <strong>de</strong>nkbar, aber<strong>in</strong> C nicht zugelassen, <strong>de</strong>n Typ 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ßersteist, mit e<strong>in</strong>em Disassembler aus <strong>de</strong>m ausführbaren Co<strong>de</strong> Assemblerco<strong>de</strong> zu erzeugen,ohne Kommentar und typografische Struktur. Nur bei kurzen, e<strong>in</strong>fachen Programmenist dieser Assemblerco<strong>de</strong> verständlich.1.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ändlichfehlerfrei 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>ierte Fehlerfreiheit e<strong>in</strong>es Programmsnicht beweisen. Man kann nur – nach e<strong>in</strong>er Vielzahl von Tests und längerem Gebrauch –davon re<strong>de</strong>n, dass e<strong>in</strong> Programm zuverlässig ist, e<strong>in</strong> falsches Ergebnis also nur mit ger<strong>in</strong>gerWahrsche<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>gabe o<strong>de</strong>r <strong>de</strong>r Peripherievernünftig reagieren, nicht mit e<strong>in</strong>em Absturz. Das Schlimmste ist, wenn e<strong>in</strong> Programmtrotz e<strong>in</strong>es Fehlers e<strong>in</strong> sche<strong>in</strong>bar richtiges Ergebnis ausgibt. Die Fehlerbehandlung machtoft <strong>de</strong>n größeren Teil e<strong>in</strong>es Programmes aus und wird häufig vernachlässigt. Die Sprache Cerleichtert diese Aufgabe.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>ckungvon Fehlern, die Berücksichtigung neuer Wünsche, die Entwicklung <strong>de</strong>r Hardware, Bestrebungenzur Standardisierung und Lernvorgänge <strong>de</strong>r Programmierer führen dazu, dass Programmeimmer wie<strong>de</strong>r überarbeitet wer<strong>de</strong>n. Kle<strong>in</strong>ere Korrekturen wer<strong>de</strong>n durch Patchesbehoben, wörtlich Flicken. Das s<strong>in</strong>d Ergänzungen zum Co<strong>de</strong>, die nicht gleich e<strong>in</strong>e neue Versionrechtfertigen. Für manche Fehler lassen sich auch ohne Än<strong>de</strong>rung <strong>de</strong>s Co<strong>de</strong>s Umgehungenf<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 nichte<strong>in</strong>mal jährlich e<strong>in</strong>e Überarbeitung ersche<strong>in</strong>t, ist tot. Je<strong>de</strong> Woche e<strong>in</strong>e neue Version ist natürlichauch ke<strong>in</strong>e Empfehlung. Leichte Än<strong>de</strong>rbarkeit beruht auf Übersichtlichkeit, ausführlicherDokumentation und Vermeidung von Hardwareabhängigkeiten. Die Übersichtlichkeitwie<strong>de</strong>rum erreicht man durch e<strong>in</strong>e zweckmäßige Strukturierung, verständliche Namenswahl


1.1. GRUNDBEGRIFFE 13und Verzicht auf beson<strong>de</strong>re Tricks e<strong>in</strong>er Programmiersprache, die zwar erlaubt, aber nichtallgeme<strong>in</strong> bekannt s<strong>in</strong>d. Gera<strong>de</strong> C erlaubt viel, was nicht zur Übersichtlichkeit beiträgt.Än<strong>de</strong>rungen zu erleichtern kann auch heißen, Än<strong>de</strong>rungen von vornhere<strong>in</strong> zu vermei<strong>de</strong>n,<strong>in</strong><strong>de</strong>m man die Programmteile so allgeme<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 allem sparsamer Umgang mit <strong>de</strong>mArbeitsspeicher. Das ist heute immer noch e<strong>in</strong>e Tugend, tritt aber h<strong>in</strong>ter <strong>de</strong>n vorgenanntenKriterien zurück. Die mo<strong>de</strong>rne Software sche<strong>in</strong>t zur Unterstützung <strong>de</strong>r Chipherstellergeschrieben zu wer<strong>de</strong>n. An zweiter Stelle kam Ausfü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 sie mit E<strong>in</strong>fachheitund Übersichtlichkeit e<strong>in</strong>hergeht. Mit an<strong>de</strong>ren Worten: erst e<strong>in</strong> übersichtliches Programmschreiben und dann nach<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 Benutzer am Term<strong>in</strong>al will bei alltäglichenAufgaben ohne das Studium pfundschwerer Handbücher auskommen und bei <strong>de</strong>nhäufigsten Fehlern Hilfe vom Bildschirm erhalten. Er will an<strong>de</strong>rerseits auch nicht mit überflüssigenInformationen und nutzlosen Spielereien belästigt wer<strong>de</strong>n. Der Schwerpunkt <strong>de</strong>rProgrammentwicklung liegt heute weniger bei <strong>de</strong>n Algorithmen, son<strong>de</strong>rn bei <strong>de</strong>r Interaktionmit <strong>de</strong>m Benutzer. Für e<strong>in</strong>en Programmierer ist es nicht immer e<strong>in</strong>fach, sich <strong>in</strong> die Rollee<strong>in</strong>es EDV-Laien zu versetzen.Schließlich ist daran zu <strong>de</strong>nken, dass man e<strong>in</strong> Programm nicht nur für <strong>de</strong>n Computerschreibt, son<strong>de</strong>rn auch für an<strong>de</strong>re Programmierer. 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 vonmehreren Möglichkeiten, e<strong>in</strong>en Algorithmus o<strong>de</strong>r e<strong>in</strong>en komplexen Zusammenhang darzustellen.Der Quellco<strong>de</strong> sollte daher leicht zu lesen, programmiererfreundlich se<strong>in</strong>. For<strong>de</strong>rnwir also menschenfreundliche Programme.C lässt <strong>de</strong>m Programmierer viel Freiheit, mehr als PASCAL. Damit nun nicht je<strong>de</strong>rschreibt, wie ihm <strong>de</strong>r Schnabel gewachsen ist, hat die Programmierergeme<strong>in</strong>schaft Regelnund Gebräuche entwickelt. E<strong>in</strong> Verstoß dagegen bee<strong>in</strong>druckt <strong>de</strong>n Compiler nicht, aber dasProgramm ist mühsam zu lesen. Der Beautifier cb(1) automatisiert die E<strong>in</strong>haltung e<strong>in</strong>igerdieser 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,• B. W. KERNIGHAN, P. J. PLAUGER, Software Tools, siehe Anhang,• 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 1993vom Hochschuldidaktischen Zentrum und vom Fachgebiet Kybernetische Verfahrenund Didaktik <strong>de</strong>r Ingenieurwissenschaften <strong>de</strong>r RWTH Aachen im Auftrag von sechsChemiefirmen. Der Verbreitung dieser Richtl<strong>in</strong>ien stehen lei<strong>de</strong>r e<strong>in</strong> H<strong>in</strong>weis auf dasUrheberrecht sowie 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 Weisengelöst wer<strong>de</strong>n. Der e<strong>in</strong>e bevorzugt viele 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>enlangen 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 objektiven Ziele erreicht wer<strong>de</strong>n, istgegen e<strong>in</strong>en persönlichen Stil nichts e<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 andas Term<strong>in</strong>al und legt los. Beson<strong>de</strong>rs jugendliche BASIC-Programmierer neigen zu dieserProgrammiertechnik. Wenn man sich das nicht schnellstens abgewöhnt, kommt man nichtweit. Um wirkliche Programme zu schreiben, muss man systematisch vorgehen und viel Konzeptpapierverbrauchen, ehe es ans Hacken geht. Es gibt mehrere Vorgehensweisen. E<strong>in</strong>everbreitete sieht fünf Stufen vor (waterfall approach):


14 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>• Aufgabenstellung (Vorstudien, Analyse, Formulierung),• Entwurf (Struktur, Anpassen an Werkzeuge wie make(1), RCS, CVS),• Umsetzung <strong>in</strong> e<strong>in</strong>e Programmiersprache (Codierung, Implementation),• Test (Fehlersuche, Prüfungen, Messungen, Vergleich mit Punkt 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. Wenn die bei<strong>de</strong>n vorangehen<strong>de</strong>n Punkte schlecht erledigt wor<strong>de</strong>ns<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 manchmalfürchterlich aufhalten. Lassen wir Betrieb und Pflege als zeitlich unbegrenzt heraus,und nehmen wir an, dass das Schreiben <strong>de</strong>r Dokumentation parallel erfolgt, so lassen sichungefähr folgen<strong>de</strong> Anteile als Ausgangswerte fü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 Papier festzuhalten 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 Kommentarund 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 Arbeitstage Zeit und e<strong>in</strong>en Programmierer, so ergebensich 20 Arbeitstage ür die Codierung gleich 20 Modulen zu je 60 Zeilen Co<strong>de</strong>. Das s<strong>in</strong>d grobeWerte, aber sie reichen für e<strong>in</strong>e erste Abschätzung aus.Bei Texten kann man von e<strong>in</strong>er Seite pro Tag ausgehen. Liegt das Rohmaterial samt allenAbbildungen fertig vor, kommt man auch auf zehn Seiten pro Tag. Umgekehrt könnenschwierige Rechnungen o<strong>de</strong>r das Beschaffen exotischer Literatur e<strong>in</strong> Manuskript beliebigverzögern. Korrekturlesen, das Zusammenstellen e<strong>in</strong>es In<strong>de</strong>x und ähnliche ungeliebte Arbeitenkosten auch Zeit, unter Umstän<strong>de</strong>n Wochen.Die Programmentwicklung vollzieht sich <strong>in</strong> <strong>de</strong>r Praxis nicht so geradl<strong>in</strong>ig, wie es <strong>de</strong>r obigePlan vermuten lässt. Aus je<strong>de</strong>r Stufe kommen Rücksprünge <strong>in</strong> vorangegangene Stufenvor, man könnte auch von Rückkoppelungen sprechen. Dagegen ist nichts e<strong>in</strong>zuwen<strong>de</strong>n, esbesteht jedoch e<strong>in</strong>e Gefahr. Wenn man nicht Zwangsmaßnahmen ergreift – Schlussstrichezieht – erreicht das Programmierprojekt nie e<strong>in</strong>en <strong>de</strong>f<strong>in</strong>ierten Zustand. Programmierer verstehendas, Kaufleute und Kun<strong>de</strong>n nicht. Gilt auch für Buchmanuskripte.Der steigen<strong>de</strong> Bedarf an Software und ihre wachsen<strong>de</strong> Komplexität verlangen die Entwicklungvon Programmierverfahren, mit <strong>de</strong>nen durchschnittliche Programmierer zuverlässigeProgramme entwickeln. Auf geniale Real Programmers alle<strong>in</strong> kann sich ke<strong>in</strong>e Firma verlassen.Die Entwicklung dieser Programmiertechnik (Software Eng<strong>in</strong>eer<strong>in</strong>g) ist noch nichtabgeschlossen.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 mathematischenGleichung. Zu<strong>de</strong>m s<strong>in</strong>d sie anfangs oft pauschal abgefasst, da <strong>de</strong>m Aufgabensteller 11E<strong>in</strong>zelheiten noch nicht klar s<strong>in</strong>d.11 Real programmers know better than the users what they need.


1.1. GRUNDBEGRIFFE 15Auf <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 Erfahrungund <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 die Formulierung <strong>de</strong>r Aufgabe.Zu diesem Schritt kehrt man im Verlauf <strong>de</strong>s Programmierens immer wie<strong>de</strong>r zurück,um zu ergänzen o<strong>de</strong>r zu berichtigen. Es ist realistisch, für die Aufgabenanalyse rund 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 Pflichtenheftschriftlich festgehalten, das zur Verständigung zwischen Entwickler und Anwen<strong>de</strong>r sowie<strong>de</strong>r Entwickler untere<strong>in</strong>an<strong>de</strong>r dient. Fragen <strong>in</strong> diesem Zusammenhang s<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>r Umsetzung <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 dannheraus, dass die 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>ewird.Nach unserer Erfahrung sollte man e<strong>in</strong>e Aufgabe zunächst e<strong>in</strong>mal so formulieren, wiesie <strong>de</strong>n augenblicklichen Bedürfnissen entspricht. Dann sollte man sich mit viel Phantasieausmalen, was alles noch dazu kommen könnte, wenn Geld, Zeit und Verstand ke<strong>in</strong>e Schrankensetzen wür<strong>de</strong>n (I have a dream ... ). Drittens streiche man von diesem Traum gna<strong>de</strong>nlosalles weg, was nicht unbed<strong>in</strong>gt erfor<strong>de</strong>rlich und absolut m<strong>in</strong>imal notwendig ist – ohne dasvielleicht nur asymptotisch erreichbare Ziel aus <strong>de</strong>n Augen zu verlieren. So kommt man mitbeschränkten Mitteln zu Software, die sich entwickeln kann, wenn die Zeit dafür reif ist.Anpassungsfähigkeit ist für Software und Lebewesen wichtiger 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). Komplexe Aufgaben wer<strong>de</strong>n <strong>in</strong> mehreren Stufen <strong>in</strong> Teilaufgabenzerlegt, die überschaubar s<strong>in</strong>d und sich durch e<strong>in</strong>e Funktion o<strong>de</strong>r Prozedur im Programmlösen lassen. Insofern spiegelt die Zerlegung bereits die spätere Programmstruktur 12 wi<strong>de</strong>r.Das Hauptprogramm soll möglichst wenig selbst erledigen, son<strong>de</strong>rn nur Aufrufe vonUnterprogrammen enthalten und somit die groß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ät wesentlich zu erhöhen– allgeme<strong>in</strong>er formulieren lassen. Damit lässt sich die Verwendbarkeit von Programmteilenverbessern. Diese Strategie wird als Top-down-Entwurf bezeichnet. Man geht vomAllgeme<strong>in</strong>en <strong>in</strong>s E<strong>in</strong>zelne.12 Real programmers disda<strong>in</strong> structured programm<strong>in</strong>g.


16 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.1.9.3 Zusammensetzen aus TeilaufgabenDer umgekehrte Weg – Bottom-up-Entwurf – liegt nicht so nahe. 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 zu e<strong>in</strong>em großen Teil zusammensetzen,so dass nur wenige spezielle Teilaufgaben ü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 zerlegt die übergeordnete Aufgabe<strong>in</strong> Teilaufgaben, versucht diese <strong>in</strong> Grundoperationen auszudrücken und kommt dannwie<strong>de</strong>r aufsteigend zu e<strong>in</strong>er genaueren und allgeme<strong>in</strong>er gültigen Formulierung. Dieser AbundAufstieg kann sich mehrmals wie<strong>de</strong>rholen. Die Aufgabenstellung ist nicht unverän<strong>de</strong>rlich.Genau so geht 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 Eigenheitene<strong>in</strong>es Computers o<strong>de</strong>r e<strong>in</strong>er Programmiersprache anzupassen. Der Benutzer hat Anspruchauf e<strong>in</strong> gut und verständlich funktionieren<strong>de</strong>s Programm. Die Zeiten, als <strong>de</strong>r Computer alsEntschuldigung für alle möglichen Unzulänglichkeiten herhalten musste, s<strong>in</strong>d vorbei.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 an das Programm zu Beg<strong>in</strong>nnoch 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> Skelett zu haben. Mit diesem kann man dann spielen und Erfahrungen sammeln <strong>in</strong> e<strong>in</strong>emStadium, <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 benutzernahen Funktionen halbwegs ausgebaut,die datennahen Funktionen schreiben vorläufig nur ihren Namen auf <strong>de</strong>n Bildschirm.Von e<strong>in</strong>em menugesteuerten Vokabeltra<strong>in</strong>er beispielsweise schreibt man zunächst das Menusystemund lässt die Funktionen, die die eigentliche Arbeit erledigen, leer o<strong>de</strong>r beschränktsie auf die Ausgabe 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übergabe und-rückgabe), immer noch mit Bildschirmmeldungen anstelle <strong>de</strong>r eigentlichen Arbeit. Funktioniertauch das wie gewü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öglichst frühen Zeitpunkt <strong>in</strong> diegewünschte Richtung. Bei e<strong>in</strong>em kommerziellen Auftrag bezieht sie <strong>de</strong>n Auftraggeber <strong>in</strong> dieEntwicklung e<strong>in</strong> und för<strong>de</strong>rt das gegenseitige Verständnis, aber auch bei privaten Projektenverh<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 Programmieraufgaben das beste Mo<strong>de</strong>ll – es gibtauch 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 Anwendungen rechtbrauchbar und <strong>in</strong> C leicht zu verwirklichen.1.1.11 FlussdiagrammeProgramme wer<strong>de</strong>n schnell unübersichtlich. Man hat daher schon früh versucht, mit Hilfegrafischer 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 Papier auf zwei Dimensionen.Es ist unmöglich, e<strong>in</strong> umfangreiches Programm durch e<strong>in</strong>e e<strong>in</strong>zige halbwegs überschaubareGrafik zu beschreiben.Flussdiagramme (flow chart), auch Blockdiagramme genannt, sollen die Abläufe <strong>in</strong>nerhalbe<strong>in</strong>es Programmes durch S<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> erstelltwer<strong>de</strong>n sollte, halten sich viele Programmierer nicht an diese Reihenfolge. Zum Teil ersetzte<strong>in</strong>e gute typografische Gestaltung <strong>de</strong>r Programmquelle auch e<strong>in</strong> Flussdiagramm, währenddas Umgekehrte nicht gilt. E<strong>in</strong> Flussdiagramm ist nicht mit e<strong>in</strong>em Syntaxdiagramm zu verwechseln,lesen Sie 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.13 Real programmers don’t draw flowcharts.


1.1. GRUNDBEGRIFFE 17true✑◗✑ ◗◗✑✑◗◗Bed<strong>in</strong>gung✑◗◗ ✑✑◗ ✑falseAnweisung 1Anweisung 2 Anweisung 4Anweisung 3Abb. 1.1: Flussdiagramm e<strong>in</strong>er if-else-Verzweigung❛ ❛❛❛❛❛❛❛❛❛❛❛❛❛if Bed<strong>in</strong>gungthen✦✦ ✦✦✦✦✦✦✦✦✦✦✦✦ elseAnweisung 1Anweisung 2Anweisung 4Anweisung 3Abb. 1.2: Nassi-Shnei<strong>de</strong>rman-Diagramm e<strong>in</strong>er if-else-Verzweigung


18 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Nassi-Shnei<strong>de</strong>rman-Diagramme o<strong>de</strong>r Struktogramme nach ISAAC NASSI und BENSHNEIDERMAN s<strong>in</strong>d e<strong>in</strong> weiterer Versuch, <strong>de</strong>n Programmablauf grafisch darzustellen. Sies<strong>in</strong>d näher an e<strong>in</strong>e Programmiersprache angelehnt, so dass es leicht fällt, nach <strong>de</strong>m Diagramme<strong>in</strong>e Quelle zu schreiben. Das lässt sich teilweise sogar mit CASE-Werkzeugen <strong>in</strong>bei<strong>de</strong> Richtungen automatisieren.1.1.12 Memo Grundbegriffe• Masch<strong>in</strong>en verstehen nur Masch<strong>in</strong>ensprache, die hardwareabhängig und für Menschenunverständlich ist.• Programmierer verwen<strong>de</strong>n höhere, an die Aufgaben angepasste Programmiersprachen,die für Masch<strong>in</strong>en unverständlich s<strong>in</strong>d. Was sie schreiben, wird Quelle (source) genannt.• Übersetzer (Compiler, Interpreter) übersetzen Quelltexte höherer Programmiersprachen<strong>in</strong> Masch<strong>in</strong>ensprache. Der umgekehrte 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, COBOLund C zum imperativen Zweig, 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>n Komplexität <strong>de</strong>r Programmefertig 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ündlichen Analyse <strong>de</strong>r Aufgabe.Die Umsetzung <strong>in</strong> e<strong>in</strong>e Programmiersprache (Codierung) ist dann vergleichsweiseharmlos.• E<strong>in</strong> Programm soll nicht nur die zugrun<strong>de</strong>liegen<strong>de</strong> Aufgabe richtig lösen, son<strong>de</strong>rn auchgegen Fehler und Ausnahmen unempf<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 wird durch e<strong>in</strong>e gute Struktur undreichlich 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 mehreren Teilstrecken mit unterschiedlichenGegebenheiten. Sie wollen wissen, was es br<strong>in</strong>gt und kostet, wenn Sie e<strong>in</strong>zelneTeilstrecken schneller o<strong>de</strong>r langsamer zurücklegen.Sie brauchen also e<strong>in</strong> Programm zur Analyse Ihres Arbeitsweges. Formulieren Sie dieAufgabe genauer, zerlegen Sie sie <strong>in</strong> Teilaufgaben, beschreiben Sie die E<strong>in</strong>- und Ausgabe,berücksichtigen Sie Fehler <strong>de</strong>s Benutzers. Aus welchen Größen besteht die Ausgabe, welcheE<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 sollten e<strong>in</strong>ige Blätter Papier mit Worten, Formeln und Skizzen se<strong>in</strong>, nach <strong>de</strong>nene<strong>in</strong> Programmierer arbeiten könnte. Sie selbst sollen an dieser Stelle noch nicht an e<strong>in</strong>eProgrammiersprache <strong>de</strong>nken.Falls Ihnen die Übung zu e<strong>in</strong>fach ersche<strong>in</strong>t, machen Sie dasselbe für e<strong>in</strong>en Vokabeltra<strong>in</strong>er,<strong>de</strong>r außer Deutsch zwei Fremdsprachen beherrscht. 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, diezum Programmieren benötigt wer<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) und die Revisionskontrolles<strong>in</strong>d auch bei Projekten außerhalb <strong>de</strong>r Programmierung nützlich, vor allem beim Bearbeitenumfangreicher Manuskripte.


1.2. PROGRAMMER’S WORKBENCH 191.2.1 Nochmals die EditorenEditoren wur<strong>de</strong>n bereits im UNIX-Kapitel, Abschnitt ?? Writer’s Workbench auf Seite ?? erläutert.Hier geht es nur um e<strong>in</strong>ige weitere Eigenschaften <strong>de</strong>s Editors vi(1), die beim Schreibenvon Programmquellen von Belang s<strong>in</strong>d.Im Quellco<strong>de</strong> wer<strong>de</strong>n üblicherweise Schleifenrümpfe und <strong>de</strong>rgleichen um e<strong>in</strong>e Tabulatorbreitee<strong>in</strong>gerückt, die als Default 8 Leerzeichen entspricht. Bei geschachtelten Schleifenstößt <strong>de</strong>r Text schnell an <strong>de</strong>n rechten Seitenrand. Es empfiehlt sich, <strong>in</strong> <strong>de</strong>m entsprechen<strong>de</strong>nVerzeichnis 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>r E<strong>in</strong>gabe e<strong>in</strong>er rechtenKlammer kurz zur zugehörigen l<strong>in</strong>ken Klammer zu spr<strong>in</strong>gen. Die Option number führt zurAnzeige <strong>de</strong>r Zeilennummern, die jedoch nicht Bestandteil <strong>de</strong>s Textes wer<strong>de</strong>n. E<strong>in</strong>e Zeileset lisp ist e<strong>in</strong>e Hilfe beim E<strong>in</strong>geben von LISP-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 Gegenklammerspr<strong>in</strong>gen und dort verbleiben.Auch beim emacs(1) gibt es e<strong>in</strong>ige Wege, das Schreiben von Quellen zu erleichtern, <strong>in</strong>sbeson<strong>de</strong>renatürlich, falls es um LISP geht. Der Editor nedit(1) lässt sich auf <strong>de</strong>n Stilaller gängigen Programmiersprachen 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 vollständige UNIX-System enthält e<strong>in</strong>en C-Compiler; Compiler für weitere Programmiersprachens<strong>in</strong>d optional. Auf unserer Anlage s<strong>in</strong>d zusätzlich e<strong>in</strong> FORTRAN- und e<strong>in</strong>PASCAL-Compiler vorhan<strong>de</strong>n, wobei von FORTRAN gegenwärtig die Versionen 77 und 90nebene<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 auchnoch die Be<strong>de</strong>utung von plün<strong>de</strong>rn. In unseren 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 meistenProgramme enthalten Aufrufe von externen Programmodulen, die bereits vorübersetztund <strong>in</strong> Bibliotheken zusammengefaßt s<strong>in</strong>d. Beispiele s<strong>in</strong>d Ausgaberout<strong>in</strong>en o<strong>de</strong>r mathematischeFunktionen. 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 Programm entsteht. Esgibt die Möglichkeit, die externen Module erst zur Laufzeit h<strong>in</strong>zuzunehmen; das heißt dynamischesL<strong>in</strong>ken und spart Speicherplatz. Dabei wer<strong>de</strong>n die Module entwe<strong>de</strong>r beim La<strong>de</strong>n<strong>de</strong>s Programms <strong>in</strong> <strong>de</strong>n Arbeitsspeicher o<strong>de</strong>r erst bei ihrem Aufruf h<strong>in</strong>zugela<strong>de</strong>n (load on <strong>de</strong>mand).Benutzen mehrere Programme 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 kommt man zu <strong>de</strong>n Shared Librariesund spart nochmals Speicherplatz.Die Aufrufe lauten cc(1), f77(1), f90(1) und pc(1). Diese Kommandos rufen Compilertreiberauf, die ihrerseits die eigentlichen Compiler /lib/ccom, f77comp, f90comp undpascomp starten und noch weitere D<strong>in</strong>ge erledigen. Ohne Optionen rufen die Compilertreiberauch 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>m Namen a.out(4) sollte man nurvorübergehend arbeiten (mit mv(1) än<strong>de</strong>rn). Der Aufruf <strong>de</strong>s C-Compilers sieht beispielsweiseso aus:14 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 zwischenB<strong>in</strong><strong>de</strong>r und Loa<strong>de</strong>r unterschie<strong>de</strong>n, soll uns hier nicht beschäftigen.


20 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>cc source.ccc -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>en um gängige Optionen erweiterten.Die Option -g veranlaßt <strong>de</strong>n Compiler, zusätzliche Informationen für <strong>de</strong>n symbolischenDebugger zu 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 die Option 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 Datei mon.out, das mit <strong>de</strong>mProfiler prof(1) ausgewertet wer<strong>de</strong>n kann, um Zeit<strong>in</strong>formationen zum Programm zuerhalten,• -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 Namentragen kann, nur sollte <strong>de</strong>r Name mit <strong>de</strong>r Kennung .c en<strong>de</strong>n. Die anschließen<strong>de</strong> Option-lm for<strong>de</strong>rt <strong>de</strong>n L<strong>in</strong>ker auf, die mathematische Standard-Bibliothek e<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>n L<strong>in</strong>ker und teilt ihm mit, dass sich im Verzeichnis./lib weitere Bibliotheken bef<strong>in</strong><strong>de</strong>n. Die Reihenfolge, <strong>in</strong> <strong>de</strong>r Bibliotheken e<strong>in</strong>gebun<strong>de</strong>nwer<strong>de</strong>n, ist wichtig. Die Option -I. veranlasst <strong>de</strong>n Präprozessor, Inclu<strong>de</strong>-Dateien auch imaktuellen Verzeichnis zu suchen, 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 symbolischeKonstante 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 namens l<strong>in</strong>t(1), <strong>de</strong>n man unbed<strong>in</strong>gtverwen<strong>de</strong>n sollte. Er reklamiert nicht 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 geschrieben hat. Man muß se<strong>in</strong>enKommentar 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 sich bei <strong>de</strong>r University of Virg<strong>in</strong>iaunter: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 kann man <strong>de</strong>n Compiler gcc(1)mit e<strong>in</strong>er Option aufrufen, die ihn nur 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>en Beautifier namens cb(1),<strong>de</strong>r <strong>de</strong>n Text <strong>in</strong> e<strong>in</strong>e standardisierte Form mit E<strong>in</strong>rückungen usw. br<strong>in</strong>gt und die Lesbarkeiterleichtert:cb source.c > source.bWenn man mit <strong>de</strong>m Ergebnis source.b zufrie<strong>de</strong>n ist, löscht man die ursprüngliche Dateisource.c und benennt source.b <strong>in</strong> source.c um.


1.2. PROGRAMMER’S WORKBENCH 211.2.3 Unentbehrlich (make)Größere Programme s<strong>in</strong>d stark geglie<strong>de</strong>rt und auf mehrere bis viele Dateien und Verzeichnisseverteilt. Der Compileraufruf wird dadurch länglich, und die Wahrsche<strong>in</strong>lichkeit, etwaszu vergessen, steigt. Hier hilft make(1). Man schreibt e<strong>in</strong>mal alle Angaben für <strong>de</strong>n Compiler<strong>in</strong> e<strong>in</strong> makefile (auch Makefile) und ruft dann zum Kompilieren nur noch make(1)auf. Für Manuskripte ist make(1) ebenfalls zu gebrauchen. Statt Makefiles ließen sich auchShellskripte e<strong>in</strong>setzen, die Stärke von make(1) liegt jedoch im Umgang mit Dateien unterBeachtung <strong>de</strong>s Zeitstempels mtime (jüngster schreiben<strong>de</strong>r Zugriff). Werkzeuge wie make(1)wer<strong>de</strong>n als Buil<strong>de</strong>r bezeichnet.Man lege für das Projekt e<strong>in</strong> eigenes Unterverzeichnis an, <strong>de</strong>nn make(1) sucht zunächstim Arbeits-Verzeichnis. Das makefile 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 Kommandozeilen zu ihrer Erzeugung. E<strong>in</strong> e<strong>in</strong>fachesmakefile sieht so aus (Zeilen mit Kommandos müssen durch e<strong>in</strong>en Tabulatorstop –nicht durch 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.cund ist folgen<strong>de</strong>rmaßen zu verstehen:Quelle 1.7 : E<strong>in</strong>faches Makefile• Das ausführbare Programm (Ziel, Target) namens pgm hängt ab von <strong>de</strong>n Modulen imObjektco<strong>de</strong> a.o und b.o. Es entsteht 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 imQuellco<strong>de</strong> a.c. Es entsteht durch <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: erst wer<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 Doppelkreuz und 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 Programmodule und paßt auf, daße<strong>in</strong>e neue Version <strong>in</strong> alle betroffenen Programmteile 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 Beispieldie <strong>in</strong>clu<strong>de</strong>-Datei <strong>in</strong>cl.h ausdrücklich genannt? Der Compiler weiß doch auf Grun<strong>de</strong><strong>in</strong>er entsprechen<strong>de</strong>n Zeile im Quelltext, daß diese Datei e<strong>in</strong>zub<strong>in</strong><strong>de</strong>n ist? Richtig, abermake(1) muß das auch wissen, <strong>de</strong>nn die <strong>in</strong>clu<strong>de</strong>-Datei könnte sich än<strong>de</strong>rn, und dann müssenalle von ihm 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 wie stdio.h brauchen nicht im makefile aufgeführt zu wer<strong>de</strong>n.Nun e<strong>in</strong> etwas umfangreicheres Beispiel, das aber längst noch nicht alle Fähigkeiten vonmake(1) ausreizt:# Kommentar, wie ueblichCC = /b<strong>in</strong>/ccCFLAGS =FC = /usr/b<strong>in</strong>/f77LDFLAGS = -lclall: csumme fsumme clean


22 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>csumme: 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 Compileraufruf CC. Überall, wo im Makefiledas Makro mittels $(CC) aufgerufen wird, wird es vor <strong>de</strong>r Ausführung wörtlich ersetzt.Auf diese Weise kann man e<strong>in</strong>fach e<strong>in</strong>en an<strong>de</strong>ren Compiler wählen, ohne im ganzen Makefileper Editor ersetzen zu müssen. Dann haben wir e<strong>in</strong> Dummy-Ziel all, das aus e<strong>in</strong>er Aufzählungweiterer Ziele besteht. Mittels make all wird dieses Dummy-Ziel erzeugt, d. h. dieaufgezählten Ziele. Unter diesen bef<strong>in</strong><strong>de</strong>t sich auch e<strong>in</strong>es namens clean, das ohne Zutatendaherkommt und offenbar nur bestimmte Tätigkeiten wie das Löschen temporärer Dateienbezweckt. E<strong>in</strong> Dummy-Ziel ist immer out-of-date, die zugehörigen Kommandos wer<strong>de</strong>nimmer ausgeführt.make(1) darf rekursiv aufgerufen wer<strong>de</strong>n, e<strong>in</strong> Makefile darf make-Aufrufe enthalten, diesich 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 un<strong>de</strong>rzeugt 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>s Skriptum, daskomplett als Report formatiert wer<strong>de</strong>n soll, dazu noch die Kapitel <strong>in</strong> jeweils e<strong>in</strong>em eigenenUnterverzeichnis als Artikel samt Folien. Natürlich s<strong>in</strong>d die Makefiles <strong>in</strong> <strong>de</strong>n Unterverzeichnissenweiche 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>ne Systeme veröffentlicht. In<strong>de</strong>r Regel muß man die Quellen auf <strong>de</strong>r eigenen Anlage kompilieren. Infolge<strong>de</strong>ssen gehörenzu <strong>de</strong>n GNU-Programmen fast immer umfangreiche Makefiles o<strong>de</strong>r sogar Hierarchien davon.Übung im Gebrauch von make(1) erleichtert die E<strong>in</strong>richtung von GNU-Software daher erheblich.Oft wird e<strong>in</strong> an das eigene System angepaßtes Makefile erst durch e<strong>in</strong> Kommando./configure erzeugt. Die Reihenfolge bei solchen Programme<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 Verzeichnissen erfor<strong>de</strong>rt, also meistSuperuserrechte. Gelegentlich wird make(1) aus e<strong>in</strong>em Shellskript heraus aufgerufen, dase<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 mitgeliefertenShellskripts Build erzeugt.


1.2. PROGRAMMER’S WORKBENCH 23Das Skript configure erlaubt oft die Option -prefix=DIR, wobei DIR das Verzeichnisist, <strong>in</strong> <strong>de</strong>m das ganze Gerö<strong>de</strong>l e<strong>in</strong>gerichtet wer<strong>de</strong>n soll, <strong>de</strong>faultmäßig meist /usr/local,aber manchmal besser /usr o<strong>de</strong>r /opt. Da von configure alles Weitere abhängt, sollteman sich die zugehörige Protokoll-Datei config.log ansehen, auch wenn ansche<strong>in</strong>end ke<strong>in</strong>eProbleme aufgetreten s<strong>in</strong>d.Statt make clean kann man auch make distclean versuchen, das räumt noch gründlicherauf, so daß h<strong>in</strong>terher wie<strong>de</strong>r mit ./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 gibt ke<strong>in</strong>e Möglichkeit, die Fehlerfreiheite<strong>in</strong>es Programmes festzustellen o<strong>de</strong>r zu beweisen außer <strong>in</strong> trivialen o<strong>de</strong>r i<strong>de</strong>alenFällen.Die Fehler lassen sich <strong>in</strong> drei Klassen e<strong>in</strong>teilen. Verstöße gegen die Regeln <strong>de</strong>r jeweiligenProgrammiersprache heißen Grammatikfehler o<strong>de</strong>r Syntaxfehler. Sie führen bereitszu e<strong>in</strong>em Abbruch <strong>de</strong>s Kompiliervorgangs und lassen sich schnell lokalisieren und beheben.Der C-Syntax-Prüfer l<strong>in</strong>t ist das beste Werkzeug zu ihrer Ent<strong>de</strong>ckung. wihle statt whilewä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>d auch beliebt, <strong>de</strong>shalbenthält <strong>de</strong>r vi(1) e<strong>in</strong>e Funktion zur Klammerprüfung. Unzulässige Operationen mitPo<strong>in</strong>tern s<strong>in</strong>d ebenfalls an <strong>de</strong>r Tagesordnung. Geht es um Texte, so fallen Tippfehler undGrammatikfehler <strong>in</strong> diese Klasse.Falls das Programm die Kompilation ohne Fehlermeldung h<strong>in</strong>ter sich gebracht hat, startetman es. Dann mel<strong>de</strong>n sich die Laufzeitfehler, die unter Umstän<strong>de</strong>n nur bei bestimmtenund womöglich seltenen Parameterkonstellationen auftreten. E<strong>in</strong> typischer Laufzeitfehlerist die Division durch e<strong>in</strong>e Variable, die manchmal <strong>de</strong>n Wert Null annimmt. Die Fehlermeldunglautet Float<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>r Laufzeitfehler ist dieÜberschreitung von Arraygrenzen o<strong>de</strong>r die Verwechslung von Variablen und Po<strong>in</strong>tern, waszu e<strong>in</strong>em Memory fault, 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 semantischeFehler genannt. Das Programm arbeitet e<strong>in</strong>wandfrei, nur tut es nicht das, wassich <strong>de</strong>r Programmierer vorgestellt hat. E<strong>in</strong> typischer Denkfehler ist das Verzählen bei <strong>de</strong>nElementen e<strong>in</strong>es Arrays o<strong>de</strong>r bei Schleifendurchgängen um genau e<strong>in</strong>s. Hier hilft <strong>de</strong>r Computernur wenig, da <strong>de</strong>r Ärmste ja gar nicht weiß, was sich <strong>de</strong>r Programmierer vorstellt. DieseFehler kosten viel Mühe, doch solcherlei Verdrüsse pflegen die Denkungskräfte anzuregen,me<strong>in</strong>t WILHELM BUSCH 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>ll zur Beschreibung e<strong>in</strong>es realen Problems ungeeignetist, mag das Programm so fehlerarm se<strong>in</strong> wie es will, se<strong>in</strong>e Ergebnisse gehen an <strong>de</strong>r Wirklichkeitvorbei. Für bestimmte Zwecke ist e<strong>in</strong>e Speisekarte e<strong>in</strong> brauchbares Mo<strong>de</strong>ll e<strong>in</strong>erMahlzeit, für an<strong>de</strong>re nicht.In diese Klasse fallen auch Fehler, die dadurch entstehen, dass wir im Computer stetsmit Zahlen endlicher Länge rechnen, während <strong>in</strong> Wirklichkeit die Zahl π unendlich viele Dezimalstellenhat und gemessene Größen statistischen Schwankungen unterliegen, also unscharfbegrenzte Intervalle darstellen. Grundkenntnisse <strong>in</strong> mo<strong>de</strong>rner numerischer Mathematikbewahren vor bl<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>nKlassen s<strong>in</strong>nvoll zugeordnet wer<strong>de</strong>n können, ist noch zu überlegen. Dann gibt esnoch <strong>de</strong>n Fehler Thema verfehlt, <strong>de</strong>r vielleicht zum Mo<strong>de</strong>ll-Fehler passt. H<strong>in</strong>tergrund dieserGedanken ist die Anwendung von Software-Werkzeugen <strong>in</strong> Text-Projekten, was erwiesenermaßendie Arbeit erleichtert.15 Es irrt <strong>de</strong>r Mensch, so lang er strebt. GOETHE, Faust. O<strong>de</strong>r errare humanum est, wie wirLate<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 Kombysis können wir lei<strong>de</strong>r ausMangel an e<strong>in</strong>em TeX-Font vorläufig nicht wie<strong>de</strong>rgeben. In <strong>de</strong>r nächsten Auflage wer<strong>de</strong>n wirjedoch e<strong>in</strong>e e<strong>in</strong>gescannte Zeichnung aus <strong>de</strong>r Höhle von Rienne-Vaplus zeigen, die als ältesteDokumentation obiger Weisheit gilt.


24 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>E<strong>in</strong> Fehler wird im Englischen auch als bug bezeichnet, was soviel wie Wanze o<strong>de</strong>r Lausbe<strong>de</strong>utet. E<strong>in</strong> Programm zu entlausen heiß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 Kontrolle das verlausteProgramm abläuft. Man hat dabei vielfältige Möglichkeiten, <strong>in</strong> <strong>de</strong>n Ablauf e<strong>in</strong>zugreifen. E<strong>in</strong>absoluter Debugger wie <strong>de</strong>r adb(1) bezieht sich dabei auf das lauffähige Programm imArbeitsspeicher – nicht auf <strong>de</strong>n Quellco<strong>de</strong> – und ist somit für die meisten Aufgaben weniggeeignet. E<strong>in</strong> symbolischer Debugger 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 hilfreicheWerkzeuge. Manche Programmierer gehen 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 Blattes Papier ansehen. In <strong>de</strong>r Übungwird 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>nund vertreiben können, möchten wir Ihnen noch e<strong>in</strong> altes Hausrezept verraten, das aus e<strong>in</strong>erHandschrift <strong>de</strong>s 9. Jahrhun<strong>de</strong>rts stammt. Das Rezept ist im Raum Wien – Münchenentstan<strong>de</strong>n und unter <strong>de</strong>n Namen Contra vermes o<strong>de</strong>r Pro nescia bekannt. Lei<strong>de</strong>r ist dieREADME-Datei, welche die Handhabung erklärt, verlorengegangen. Wir schlagen vor, die Zeilenals Kommentar <strong>in</strong> das Programm e<strong>in</strong>zufügen. Hier <strong>de</strong>r Text: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 Programmablä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 1000000Die 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 prim 30.65 s betrug, davon entfielen22.53 s auf die Ausführung von Benutzeranweisungen und 1.07 s auf Systemtätigkeiten. DieAusgabe wur<strong>de</strong> durch e<strong>in</strong>en Aufruf <strong>de</strong>s Primzahlenprogramms aus <strong>de</strong>m Skriptum Programmieren<strong>in</strong> C/<strong>C++</strong> erzeugt, das selbst Zeiten mittels <strong>de</strong>s Systemaufrufs time(2) misst undrund 22 s fü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 setzt voraus, daß das Programmmit <strong>de</strong>r Option -G kompiliert wor<strong>de</strong>n ist. Es wird gestartet und erzeugt neben se<strong>in</strong>er normalenAusgabe e<strong>in</strong>e Datei gmon.out, das mit gprof(1) betrachtet wird. Besser noch lenktman die Ausgabe von gprof(1) <strong>in</strong> e<strong>in</strong>e Datei um, 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.16 Real programmers don’t use source language <strong>de</strong>buggers.


1.2. PROGRAMMER’S WORKBENCH 25seconds 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 $$remU22.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 aufgerufen wird und 4,87 s verbrät. Diebei<strong>de</strong>n ersten Funktionen wer<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 Systemaufruf times(2), <strong>de</strong>n Debugger o<strong>de</strong>r dasUNIX-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 immer wie<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, Datenbankfunktionen o<strong>de</strong>rFunktionen zur Abfrage von Meßgeräten am Bus.Damit man diese Funktionen nicht je<strong>de</strong>smal neu zu erf<strong>in</strong><strong>de</strong>n braucht, wer<strong>de</strong>n sie <strong>in</strong> Bibliothekengepackt, die <strong>de</strong>m Programmierer zur Verfügung stehen. Teils stammen sie vomHersteller <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 <strong>de</strong>r Anwendungssoftware, teils von Benutzern. Bibliothekenenthalten Programmbauste<strong>in</strong>e, es lassen sich aber auch an<strong>de</strong>re Dateien (Texte,Grafiken) <strong>in</strong> gleicher Weise zusammenfassen. Dann spricht man allgeme<strong>in</strong>er von Archiven.Außer <strong>de</strong>n Dateien enthalten Archive Verwaltungs<strong>in</strong>formationen (In<strong>de</strong>x) zum schnellen F<strong>in</strong><strong>de</strong>n<strong>de</strong>r Inhalte. Diese Informationen wur<strong>de</strong>n früher mit <strong>de</strong>m Kommando ranlib(1) eigenserzeugt, heute erledigt ar(1) das mit. Die Verwendung von Bibliotheken beim Programmierenwird 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 kann man zusätzlich erworbeneo<strong>de</strong>r selbst erstellte Bibliotheken verwen<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>x-sequentieller Dateien, für Grafik,


26 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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 erzeugt man mit <strong>de</strong>m UNIX-Kommando ar(1); das Datei-Format ist unter ar(4) beschrieben. E<strong>in</strong> Beispiel zeige <strong>de</strong>nGebrauch. Wir haben e<strong>in</strong> Programm statistik.c zur Berechnung von Mittelwert und Varianz<strong>de</strong>r <strong>in</strong> <strong>de</strong>r Kommandozeile mitgegebenen ganzen 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) {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 eigenen FunktionsbibliothekDas Programm verwen<strong>de</strong>t die Funktionen mwert() und varianz(), die wir aus e<strong>in</strong>erhausgemachten Funktionsbibliothek namens libstat.a entnehmen. Der im Kommentargenannte Compileraufruf mit <strong>de</strong>r Option -L . veranlaßt <strong>de</strong>n L<strong>in</strong>ker, diese Bibliothek imArbeits-Verzeichnis zu suchen. Die Funktionen sehen so aus:double mwert(x)<strong>in</strong>t *x;{<strong>in</strong>t j, k;double m;


1.2. PROGRAMMER’S WORKBENCH 27for (j = 1, k = 0; j


28 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>und pr<strong>in</strong>tf auf, 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>r Standardbibliotheks<strong>in</strong>d. Die Funktionen mwert und varianz wer<strong>de</strong>n ebenfalls aufgerufen und nicht<strong>de</strong>f<strong>in</strong>iert, da sie aus e<strong>in</strong>er Privatbibliothek stammen.Das Werkzeug cxref(1) erzeugt zu e<strong>in</strong>er Gruppe von C-Quellfiles e<strong>in</strong>e Kreuzreferenzlistealler 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 *36PI 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 durch Bibliotheksfunktionen geratenviele Namen <strong>in</strong> das Programm, von <strong>de</strong>nen man nichts ahnt. Ferner gibt es e<strong>in</strong>ige Werkzeugezur Ermittlung und Bearbeitung von Str<strong>in</strong>gs <strong>in</strong> Quellfiles und ausführbaren Programmen,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 Quelltext markiert.1.2.8 Versionsverwaltung mit RCS, SCCS und CVSGrößere Projekte wer<strong>de</strong>n von zahlreichen, unter Umstän<strong>de</strong>n wechseln<strong>de</strong>n Programmiererno<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 mehrere Systeme portiert. DieArbeit vollzieht sich <strong>in</strong> mehreren Stufen parallel zur Zeitachse:• Aufgabenstellung• Aufgabenanalyse• Umsetzung <strong>in</strong> e<strong>in</strong>e Programmiersprache• Testen• Dokumentieren• vorläufige Freigabe• endgültige Freigabe• Weiterentwicklung, Pflege


1.2. PROGRAMMER’S WORKBENCH 29Des weiteren wird e<strong>in</strong> Programmpaket <strong>in</strong> viele überschaubare Module aufgeteilt. Von je<strong>de</strong>mModul entstehen im Verlauf <strong>de</strong>r Arbeit 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>atensystem mit <strong>de</strong>n AchsenModul, Stufe (Zeit) und Version darstellen. Das von WALTER F. TICHY entwickelte RevisionControl System RCS ist e<strong>in</strong> Werkzeug, um bei dieser Entwicklung Ordnung zu halten. Esist e<strong>in</strong>fach handzuhaben und verträgt sich 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, ohne daß diese vollständig gespeichertzu wer<strong>de</strong>n brauchen (Speichern von Differenzen).• Es verh<strong>in</strong><strong>de</strong>rt gleichzeitige schreiben<strong>de</strong> Zugriffe mehrerer Benutzer auf <strong>de</strong>nselben Text.Sowie es um mehr als Wegwerfprogramme geht, sollte man make(1) und RCS e<strong>in</strong>setzen.Der ger<strong>in</strong>ge Aufwand zum E<strong>in</strong>arbeiten wird bei <strong>de</strong>r weiteren Arbeit mehr als wett gemacht.Arbeiten mehrere Programmierer an e<strong>in</strong>em Projekt, kommt man um RCS o<strong>de</strong>r ähnlichesnicht herum. Bei<strong>de</strong> Werkzeuge s<strong>in</strong>d auch fü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/02/06 20:01:11 wulf Exp $o<strong>de</strong>r $Id: unix8.tex,v 1.1.1.1 2005/02/06 20:01:11 wulf Exp $ vorkommen,siehe unten. Dann übergibt man mit <strong>de</strong>m Kommando ci filename (check <strong>in</strong>)die Datei <strong>de</strong>m RCS. Dieses ergänzt die Datei durch Versions<strong>in</strong>formationen und machte<strong>in</strong>e nur lesbare RCS-Datei (444) mit <strong>de</strong>r Kennung ,v daraus. Die ursprüngliche Dateilö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>erDatei zurück, und zwar nur zum Lesen. Diese Kopie kann man mit allen UNIX-Werkzeugen bearbeiten, nur das Zurückschreiben mittels ci verweigert das RCS.• Mit <strong>de</strong>m Kommando co -l filename wird e<strong>in</strong>e les- und schreibbare Kopie erzeugt.Dabei wird die RCS-Datei für weitere, gleichzeitige Schreibzugriffe gesperrt (l = lock).Die Kopie kann man mit allen UNIX-Werkzeugen bearbeiten, Umbenennen wäre jedoche<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>formationen zu 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>formationen auf <strong>de</strong>n Schirm geholt.Enthält <strong>de</strong>r Quelltext die Zeichenfolge $Log: unix8.tex,v $ – zweckmäßig imKommentar am Anfang – so wer<strong>de</strong>n die Versions<strong>in</strong>formationen auch dorth<strong>in</strong> übernommen.Dann hat man alles im Quellfile beisammen.• Falls Sie sich mit co -l filename e<strong>in</strong>e Kopie zum Editieren geholt und damit gleichzeitigdas Orig<strong>in</strong>al für weitere Schreibzugriffe gesperrt haben, anschließend die Kopiemit rm(1) löschen, so haben Sie nichts mehr zum Zurückstellen. In diesem Fall läßtsich die Sperre mit rcs -u filename aufheben. Besser ist es jedoch, auf die UNIX-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. Dievom RCS vergebenen Zugriffsrechte können von UNIX-Kommandos (chmod(1)) überranntwer<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 setzt voraus, daß sich dieBeteiligten 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.1 2005/02/06 19:44:00 wuCC = /b<strong>in</strong>/cc


30 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>CFLAGS = -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.cbubble.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 Familie von Quelltexten ausweitenwird, 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 Wertenan:/* 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 2005/02/06 19:44:00 wulf Exp $*/<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>rPlatzhalter $Hea<strong>de</strong>r: /home/<strong>de</strong>bian/unix/unix8.tex,v 1.1.1.1 2005/02/06 20:01:11 wulf Exp $Bestandteil <strong>de</strong>s Co<strong>de</strong>s, die Versions<strong>in</strong>formationen stehen also auch im ausführbaren Programm.Man könnte sogar mit ihnen etwas 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


1.2. PROGRAMMER’S WORKBENCH 31*/static char rcsid[] ="$Hea<strong>de</strong>r: /home/<strong>de</strong>bian/prog/quellen/mysort.tex,v 1.1.1.1 2005/02/06 19:44:00 wulf E#<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);}time2 = 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> dieserFunktion ist, daß wir nicht die Str<strong>in</strong>gs durch Umkopieren sortieren, son<strong>de</strong>rn nur die Indizes<strong>de</strong>r Str<strong>in</strong>gs. Ansonsten kann man hier noch e<strong>in</strong>iges verbessern und vor allem auch an<strong>de</strong>reSortieralgorithmen nehmen. Man sollte auch das E<strong>in</strong>lesen und die Ausgabe vom Sortierentrennen:/* 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 2005/02/06 19:44:00 wulf*/#<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){


32 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong><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);}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> */return 0;}Quelle 1.15 : C-Funktion Bubblesort


1.2. PROGRAMMER’S WORKBENCH 33Bubblesort eignet sich für kle<strong>in</strong>e Sortieraufgaben mit bis zu etwa hun<strong>de</strong>rt Elementen. KopierenSie sich die Bauste<strong>in</strong>e <strong>in</strong> e<strong>in</strong> eigenes Verzeichnis und entwickeln Sie das Programmunter 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 Projekten als lästig, ähnlich wie dasAnlegen e<strong>in</strong>es Makefiles. Man gewöhnt sich 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ür die selbst auferlegteOrdnung dankbar.Das Source Co<strong>de</strong> Control System SCCS verwaltet die Versionen <strong>de</strong>r Module, <strong>in</strong><strong>de</strong>mes die erste Fassung vollständig speichert und dann jeweils die Differenzen zur nächstenVersion, während RCS die jüngste Version speichert und die älteren aus <strong>de</strong>n Differenzenrekonstruiert.Alle Versionen e<strong>in</strong>es Programmes samt <strong>de</strong>n Verwaltungsdaten wer<strong>de</strong>n <strong>in</strong> e<strong>in</strong>er e<strong>in</strong>zigenSCCS-Datei namens s.filename abgelegt, auf das schreibend nur über beson<strong>de</strong>re SCCS-Kommandos zugegriffen wer<strong>de</strong>n kann. Das erste dieser Kommandos ist adm<strong>in</strong>(1) und erzeugtaus e<strong>in</strong>em C-Quellfile program.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, siehe Referenz-Handbuch.Mittels get(1) holt man das Quellfile wie<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 Projekten ist es wünschenswert,mehrere Dateien geme<strong>in</strong>sam o<strong>de</strong>r ganze Verzeichnisse <strong>in</strong> die Versionsverwaltung e<strong>in</strong>zubeziehen.Dies leistet das Concurrent Versions System (CVS). Es baut auf RCS auf und erweitert<strong>de</strong>ssen Funktionalität außer<strong>de</strong>m um e<strong>in</strong>e Client-Server-Architektur. Die beteiligtenDateien und Verzeichnisse können auf verschie<strong>de</strong>nen Computern im Netz liegen. Im Gegensatzzu RCS, das zu e<strong>in</strong>em Zeitpunkt immer nur e<strong>in</strong>em Benutzer das Schreiben gestattet,verfolgt CVS e<strong>in</strong>e sogenannte optimistische Kooperationsstrategie. Mehrere Programmiererkönnen gleichzeitig auf Kopien <strong>de</strong>rselben Version (Revision) arbeiten. Beim Zurückschreibenwird e<strong>in</strong> Abgleich mit <strong>de</strong>r <strong>in</strong> <strong>de</strong>r zentralen Versionsbibliothek (Repository) abgelegtenFassung erzwungen, um zu verh<strong>in</strong><strong>de</strong>rn, daß parallel durchgeführte und bereits zurückgeschriebeneVersionen überschrieben wer<strong>de</strong>n. Diese Strategie kann zu Konflikten führen, dieper Hand aufgelöst wer<strong>de</strong>n müssen. Während das E<strong>in</strong>richten e<strong>in</strong>es CVS-Projektes Überblickerfor<strong>de</strong>rt, ist das Arbeiten unter CVS nicht schwieriger als unter RCS. E<strong>in</strong>zelheiten wie sooft am e<strong>in</strong>fachsten aus <strong>de</strong>m Netz, wo außer <strong>de</strong>m Programmpaket selbst auch kurze o<strong>de</strong>r ausführliche,<strong>de</strong>utsche o<strong>de</strong>r englische Anleitungen zu f<strong>in</strong><strong>de</strong>n s<strong>in</strong>d. Unter <strong>de</strong>n Namen W<strong>in</strong>CVSund MacCVS liegen Fassungen für weitere Betriebssysteme im Netz.Der Oberbegriff <strong>de</strong>s ganzen Gebietes lautet Software Configuration Management (SCM)o<strong>de</strong>r allgeme<strong>in</strong>er Configuration Management (CM). Lassen Sie e<strong>in</strong>mal e<strong>in</strong>e Suchmasch<strong>in</strong>edarauf los, es gibt mehrere freie o<strong>de</strong>r kommerzielle Produkte sowie Übersichten, E<strong>in</strong>führungenund Tutorials dazu.Ist die Entwicklung e<strong>in</strong>er Software o<strong>de</strong>r e<strong>in</strong>es Manuskriptes vorläufig abgeschlossen, gehtes an die Pflege. Dazu gehört unter an<strong>de</strong>rem das Management <strong>de</strong>r im Betrieb <strong>de</strong>r Softwareauftauchen<strong>de</strong>n Probleme. Auch hierfür gibt es Werkzeuge, beispielsweise gnats aus <strong>de</strong>mGNU-Projekt. Aber das sprengt <strong>de</strong>n Rahmen dieses Buches.CASE be<strong>de</strong>utet Computer Ai<strong>de</strong>d Software Eng<strong>in</strong>eer<strong>in</strong>g. An sich ist das nichts Neues, beimProgrammieren hat man schon immer Computer e<strong>in</strong>gesetzt. Das Neue bei CASE Tools wieSoftBench von Hewlett-Packard besteht dar<strong>in</strong>, daß die e<strong>in</strong>zelnen Programmierwerkzeuge wiesyntaxgesteuerte 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>er e<strong>in</strong>heitlichen, heutzutagegrafischen Oberfläche – hier das X W<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>velopmentenvironment, IDE). Damit zu arbeiten ist die mo<strong>de</strong>rne Form <strong>de</strong>s Programmierens undkann effektiv se<strong>in</strong>.


34 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.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>rPASCAL) s<strong>in</strong>d auch unter verschie<strong>de</strong>nen Betriebssystemen (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, fonction système) e<strong>in</strong>es Betriebssystems (UNIX) s<strong>in</strong>d für alleProgrammiersprachen (C, FORTRAN, PASCAL, COBOL) dieselben. Sie gehören zum Betriebssystem.Man f<strong>in</strong><strong>de</strong>t auch die Bezeichnung Kernschnittstellenfunktion, die besagt, dasse<strong>in</strong> solcher Aufruf sich unmittelbar an <strong>de</strong>n Kern <strong>de</strong>s Betriebssystems richtet. Der Kreis <strong>de</strong>rSystemaufrufe 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>rtwer<strong>de</strong>n. Da UNIX zum großen Teil <strong>in</strong> C geschrieben ist, s<strong>in</strong>d die Systemaufrufe vonUNIX C-Funktionen, die sich <strong>in</strong> ihrer Syntax nicht von eigenen o<strong>de</strong>r frem<strong>de</strong>n C-Funktionenunterschei<strong>de</strong>n. Deshalb müssen auch FORTRAN- o<strong>de</strong>r PASCAL-Programmierer etwas von<strong>de</strong>r Programmiersprache C verstehen. Im Handbuch wer<strong>de</strong>n die Systemaufrufe <strong>in</strong> Sektion(2) beschrieben.Bei POSIX-konformen Betriebssystemen spricht man statt von Systemaufrufen besservon POSIX-Funktionen, da <strong>de</strong>r POSIX-Standard offen lässt, ob diese vom Betriebssystem zurVerfügung gestellten Funktionen als Systemaufrufe o<strong>de</strong>r als Bibliothek verwirklicht s<strong>in</strong>d.Auf je<strong>de</strong>n Fall gehören sie zum Betriebssystem, nicht zum Compiler. Die Unterscheidungspielt e<strong>in</strong>e Rolle, wenn man für verschie<strong>de</strong>ne Betriebssysteme und/o<strong>de</strong>r Compiler programmiert.Der Programmierer muss wissen, woher se<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, 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 genommengehören diese Standardfunktionen jedoch zu <strong>de</strong>n jeweiligen Programmiersprachen (zumCompiler) und nicht zum Betriebssystem. Der Kreis <strong>de</strong>r Standardfunktionen ist beliebig ergänzbar.Um <strong>de</strong>n Benutzer zu verwirren, s<strong>in</strong>d die Systemaufrufe und 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, Systemaufrufen und Standardfunktionenist <strong>in</strong> gewissem Umfang willkürlich. Systemaufrufe erledigen Aufgaben, die aus <strong>de</strong>mAufbau und <strong>de</strong>n kennzeichnen<strong>de</strong>n Eigenschaften <strong>de</strong>s Betriebssystems herrühren, bei UNIXalso <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>es Systemaufrufs (open(2)),Sortieren h<strong>in</strong>gegen Sache e<strong>in</strong>er Standardfunktion (qsort(3)). Es gibt aber zusätzlich auchStandardfunktionen zum Umgang mit Dateien, die <strong>de</strong>n jeweiligen Systemaufruf komfortabelverpacken (fopen(3)). Nach außen <strong>de</strong>f<strong>in</strong>iert die Menge <strong>de</strong>r Systemaufrufe das Betriebssystem.Zwei Systeme, die <strong>in</strong> ihren Aufrufen übere<strong>in</strong>stimmen, s<strong>in</strong>d für <strong>de</strong>n Benutzer i<strong>de</strong>ntisch.Neue Funktionalitäten <strong>de</strong>s Betriebssystems stellen sich <strong>de</strong>m Programmierer als neue Systemaufrufedar, siehe zum Beispiel unter stream(2).17 Standardfunktionen s<strong>in</strong>d erst verfügbar, nach<strong>de</strong>m an<strong>de</strong>re Programmierer sie geschriebenhaben.


1.2. PROGRAMMER’S WORKBENCH 35E<strong>in</strong>ige UNIX-Systemaufrufe haben gleiche o<strong>de</strong>r ähnliche Aufgaben wie Shell-Kommandos. Wenn man die Zeit wissen möchte, verwen<strong>de</strong>t man im Dialog das Shell-Kommando date(1). Will man 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. Das Shell-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 Programmiersprache C. E<strong>in</strong>e Funktionübernimmt beim Aufruf Argumente o<strong>de</strong>r Parameter und gibt e<strong>in</strong> Ergebnis zurück. DieserMechanismus wird Parameterübergabe genannt. Man muss ihn verstan<strong>de</strong>n haben,um Funktionen <strong>in</strong> eigenen Programmen verwen<strong>de</strong>n zu können. E<strong>in</strong>e Erklärung f<strong>in</strong><strong>de</strong>t sichim Skriptum Programmieren <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 Greenwich Mean Time, 1. Januar 1970. Computeruhren laufenübrigens erstaunlich ungenau, falls sie nicht durch e<strong>in</strong>e Funkuhr o<strong>de</strong>r über das Netz synchronisiertwer<strong>de</strong>n. Ferner brauchen wir die Standardfunktion gmtime(3), Beschreibungunter ctime(3), die aus <strong>de</strong>n obigen Sekun<strong>de</strong>n e<strong>in</strong>e Struktur erzeugt, die Datum und Uhrzeitenthält. Die Umrechnung von Greenwich auf Karlsruhe nehmen wir selbst vor. Eleganterwäre e<strong>in</strong> Rückgriff auf die Zeitzonen-Variable <strong>de</strong>r Umgebung. Laut Referenz-Handbuch hattime(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>fachstenFall <strong>de</strong>n Nullpo<strong>in</strong>ter. Der Returnwert ist vom Typ long <strong>in</strong>teger. Der größte Wert diesesTyps liegt etwas über 2 Milliar<strong>de</strong>n. Damit läuft diese Uhr etwa 70 Jahre. Die Subrout<strong>in</strong>egmtime(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 vom Typ Po<strong>in</strong>ter auf long <strong>in</strong>teger.Wir müssen also <strong>de</strong>n Returnwert von time(2) <strong>in</strong> e<strong>in</strong>en Po<strong>in</strong>ter umwan<strong>de</strong>ln (referenzieren).Der Rückgabewert <strong>de</strong>r Funktion gmtime(3) ist e<strong>in</strong> Po<strong>in</strong>ter auf e<strong>in</strong>e Struktur namens tm.Diese Struktur ist <strong>in</strong> <strong>de</strong>r <strong>in</strong>clu<strong>de</strong>-Datei time.h <strong>de</strong>f<strong>in</strong>iert. Die <strong>in</strong>clu<strong>de</strong>-Dateien s<strong>in</strong>d lesbarerText; es ist ratsam h<strong>in</strong>e<strong>in</strong>zuschauen. In <strong>de</strong>r weiteren Beschreibung zu ctime(3) wird dieStruktur tm erläutert: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 wir ke<strong>in</strong>en Gebrauch. Da dieKomponenten 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. Vermutlichwollte sich <strong>de</strong>r Programmierer <strong>de</strong>n Weg offenhalten, künftig auch an<strong>de</strong>re Typen aufzunehmen(Zeitzone). Das Programm, das die Quelle zu <strong>de</strong>m Kommando zeit aus <strong>de</strong>r erstenÜbung ist, sieht folgen<strong>de</strong>rmaßen aus:18 In HP-UX. In ANSI-C ist e<strong>in</strong>e Standardfunktion time(3) enthalten.


36 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>/* 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);pr<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üssen wir sie entwe<strong>de</strong>r selbst schreiben(was <strong>de</strong>r erfahrene Programmierer scheut) o<strong>de</strong>r nach e<strong>in</strong>em Weg suchen, e<strong>in</strong>e beliebigeC-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ötigt e<strong>in</strong> Argument vom TypPo<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) erwartet e<strong>in</strong> Argument vom TypPo<strong>in</strong>ter auf long <strong>in</strong>teger, was machbar wäre, aber ihr Ergebnis ist e<strong>in</strong> Po<strong>in</strong>ter auf e<strong>in</strong>e Struktur.Das hat FORTRAN noch nie gesehen 19 . Deshalb weichen wir auf die C-Standardfunktionctime(3) aus, <strong>de</strong>ren Rückgabewert vom Typ Po<strong>in</strong>ter auf character ist, was es <strong>in</strong> FORTRANnäherungsweise gibt. In FORTRAN ist e<strong>in</strong> Zeichen e<strong>in</strong> Str<strong>in</strong>g <strong>de</strong>r Länge e<strong>in</strong>s. Str<strong>in</strong>gs wer<strong>de</strong>nper 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 unddie Anzahl <strong>de</strong>r Zeichen im Str<strong>in</strong>g als Integerwert. Das Programm sieht dann so 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)’) atimeendQuelle 1.17 : FORTRAN-Programm zur Anzeige <strong>de</strong>r SystemzeitDie ALIAS-Anweisung ist als Erweiterung zu FORTRAN 77 <strong>in</strong> vielen Compilern ent-19 FORTRAN 90 kennt Strukturen.


1.2. PROGRAMMER’S WORKBENCH 37halten und dient dazu, <strong>de</strong>n Aufruf von Unterprogrammen an<strong>de</strong>rer Sprachen zu ermöglichen.Der Compiler weiß damit, dass das Unterprogramm außerhalb <strong>de</strong>s Programms – zum Beispiel<strong>in</strong> e<strong>in</strong>er Bibliothek – e<strong>in</strong>en an<strong>de</strong>ren Namen hat als <strong>in</strong>nerhalb <strong>de</strong>s Programms. Wir<strong>de</strong><strong>in</strong>e Sprache angegeben (hier C), so erfolgt die Parameterübergabe gemäß <strong>de</strong>r Syntax dieserSprache. E<strong>in</strong>zelheiten siehe im Falle unserer Anlage im HP FORTRAN 77/HP-UX ReferenceManual im Abschnitt Compiler 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 foratimedie C-Standard-Funktion spr<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) (die Anzahl <strong>de</strong>r ausgegebenen Zeichen)wird nicht verwertet, <strong>de</strong>shalb ist foratime e<strong>in</strong>e FORTRAN-Subrout<strong>in</strong>e (ke<strong>in</strong>e Funktion),die im Programm mit call aufgerufen wer<strong>de</strong>n muss.Der Systemaufruf time(2) verlangt als Argument e<strong>in</strong>en Po<strong>in</strong>ter auf long <strong>in</strong>teger,daher ist tloc als vier Bytes lange Integerzahl <strong>de</strong>klariert. tloc spielt weiter ke<strong>in</strong>e Rolle.Die Übergabe als Po<strong>in</strong>ter (by reference) ist <strong>in</strong> FORTRAN Standard für Zahlenvariable undbraucht nicht eigens vere<strong>in</strong>bart zu wer<strong>de</strong>n. Der Rückgabewert von time geht <strong>in</strong> die Variablesec vom Typ long <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. DieseC-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 von e<strong>in</strong>em Typ, wie er durch<strong>de</strong>n Formatstr<strong>in</strong>g bezeichnet wird. Der Rückgabewert <strong>de</strong>r Funktion ctime(3) ist e<strong>in</strong> Po<strong>in</strong>terauf char. Da dies ke<strong>in</strong> <strong>in</strong> FORTRAN zulässiger Typ ist, <strong>de</strong>klarieren wir die Funktionersatzweise als vom Typ 4-Byte-<strong>in</strong>teger. Der Po<strong>in</strong>ter lässt sich auf je<strong>de</strong>n Fall <strong>in</strong> <strong>de</strong>n vier Bytesunterbr<strong>in</strong>gen. Nach unserer Erfahrung reichen auch zwei Bytes, ebenso funktioniert <strong>de</strong>rTyp logical, nicht jedoch real.Der Formatstr<strong>in</strong>g besteht aus <strong>de</strong>r Str<strong>in</strong>gkonstanten %s, gefolgt von <strong>de</strong>m ASCII-ZeichenNr. 0, wie es bei Str<strong>in</strong>gs <strong>in</strong> C Brauch ist. Für spr<strong>in</strong>tf(3) besagt dieser Formatstr<strong>in</strong>g, dasdritte Argument – <strong>de</strong>n Rückgabewert von ctime(3) – als e<strong>in</strong>en Str<strong>in</strong>g aufzufassen, das heißtals Po<strong>in</strong>ter auf das erste Element e<strong>in</strong>es Arrays of characters.atime ist e<strong>in</strong> FORTRAN-Str<strong>in</strong>g-Deskriptor, <strong>de</strong>ssen erste Komponente e<strong>in</strong> Po<strong>in</strong>ter auf characterist. 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>r puresFORTRAN.An diesem Beispiel erkennen Sie, dass Sie auch als FORTRAN- o<strong>de</strong>r PASCAL-Programmierer etwas von C verstehen müssen, um die Systemaufrufe und C-Standardfunktionen syntaktisch richtig zu gebrauchen.Bei manchen FORTRAN-Compilern (Hewlett-Packard, Microsoft) lassen sich durch e<strong>in</strong>ene<strong>in</strong>fachen Interface-Aufruf Rout<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 Systemaufrufen Informationen über e<strong>in</strong>eFatei gew<strong>in</strong>nen, dazu noch e<strong>in</strong>e Angabe 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>rDatei als Argument übernehmen, wie wir es von UNIX-Kommandos her kennen. Dazu ist e<strong>in</strong>bestimmter Formalismus 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, argv und gegebenenfalls envp. DasArgument argc ist <strong>de</strong>r Argument Counter, e<strong>in</strong>e Ganzzahl. Sie ist gleich <strong>de</strong>r Anzahl <strong>de</strong>r Argumente<strong>in</strong> <strong>de</strong>r Kommandozeile beim Aufruf <strong>de</strong>s Programms. Das Kommando selbst ist daserste Argument, also hat argc m<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 weiteren Str<strong>in</strong>gs s<strong>in</strong>d die mit <strong>de</strong>m Kommando übergebenenArgumente, hier <strong>de</strong>r Name <strong>de</strong>r gefragten Datei. Der Environment Po<strong>in</strong>ter envp wird nurbenö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.


38 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Die Namen argc, argv und envp s<strong>in</strong>d willkürlich, aber üblich. Typ und Reihenfolge s<strong>in</strong>dvorgegeben.Die Umgebung besteht aus Str<strong>in</strong>gs (mit Kommando set (Shell) anschauen). In <strong>de</strong>rfor-Schleife wer<strong>de</strong>n die Str<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 Ergebnis ist <strong>de</strong>r In<strong>de</strong>x i <strong>de</strong>s gesuchtenStr<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. Eruntersucht die Zugriffsmöglichkeiten auf 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>sgefragten Zugriffs kennzeichnet. Falls <strong>de</strong>r gefragte Zugriff möglich ist, liefert access(2)<strong>de</strong>n Wert null zurück, <strong>de</strong>r <strong>in</strong> e<strong>in</strong>em C-Programm zugleich 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> Sektion 2. Er ermittelt Datei<strong>in</strong>formationenaus <strong>de</strong>r Ino<strong>de</strong> und hat die Syntax#<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 Aufnahmee<strong>in</strong>er Struktur, die die Informationen enthält. Diese Struktur vom Typ stat 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 aufDeklarationen <strong>in</strong> /usr/<strong>in</strong>clu<strong>de</strong>/types.h. Auch e<strong>in</strong>ige Informationen wie S_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>n wie im vorigen Abschnitt umgerechnet.In UNIX-Datei-Systemen enthält je<strong>de</strong> Datei am Anfang e<strong>in</strong>e Magic Number, die überdie Art <strong>de</strong>r Datei Auskunft gibt (man magic). Mittels <strong>de</strong>s Systemaufrufs open(2) wird diefragliche Datei zum Lesen geöffnet, mittels lseek(2) <strong>de</strong>r Lesezeiger auf die Magic Numbergesetzt und mittels read(2) die Zahl gelesen. Der Systemaufruf close(2) schließt die Dateiwie<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 das Programm:/* 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;


1.2. PROGRAMMER’S WORKBENCH 39if (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) */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");break;}case S IFIFO:{puts("File ist e<strong>in</strong>e Pipe");break;}<strong>de</strong>fault:{


40 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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:{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);}


1.2. PROGRAMMER’S WORKBENCH 41Quelle 1.18 : C-Programm zum Abfragen von Informationen über e<strong>in</strong>e DateiDie Verwendung von Systemaufrufen o<strong>de</strong>r Standardfunktionen <strong>in</strong> C-Programmen istnicht schwieriger als <strong>de</strong>r Gebrauch an<strong>de</strong>rer Funktionen. Man muss sich nur an die imReferenz-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 Systemaufrufe und Standardfunktionen gibt. Die Ausgabe <strong>de</strong>s Programms siehtfolgen<strong>de</strong>rmaßen aus:LOGNAME=wualex1Datei heisst: a.outDatei existiertDatei 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). Es han<strong>de</strong>lt sich um ausführlicheInformationen über die Zugriffsrechte usw. Ähnliche Auskünfte über e<strong>in</strong>e Datei liefert dasKommando chatr(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 Robustheitse<strong>in</strong>es Systems auf die Probe stellen kann.(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>n Prozesses mit e<strong>in</strong>er neuenProzess-ID. Im Beispiel wird fork(2) <strong>in</strong> e<strong>in</strong>er ewigen for-Schleife aufgerufen.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


42 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>• 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 syntaktische Richtigkeit 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 Werkzeug make(1) dr<strong>in</strong>gend zu empfehlen.Der Compileraufruf vere<strong>in</strong>facht sich 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 nichtimmer vermeidbar.• Programmfunktionen (aber auch an<strong>de</strong>re Dateien) lassen sich <strong>in</strong> Bibliotheken archivieren,die bequemer zu handhaben s<strong>in</strong>d als e<strong>in</strong>e Menge von e<strong>in</strong>zelnen Funktionen.• Bei größeren Projekten kommt man nicht um e<strong>in</strong> Kontrollsystem wie RCS o<strong>de</strong>r CVSherum, vor allem dann, wenn mehrere 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 wettgemacht wird.• CASE-Tools vere<strong>in</strong>igen die e<strong>in</strong>zelnen Werkzeuge unter e<strong>in</strong>er geme<strong>in</strong>samen Benutzeroberfläche.Der Programmierer braucht 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 Betriebssystems nach oben, zu <strong>de</strong>n Anwendungsprogrammenh<strong>in</strong>. Sie s<strong>in</strong>d Teil <strong>de</strong>s Betriebssystems.• Systemaufrufe haben vorwiegend mit Prozessen, <strong>de</strong>n Datei-Systemen und <strong>de</strong>r E<strong>in</strong>- undAusgabe zu tun.• UNIX-Systemaufrufe s<strong>in</strong>d C-Funktionen, die sich im Gebrauch nicht von an<strong>de</strong>ren C-Funktionen unterschei<strong>de</strong>n.• C-Standardfunktionen gehören zum C-Compiler, nicht zum Betriebssystem.• E<strong>in</strong> FORTRAN-Programmierer auf e<strong>in</strong>em UNIX-System ist auf die UNIX-Systemaufrufe angewiesen, nicht aber auf die C-Standardfunktionen (dafür gibtes FORTRAN-Standardfunktionen). Dasselbe gilt für je<strong>de</strong> an<strong>de</strong>re Programmiersprache.


1.2. PROGRAMMER’S WORKBENCH 431.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 Programm mit bestimmten Fehlern.Legen Sie mit mkdir prog e<strong>in</strong> Unterverzeichnis prog an, wechseln Sie mit cd progdorth<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>eAuswirkungen, 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 Programm los:l<strong>in</strong>t fehler.cund erhalten das Ergebnis:fehler.c==============(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


44 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>==============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 Warnungen s<strong>in</strong>d nicht so dr<strong>in</strong>gend.Mit <strong>de</strong>m vi(1) ergänzen wir die 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>e Hilfe zur Klammerprüfung bietet(Prozentzeichen). Neuer Lauf von 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>r Variablen a (obwohl heimtückischerFehler, aber das ahnen wir noch nicht). Wir lassen kompilieren und rufen das kompilierteProgramm a.out(4) auf:cc fehler.ca.outDer Compiler hat nichts zu beanstan<strong>de</strong>n. Ersten Summan<strong>de</strong>n e<strong>in</strong>geben, Antwort:memory fault o<strong>de</strong>r Bus error - core dumped. Debugger 20 e<strong>in</strong>setzen, dazu nochmalsmit <strong>de</strong>r Option -g und <strong>de</strong>m vom Debugger verwen<strong>de</strong>ten Objektfile /usr/lib/xdbend.o kompilierenund anschließend laufen lassen, um e<strong>in</strong>en aktuellen Speicherauszug (Coredump) zuerzeugen:cc -g fehler.c /usr/lib/xdbend.ochmod 700 a.outa.outxdbStandardmäßig greift <strong>de</strong>r Debugger auf die ausführbare Datei a.out(4) und das beim Zusammenbrucherzeugte Corefile core(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 RETURN weitergehen, bis Auffor<strong>de</strong>rungzur 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>s Debuggers Bus error. Wir holen uns weitere Informationen vom Debugger:Tsq(stack view<strong>in</strong>g)(E<strong>in</strong>zelschritt)(quit)20 Real programmers can read core dumps.


1.2. PROGRAMMER’S WORKBENCH 45Nach<strong>de</strong>m wir wissen, daß <strong>de</strong>r Fehler nach <strong>de</strong>r E<strong>in</strong>gabe von a auftritt, schauen wir uns dieZeile mit scanf( ..., a) an und bemerken, daß wir <strong>de</strong>r Funktion scanf(3) e<strong>in</strong>e Variablestatt e<strong>in</strong>es Po<strong>in</strong>ters übergeben haben (man scanf o<strong>de</strong>r im Anhang nachlesen). Wir ersetzenalso a durch &a. Das Compilieren erleichtern wir uns durch make(1). Wir schreiben e<strong>in</strong>eDatei namens makefile mit folgen<strong>de</strong>n Zeilen:fehler: fehler.ccc fehler.c -o fehlerund rufen anschließend nur noch das Kommando make(1) ohne Argumente auf. Das Ergebnisist e<strong>in</strong> lauffähiges Programm mit Namen fehler. Der Aufruf von fehler führt beis<strong>in</strong>nvollen E<strong>in</strong>gaben zu e<strong>in</strong>er Ausgabe, die richtig se<strong>in</strong> könnte. Wir haben aber noch e<strong>in</strong>enDenkfehler dar<strong>in</strong>. Statt <strong>de</strong>r Summe wird <strong>de</strong>r Integer-Quotient berechnet. Wir berichtigenauch das und testen das Programm mit e<strong>in</strong>igen E<strong>in</strong>gaben. Da unser Quelltext richtig zu se<strong>in</strong>sche<strong>in</strong>t, verschönern wir se<strong>in</strong>e vorläufig endgültige Fassung mit <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 und untersuchen das Programmnoch 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>er ausfü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 lang wer<strong>de</strong>n kann. strip(1) wirft aus e<strong>in</strong>er ausführbaren Datei die nur für <strong>de</strong>n Debugger,nicht aber für die Ausführung wichtigen Informationen heraus und verkürzt dadurch dieDatei. Abmel<strong>de</strong>n mit exit.Schreiben Sie <strong>in</strong> e<strong>in</strong>er Programmiersprache Ihrer Wahl (ich empfehle 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 Zeitstempel mittels utime(2) setzt,• die verwen<strong>de</strong>ten Werte mittels fpr<strong>in</strong>tf(3) als Text <strong>in</strong> die Datei schreibt. fpr<strong>in</strong>tf(3)f<strong>in</strong><strong>de</strong>n Sie unter pr<strong>in</strong>tf(3).Schreiben Sie e<strong>in</strong> Programm ähnlich who(1). Sie brauchen dazu getut(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 benutzt man RCS?• Was s<strong>in</strong>d Systemaufrufe? Wer braucht sie?• Unterschied zu Standardfunktionen?• Welche Aufgaben erledigen die Systemaufrufe hauptsächlich?


46 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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, bestehend aus Zeilen, diese wie<strong>de</strong>rumaus druck- und sichtbaren Zeichen (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 gruppiert, die durch Trennzeichenvone<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. Zeilenwer<strong>de</strong>n durch das Zeilenen<strong>de</strong> markiert, meist durch die ASCII-Zeichen CR und/o<strong>de</strong>r LF. S<strong>in</strong>ne<strong>in</strong>heitenwie Wörter, Zahlen o<strong>de</strong>r Operatoren wer<strong>de</strong>n als Token bezeichnet, sie dürfen nichtdurch Trennzeichen o<strong>de</strong>r Zeilenwechsel unterbrochen wer<strong>de</strong>n.Kommentar ist nur für <strong>de</strong>n menschlichen Leser bestimmt und gelangt <strong>in</strong> C/<strong>C++</strong> gar nichtbis zum Übersetzungsvorgang, son<strong>de</strong>rn wird schon vom Präprozessor entfernt und kann bisauf se<strong>in</strong>e Begrenzungen frei gestaltet wer<strong>de</strong>n. Ebenso entfernt <strong>de</strong>r Präprozessor das ZeichenpaarBackslash-Zeilenwechsel und verb<strong>in</strong><strong>de</strong>t somit zwei Zeilen. Auf diese Weise lassen sichlange Anweisungen auf mehrere Zeilen verteilen. Schlüsselwörter und Operatoren s<strong>in</strong>dfestgelegte Zeichen o<strong>de</strong>r Zeichengruppen, an die je<strong>de</strong>r gebun<strong>de</strong>n ist. Namen wer<strong>de</strong>n nachgewissen Regeln vom Programmierer gebil<strong>de</strong>t, ebenso Konstanten. Trennzeichen trennendie genannten Bauste<strong>in</strong>e o<strong>de</strong>r ganze Anweisungen vone<strong>in</strong>an<strong>de</strong>r und s<strong>in</strong>d festgelegt, meistLeerzeichen (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 – legt nicht alle E<strong>in</strong>zelheiten fest. Zumanchen Fragen spricht er nur Empfehlungen 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 genaueBeschreibung <strong>de</strong>r bei<strong>de</strong>n, sollte experimentell prüfen, was geschieht, und se<strong>in</strong> Programmausführlich kommentieren.1.3.2 Syntax-DiagrammeDie Syntax <strong>de</strong>r e<strong>in</strong>zelnen Bauste<strong>in</strong>e – das heißt ihr regelgerechter Gebrauch – kann mittelsText beschrieben wer<strong>de</strong>n. Das ist oft umständlich und teilweise schwer zu verstehen.Deshalb nimmt man Beispiele zu Hilfe, die aber selten die Syntax vollständig erfassen. Sohaben sich Syntax-Diagramme e<strong>in</strong>gebürgert, die nach etwas Übung leicht zu lesen s<strong>in</strong>d.In Abbildung 1.3 auf Seite 47 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-Anweisung besteht aus:• <strong>de</strong>m Schlüsselwort if,• 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>em Block,• 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


1.3. BAUSTEINE EINES QUELLTEXTES 47if-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>s Blockes• 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 Anweisung ausgeführt, an<strong>de</strong>rnfalls diezweite. 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 im Programm 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, lassen sich Blöcke schachteln.E<strong>in</strong> Block kann überall stehen, wo e<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 Programmiersprache ist die Backus-Naur-Form, die von JOHN BACKUS, 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 entwickelt wor<strong>de</strong>n ist. Weiteressiehe bei D. GRIES.1.3.3 KommentarAlle Programmiersprachen ermöglichen, Text <strong>in</strong> e<strong>in</strong> Programm e<strong>in</strong>zufügen, <strong>de</strong>r vom Compilerüberlesen wird und nur für <strong>de</strong>n menschlichen Leser bestimmt ist. Dieser Kommentarmuss mit e<strong>in</strong>em beson<strong>de</strong>ren Zeichen e<strong>in</strong>geleitet und gegebenenfalls been<strong>de</strong>t wer<strong>de</strong>n.In C/<strong>C++</strong> leitet die Zeichengruppe /* <strong>de</strong>n Kommentar e<strong>in</strong>. Er kann sich über mehrereZeilen erstrecken, darf aber nicht geschachtelt wer<strong>de</strong>n. Zu e<strong>in</strong>er ungewollten Schachtelungkommt es, wenn man kommentierte Programmteile durch E<strong>in</strong>rahmen mit Kommentarzeichenvorübergehend unwirksam macht. Die Fehlermeldung <strong>de</strong>s Compilers sagt irgen<strong>de</strong>twasmit Po<strong>in</strong>tern und 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. Ansonsten kann Kommentar überall stehen, nicht nur aufe<strong>in</strong>er eigenen Zeile. E<strong>in</strong> Beispiel:


48 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>/*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 */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: da Fehlermeldungen <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 irgendwo zusammenfassen,so dass sie leicht ausgetauscht wer<strong>de</strong>n können). Damit sieht man sofort, woher e<strong>in</strong>e Meldungstammt. Kommentar schreiben wir wie<strong>de</strong>r <strong>in</strong> Englisch, da die Programmbeispiele auch perMail o<strong>de</strong>r News <strong>in</strong> die unendlichen Weiten <strong>de</strong>s Internet geschickt wer<strong>de</strong>n, wo Englisch nune<strong>in</strong>mal die l<strong>in</strong>gua franca ist. An Kommentar 21 soll man nicht sparen, <strong>de</strong>nn er kostet wenigAufwand und kann viel helfen, während die Dokumentation zum Programm nur zu oft adcalendas 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. Er beg<strong>in</strong>nt mit zwei Schrägstrichenund en<strong>de</strong>t mit <strong>de</strong>m Zeilenwechsel, weshalb er Zeilenkommentar genannt wird. DieserKommentar darf <strong>in</strong>nerhalb <strong>de</strong>s oben genannten Kommentars vorkommen. Die umgekehrteFolge ist auch zulässig, aber selten anzutreffen.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>em Buchstaben o<strong>de</strong>r e<strong>in</strong>em Unterstrich (un<strong>de</strong>rscore) beg<strong>in</strong>nen.Benutzereigene Namen sollten immer mit e<strong>in</strong>em Buchstaben anfangen, <strong>de</strong>r Unterstrichals erstes Zeichen wird vom Compiler o<strong>de</strong>r vom System verwen<strong>de</strong>t. Die weiteren Zeichen <strong>de</strong>sNamens können Buchstaben, Ziffern o<strong>de</strong>r <strong>de</strong>r Unterstrich se<strong>in</strong>. Groß- und Kle<strong>in</strong>buchstabenwer<strong>de</strong>n unterschie<strong>de</strong>n. Die maximal zulässige Länge von Namen kann durch <strong>de</strong>n Compiler,<strong>de</strong>n L<strong>in</strong>ker o<strong>de</strong>r das Bestriebssystem 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>d m<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>buchstabennicht 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 bestimmte Wörter e<strong>in</strong>e beson<strong>de</strong>reBe<strong>de</strong>utung, beispielsweise ma<strong>in</strong>, while und if. Diese Wortsymbole o<strong>de</strong>r Schlüsselwör-21 Real programmers don’t comment their co<strong>de</strong>.


1.3. BAUSTEINE EINES QUELLTEXTES 49ter 22 dü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 Standardfunktionenwie pr<strong>in</strong>tf() o<strong>de</strong>r fopen() sollen nicht umfunktioniert wer<strong>de</strong>n. C zeichnet sich durche<strong>in</strong>e ger<strong>in</strong>ge Anzahl von Schlüsselwörtern aus, etwa dreißig, siehe Anhang D.1 C-Lexikon,Schlüsselwörter auf Seite 198. Mit <strong>C++</strong> kommen nochmal dreißig dazu. Unterboten wirdC/<strong>C++</strong> dar<strong>in</strong> nur von SMALLTALK mit fünf Schlüsselwörtern.1.3.6 Operan<strong>de</strong>nWir schränken hier <strong>de</strong>n Begriff Daten etwas e<strong>in</strong> und verstehen darunter nur die passivenObjekte, mit <strong>de</strong>nen e<strong>in</strong> Programm etwas tut, also Text, Zahlen, Grafiken usw. Diese Objekteund ihre Untere<strong>in</strong>heiten nennen wir Operan<strong>de</strong>n (operand). Mit ihnen wer<strong>de</strong>n Operationendurchgeführt. Das Wort Objekt 23 vermei<strong>de</strong> ich hier, um ke<strong>in</strong>e Assoziationen an objektorientiertesProgrammieren zu 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 Speicheradresse zugegriffen. Die Speicheradressee<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 bevorzuge das englische WortPo<strong>in</strong>ter, weil das <strong>de</strong>utsche Wort Zeiger drei Be<strong>de</strong>utungen hat: Po<strong>in</strong>ter, In<strong>de</strong>x, Cursor. Außer<strong>de</strong>mbezeichne ich Po<strong>in</strong>ter nicht als Variable, obwohl ihr Wert verän<strong>de</strong>rlich ist. Wer dasenglische 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>ter2. Ordnung usw. Der Geltungsbereich e<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>e Dateio<strong>de</strong>r das ganze Programm. Gleiches gilt für die Lebensdauer. In <strong>de</strong>r Deklaration e<strong>in</strong>esOperan<strong>de</strong>n wer<strong>de</strong>n se<strong>in</strong> Name und se<strong>in</strong>e Eigenschaften vere<strong>in</strong>bart. In <strong>de</strong>r Def<strong>in</strong>ition erhälter e<strong>in</strong>en Wert und benötigt spätestens dann e<strong>in</strong>en Platz im Arbeitsspeicher. Deklaration undDef<strong>in</strong>ition können <strong>in</strong> e<strong>in</strong>er Anweisung zusammengezogen se<strong>in</strong>. Die erstmalige Zuweisung e<strong>in</strong>esWertes an e<strong>in</strong>e Variable heißt Initialisierung. Deklaration und Def<strong>in</strong>ition wer<strong>de</strong>n auchunter <strong>de</strong>m Begriff Vere<strong>in</strong>barung zusammengefasst.Auf die Auswahl und Strukturierung <strong>de</strong>r Operan<strong>de</strong>n soll man Sorgfalt verwen<strong>de</strong>n. E<strong>in</strong>ezweckmäßige Datenstruktur erleichtert das Programmieren und führt zu besseren Programmen.E<strong>in</strong>e nachträgliche Än<strong>de</strong>rung <strong>de</strong>r Datenstruktur erfor<strong>de</strong>rt meist e<strong>in</strong>en großenAufwand, weil viele Programme o<strong>de</strong>r Programmteile davon betroffen s<strong>in</strong>d. Die Namen <strong>de</strong>rOperan<strong>de</strong>n sollen ihre Be<strong>de</strong>utung erklären, erfor<strong>de</strong>rlichenfalls ist ihre Be<strong>de</strong>utung im Kommentaro<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 konstant bleiben (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 das22 Es gibt die Bezeichnungen Wortsymbol, Schlüsselwort und reserviertes Wort. Geme<strong>in</strong>tist <strong>in</strong> je<strong>de</strong>m Fall, dass das Wort – e<strong>in</strong>e bestimmte Zeichenfolge – nicht une<strong>in</strong>geschränkt alsNamen verwen<strong>de</strong>t wer<strong>de</strong>n darf. In C dürfen diese Wörter – außer im Kommentar – ke<strong>in</strong>esfallsfür e<strong>in</strong>en an<strong>de</strong>ren als ihren beson<strong>de</strong>ren Zweck verwen<strong>de</strong>t wer<strong>de</strong>n. In FORTRAN dürfendiese Wörter <strong>in</strong> Zusammenhängen, die e<strong>in</strong>e Deutung als Schlüsselwort ausschließen, auchals Namen verwen<strong>de</strong>t wer<strong>de</strong>n. Man darf also e<strong>in</strong>e Variable if nennen, und <strong>in</strong> <strong>de</strong>r Zuweisungif = 3 wird die Zeichenfolge if als Variable und nicht als Wortsymbol im S<strong>in</strong>ne von fallsverstan<strong>de</strong>n.23 KERNIGHAN + RITCHIE gebrauchen Objekt im S<strong>in</strong>ne e<strong>in</strong>es Speicherbereiches, auf <strong>de</strong>nmittels e<strong>in</strong>es Namens zugegriffen wird.


50 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Ergebnis e<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>enProgrammaufruf konstant ist, beim nächsten Aufruf aber e<strong>in</strong>en an<strong>de</strong>ren Wert hat (wie <strong>de</strong>rMehrwertsteuersatz).Man tut gut, sämtliche Operan<strong>de</strong>n e<strong>in</strong>es Programmes an wenigen Stellen zusammenzufassenund zu <strong>de</strong>klarieren. In <strong>de</strong>n Funktionen o<strong>de</strong>r Prozeduren sollen ke<strong>in</strong>e geheimnisvollenZahlen (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örigen Prozesses kopiert und vor schreiben<strong>de</strong>n Zugriffen geschütztwird. Diese Konstanten wer<strong>de</strong>n auch Literale genannt. Variable h<strong>in</strong>gegen belegenSpeicherplätze im User Data Segment, <strong>de</strong>ren Adressen das Programm kennt und auf die eslesend und schreibend zugreift.In ANSI-C s<strong>in</strong>d die Typ-Attribute (type qualifier) const und 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),• 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>r e<strong>in</strong>mal als ganzzahlig <strong>de</strong>klariertwor<strong>de</strong>n ist, bleibt dies während <strong>de</strong>s ganzen Programmes. E<strong>in</strong>ige Programmiersprachenerlauben auch variable Typen, die erst zur Laufzeit bestimmt wer<strong>de</strong>n o<strong>de</strong>r sich während dieserän<strong>de</strong>rn. Typfreie Sprachen kennen nur das Byte o<strong>de</strong>r das Masch<strong>in</strong>enwort als Datentyp.Die Typisierung 24 erleichtert die Arbeit und erhöht die Sicherheit sowie die Rechengeschw<strong>in</strong>digkeit.Stellen Sie sich vor, Sie müssten bei Gleitkommazahlen Exponent und Mantisse je<strong>de</strong>smalselbst aus <strong>de</strong>n Bytes herausdröseln. O<strong>de</strong>r <strong>de</strong>r Computer müsste je<strong>de</strong>smal aus <strong>de</strong>mZusammenhang e<strong>in</strong>er Operation ermitteln, um was für e<strong>in</strong>en Typ von Operan<strong>de</strong>n es sichhan<strong>de</strong>lt. Es gibt aber auch Aufgaben, 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 Skriptsprachen bearbeitet wer<strong>de</strong>n.Die Typ<strong>de</strong>klarationen <strong>in</strong> C/<strong>C++</strong> können ziemlich schwierig zu verstehen se<strong>in</strong>, vor allembei mangeln<strong>de</strong>r Übung. Im Netz f<strong>in</strong><strong>de</strong>t sich e<strong>in</strong> Programm c<strong>de</strong>cl, das Typ<strong>de</strong>klarationen <strong>in</strong>e<strong>in</strong>faches Englisch ü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.1.3.6.3 E<strong>in</strong>fache TypenIn je<strong>de</strong>r Programmiersprache gibt es Grundtypen, aus <strong>de</strong>nen alle höheren Typen zusammengesetztwer<strong>de</strong>n. In C/<strong>C++</strong> s<strong>in</strong>d dies ganze Zahlen, Gleitkommazahlen und Zeichen.24 Real programmers don’t worry about types.


1.3. BAUSTEINE EINES QUELLTEXTES 51Ganze Zahlen In C/<strong>C++</strong> gibt es ganze Zahlen mit o<strong>de</strong>r ohne Vorzeichen 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 und beim Portieren zu beachten.Häufig s<strong>in</strong>d <strong>in</strong>t und long gleich und belegen e<strong>in</strong> Masch<strong>in</strong>enwort, auf unserer Anlage also4 Bytes gleich 32 Bits (32-Bit-Architektur). Festgelegt ist nur die Reihenfolge:char


52 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Gleitkommazahlen Gleitkommazahlen – auch als Reals o<strong>de</strong>r Float<strong>in</strong>g Po<strong>in</strong>t Numbers bezeichnet– wer<strong>de</strong>n durch e<strong>in</strong>e Mantisse und e<strong>in</strong>en Exponenten dargestellt. Der Exponentversteht sich nach außen zur Basis 10, <strong>in</strong>tern wird die Basis 2 verwen<strong>de</strong>t. Die Mantisse istauf e<strong>in</strong>e Stelle ungleich 0 vor <strong>de</strong>m Dezimalkomma o<strong>de</strong>r -punkt normiert. Es gibt:• float Gleitkommazahl e<strong>in</strong>facher Genauigkeit• double Gleitkommazahl doppelter Genauigkeit• 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>rn auch <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 double ist selten.Für Gleitkommazahlen s<strong>in</strong>d die Addition, die Subtraktion, die Multiplikation, die Divisionsowie Vergleiche zulässig. Die Abfrage auf Gleichheit ist jedoch heikel, da aufgrund vonRundungsfehlern zwei Gleitkommazahlen selten gleich s<strong>in</strong>d. Wenn möglich, mache man umGleitkommazahlen e<strong>in</strong>en großen Bogen. Die Operationen dauern länger als die entsprechen<strong>de</strong>nfür Ganzzahlen, und die Auswirkungen von Rundungsfehlern s<strong>in</strong>d schwierig abzuschätzen.Zur <strong>in</strong>ternen Darstellung von Gleitkommazahlen siehe Abschnitt ?? Arithmetikprozessorenauf Seite ??.Alphanumerischer Typ E<strong>in</strong>e Größe, <strong>de</strong>ren Wertevorrat die Zeichen <strong>de</strong>r ASCII-Tabelleo<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, bezeichnetmit char. 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.Mittlerweile gibt es auch <strong>in</strong>ternationale Zeichensätze, <strong>de</strong>ren Zeichen je zwei Bytes belegen.Die Deklaration von alphanumerischen Variablen sieht 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 angepasst wird.Die Verwandtschaft zwischen Ganzzahlen und Zeichen <strong>in</strong> C verwirrt anfangs. Man machesich die Geme<strong>in</strong>samkeiten an e<strong>in</strong>em kle<strong>in</strong>en Programm klar:/* 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;}


1.3. BAUSTEINE EINES QUELLTEXTES 53Quelle 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 Funktionpr<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 66 vertreten ist. In <strong>de</strong>r zweiten Zeile wer<strong>de</strong>n alle Werte als 7-bit-ASCII-Zeichenverstan<strong>de</strong>n, wobei die Zahlen, die mehr als 7 Bit (> 127) beanspruchen, nach 7 Bit l<strong>in</strong>ks abgeschnittenwer<strong>de</strong>n. Die Zahl 233 führt so zur Ausgabe <strong>de</strong>s Zeichens Nr. 233 - 128 = 105. DieZahl - 33 wird als Zeichen Nr. 128 - 33 = 95, <strong>de</strong>m Unterstrich, ausgegeben. Wie man an <strong>de</strong>rRechnung erkennt, wer<strong>de</strong>n Zeichen vom Prozessor wie ganze Zahlen behan<strong>de</strong>lt und erst 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ß aufSystemen mit 8-bit- o<strong>de</strong>r 16-bit-Zeichensätzen die Grenze höher liegt, aber die Arbeitsweisebleibt. Manchmal will man e<strong>in</strong> Byte wahlweise als Ganzzahl o<strong>de</strong>r als Zeichen auffassen, aberdas gehört zu <strong>de</strong>n berüchtigten Tricks <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>s Zeichens setzt voraus, dassdas System, auf <strong>de</strong>m das Programm ausgeführt wird, <strong>de</strong>n ASCII-Zeichensatz verwen<strong>de</strong>t, womitdie Portabilitä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>n Zeichens gemäß se<strong>in</strong>erZeichensatz-Tabelle (ASCII, ROMAN8), die Umwandlung <strong>de</strong>s Wertes entsprechend se<strong>in</strong>emTyp ist 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 logical kann 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 dieIntegerwerte 0 (= false) und nicht-0 (= true) verwen<strong>de</strong>t. Verwirrend ist, dass viele Funktionenbei Erfolg <strong>de</strong>n Wert 0 und bei Fehlern Werte ungleich 0 zurückgeben.Leerer Typ Der leere Datentyp void wird zum Deklarieren von Funktionen verwen<strong>de</strong>t,die ke<strong>in</strong> Ergebnis zurückliefern, sowie zum Erzeugen generischer (allgeme<strong>in</strong>er) Po<strong>in</strong>ter, dieauf Variablen e<strong>in</strong>es vorläufig beliebigen Typs zeigen. Der Typ hat ke<strong>in</strong>e Größe. Der Bytebedarfe<strong>in</strong>es Po<strong>in</strong>ters dagegen liegt fest, auch wenn <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>r zugehörigen Variablen)bekannt se<strong>in</strong>. Variablen vom Typ void lassen sich nicht verarbeiten, weil sie nichtexistieren. Man bezeichnet <strong>de</strong>n Typ void als unvollständig, da er nicht alle Fähigkeiten e<strong>in</strong>esvollständigen Typs wie <strong>in</strong>t aufweist. Man braucht diesen schrägen Typ aus ähnlichenGrü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 sich alle an<strong>de</strong>ren Typen zusammensetzen lassen. Man hätte<strong>de</strong>n Typ auch byte nennen können.1.3.6.4 Zusammengesetzte Typen (Arrays, Strukturen)Arrays Die meisten Programmiersprachen kennen Arrays, auch als Vektoren o<strong>de</strong>r unglücklicherweiseals Fel<strong>de</strong>r 25 bezeichnet; das s<strong>in</strong>d geordnete Mengen von Größen <strong>de</strong>sselbenTyps. Je<strong>de</strong>m Element 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 stetsmit 0 beg<strong>in</strong>nt. In e<strong>in</strong>em Array von zwölf Elementen 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 aller e<strong>in</strong>fachen Typen, an<strong>de</strong>reArrays, Strukturen, Unions o<strong>de</strong>r Po<strong>in</strong>ter se<strong>in</strong>, jedoch ke<strong>in</strong>e Funktionen. Dateien s<strong>in</strong>d formal25 Fel<strong>de</strong>r <strong>in</strong> Datensätzen s<strong>in</strong>d etwas völlig an<strong>de</strong>res.


54 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Strukturen, e<strong>in</strong> Array von Dateien ist also erlaubt. Die Deklaration von Arrays sieht folgen<strong>de</strong>rmaßenaus:<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>r Elemente) wissen. Sie mussbereits im Programm stehen und kann nicht erst zur Laufzeit errechnet wer<strong>de</strong>n. Man kannjedoch die Größe e<strong>in</strong>es Arrays zur Laufzeit mittels <strong>de</strong>r Standardfunktion malloc(3) än<strong>de</strong>rn,siehe Abschnitt 1.11.9 Dynamische Speicherverwaltung auf Seite 158.Es gibt mehrdimensionale Arrays (Matrizen usw.) mit entsprechend vielen In<strong>de</strong>xfolgen.Die Elemente wer<strong>de</strong>n im Speicher h<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 letzteIn<strong>de</strong>x am schnellsten än<strong>de</strong>rt. Der Compiler l<strong>in</strong>earisiert das Array, wie man sagt. E<strong>in</strong>e Matrixwird zeilenweise gespeichert. Vorsicht beim Übertragen von o<strong>de</strong>r nach FORTRAN: dort läuftdie Indizierung an<strong>de</strong>rs als <strong>in</strong> C/<strong>C++</strong>, e<strong>in</strong>e Matrix wird spaltenweise gespeichert. PASCALverhält sich wie C/<strong>C++</strong>.Der Name e<strong>in</strong>es Arrays ist e<strong>in</strong>e Adresskonstante und kann daher nicht auf <strong>de</strong>r l<strong>in</strong>kenSeite e<strong>in</strong>er Zuweisung vorkommen. Weiteres dazu im Abschnitt 1.3.6.7 Po<strong>in</strong>ter auf Seite 56.Str<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, abgeschlossen durch 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 nicht beliebig lang wer<strong>de</strong>n.Wenn nicht Arbeitsspeicher, Editor o<strong>de</strong>r an<strong>de</strong>re Faktoren vorher zuschlagen, muss man ab32 kByte auf Probleme gefasst se<strong>in</strong>, wohlgmerkt beim e<strong>in</strong>zelnen Str<strong>in</strong>g, nicht bei e<strong>in</strong>em ausvielen Str<strong>in</strong>gs bestehen<strong>de</strong>n Text. Man stößt selten an diese Grenze, <strong>de</strong>shalb wird sie <strong>in</strong> vielenBüchern nicht erwähnt.Wir bevorzugen das Wort Str<strong>in</strong>g um hervorzuheben, dass es sich hierbei um Zeichenfolgen<strong>in</strong> e<strong>in</strong>em bestimmten, sprachenspezifischen Format 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 verarbeiteno<strong>de</strong>r durch Zugriff auf se<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 auch selbst um die ASCII-Nullkü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>n beliebigen Uns<strong>in</strong>n zulassen,dann muss man die E<strong>in</strong>gaben als lange (e<strong>in</strong>ige Zeilen) Str<strong>in</strong>gs übernehmen, die Str<strong>in</strong>gsprüfen und dann – sofern sie vernünftig s<strong>in</strong>d – <strong>in</strong> <strong>de</strong>n gewünschten Typ umwan<strong>de</strong>ln. E<strong>in</strong>gutes Programm vertraut E<strong>in</strong>gaben niemals bl<strong>in</strong>dl<strong>in</strong>gs, son<strong>de</strong>rn prüft sie vor <strong>de</strong>r weiterenVerarbeitung gründlich. E<strong>in</strong> Programmbeispiel dazu f<strong>in</strong><strong>de</strong>t sich im Abschnitt 1.11.7.2 Po<strong>in</strong>terauf Typ void: xread.c auf Seite 148.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 abgeschlossen s<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") dargestellt wer<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> PASCAL als Record bezeichnet,vere<strong>in</strong>t Komponenten ungleichen 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ürfen geschachtelt wer<strong>de</strong>n,aber nicht sich selbst enthalten (ke<strong>in</strong>e Rekursion). Möglich ist jedoch, dass e<strong>in</strong>e Strukture<strong>in</strong>en Po<strong>in</strong>ter auf sich selbst enthält – e<strong>in</strong> Po<strong>in</strong>ter ist ja nicht die Struktur selbst – womit Verkettungenhergestellt wer<strong>de</strong>n. Das Schlüsselwort lautet struct.


1.3. BAUSTEINE EINES QUELLTEXTES 55E<strong>in</strong> typisches Beispiel für e<strong>in</strong>e Struktur ist e<strong>in</strong>e Personal- o<strong>de</strong>r Mitglie<strong>de</strong>rliste, bestehendaus alphanumerischen und numerischen Komponenten. 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>rPostleitzahlen s<strong>in</strong>d alphanumerische Größen, da Rechenoperationen mit ihnen s<strong>in</strong>nlos s<strong>in</strong>d.Wir erzeugen e<strong>in</strong>en Strukturtyp ohne eigenen Namen und <strong>de</strong>klarieren zugleich e<strong>in</strong>e Variablenamens 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>em zweiten Schritt Variablenvom 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>klariertist:type<strong>de</strong>f struct {<strong>in</strong>t _cnt;unsigned charunsigned charshort _flag;char _file;} FILE;*_ptr;*_base;Mit dieser type<strong>de</strong>f-Deklaration wird e<strong>in</strong> Strukturname FILE vere<strong>in</strong>bart, <strong>de</strong>r <strong>in</strong> weiterenDeklarationen als Typ auftritt. FILE ist ke<strong>in</strong>e Variable, son<strong>de</strong>rn e<strong>in</strong> Synonym für obigeStruktur. Anschließend lassen 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ür Typen auf Seite 61 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>enUnterschied zwischen Textfiles und sonstigen Dateien gibt. Die Glie<strong>de</strong>rung erzeugt daslesen<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 Strukturkomponenten s<strong>in</strong>d e<strong>in</strong>zelne Bitso<strong>de</strong>r Gruppen von Bits, die über ihren Komponentennamen angesprochen wer<strong>de</strong>n. E<strong>in</strong>eBitfeld-Struktur darf ke<strong>in</strong>e weiteren Komponenten enthalten und soll möglichst vom Basistypunsigned se<strong>in</strong>. E<strong>in</strong> e<strong>in</strong>zelnes Bitfeld darf maximal die Länge e<strong>in</strong>es Masch<strong>in</strong>enworteshaben, es kann also 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>e Arrays, esgibt ke<strong>in</strong>en In<strong>de</strong>x. Ebensowenig lassen sich Bitfel<strong>de</strong>r referenzieren (&-Operator). Bitfel<strong>de</strong>rwer<strong>de</strong>n verwen<strong>de</strong>t, um mehrere 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.


56 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.3.6.5 UnionE<strong>in</strong>e Variable <strong>de</strong>s Typs union kann Werte unterschiedlichen Typs aufnehmen, zu e<strong>in</strong>emZeitpunkt 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>mselbenZweck, <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 untergebrachte Datentyp. Die Deklaration e<strong>in</strong>er Variablen als Union sieht aus wie beie<strong>in</strong>er Struktur:union unione<strong>in</strong>s {<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>klariert und zugleich e<strong>in</strong>e Variableux dieses Typs. Auf die jeweilige Variable wird zugegriffen wie auf die Komponenten e<strong>in</strong>erStruktur: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>gesteckt wor<strong>de</strong>n ist, an<strong>de</strong>rnfallsgibt es Überraschungen. Die Union habe ich noch nie gebraucht, sie soll <strong>in</strong> <strong>de</strong>rSystemprogrammierung vorkommen und trägt sicher nicht zur Klarheit e<strong>in</strong>es Programmesbei.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ählten Werte annehmen.Die Reihenfolge <strong>de</strong>r Werte ist maßgebend für Vergleiche: montag ist kle<strong>in</strong>er als dienstag.Auch Farben bieten sich für e<strong>in</strong>en Aufzählungstyp an. In <strong>de</strong>r Masch<strong>in</strong>e wer<strong>de</strong>n Aufzählungstypendurch Ganzzahlen dargestellt, <strong>in</strong>sofern han<strong>de</strong>lt es sich nicht um e<strong>in</strong>en neuen Typ.Aufzählungstypen verbessern 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 umgehen kann (o<strong>de</strong>r wenigstensso tut), verfügt über magische Kräfte und steht mit f<strong>in</strong>steren Mächten im Bun<strong>de</strong>. Vermutlichfrisst er auch 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 ist das Arbeiten mitPo<strong>in</strong>tern e<strong>in</strong>fach, man muss nur langsam und 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>nvollenE<strong>in</strong>satz von Po<strong>in</strong>tern: das Sortieren von Datensätzen. Die Datensätze enthalten <strong>in</strong> Forme<strong>in</strong>er Struktur Namen, Anschrift und weitere Angaben zu Personen. Die Datensätze sollennach <strong>de</strong>m Namen sortiert wer<strong>de</strong>n, um e<strong>in</strong>en schnellen Zugriff zu ermöglichen. Wür<strong>de</strong>n wirdie Datensätze nach 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, sowäre das mit viel Kopierarbeit verbun<strong>de</strong>n. Statt<strong>de</strong>ssen legt man e<strong>in</strong> Hilfsfile, e<strong>in</strong>en In<strong>de</strong>xan, <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 mit wesentlich weniger Kopierarbeitverbun<strong>de</strong>n ist, weil die Sätze kü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, suche dort möglichst geschickt nach<strong>de</strong>m Schlüssel und spr<strong>in</strong>ge dann zu <strong>de</strong>r bei <strong>de</strong>m Schlüssel stehen<strong>de</strong>n Speicheradresse <strong>de</strong>sDatensatzes. Ich kann auch zwei In<strong>de</strong>xfiles mit verschie<strong>de</strong>nen SortierschLüsseln (Namen,


1.3. BAUSTEINE EINES QUELLTEXTES 57Geburtstag) anlegen, während die Datensätze bestenfalls nach e<strong>in</strong>em e<strong>in</strong>zigen Schlüssel sortiertse<strong>in</strong> können. Meistens verzichtet man darauf, die Datensätze zu sortieren. Der dritteBand von DONALD E. KNUTH befasst sich nur mit Suchen und Sortieren, e<strong>in</strong> <strong>in</strong>teressantesGebiet. Je<strong>de</strong>r versteht die 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übergabe von Funktionen, sieheAbschnitt 1.4.3 Parameterübergabe auf Seite 82. Und schließlich können C-Funktionen nure<strong>in</strong>en e<strong>in</strong>zigen Wert zurückgeben. Setzt sich ihr Ergebnis aus mehreren Werten zusammen– wie bei e<strong>in</strong>em Str<strong>in</strong>g o<strong>de</strong>r e<strong>in</strong>em Vektor – so geht das nur über e<strong>in</strong>en Po<strong>in</strong>ter auf das ersteElement <strong>de</strong>s Ergebnisses.Auf Variablen kann mittels ihres Namens o<strong>de</strong>r ihrer Speicheradresse (Hausnummer) zugegriffenwer<strong>de</strong>n. Die Speicheradresse braucht 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 Namene<strong>in</strong>es Po<strong>in</strong>ters. Genaugenommen gehören die 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>r Programmierspraches<strong>in</strong>d, <strong>de</strong>nen zur Laufzeit als Wert Adressen zugewiesen wer<strong>de</strong>n. Deshalb wer<strong>de</strong>n sieauch als Adressvariable 26 bezeichnet. Po<strong>in</strong>ter haben Namen, Adressen s<strong>in</strong>d hexa<strong>de</strong>zimaleZahlen. Das Arbeiten mit Adressen beziehungsweise Po<strong>in</strong>tern erlaubt gelegentlich e<strong>in</strong>eelegante Programmierung, ist manchmal unvermeidlich und im übrigen älter als die Verwendungvon Variablennamen. Man muss nur stets sorgfältig die Variable von ihrem Po<strong>in</strong>terunterschei<strong>de</strong>n. Wenn man Arrays von Po<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>em p beg<strong>in</strong>neno<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, unter Umstän<strong>de</strong>n auf e<strong>in</strong>enweiteren Po<strong>in</strong>ter. Typlose Po<strong>in</strong>ter gibt es 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 letzten En<strong>de</strong>s dieSpeicheradressen (Hausnummern) ganze Zahlen s<strong>in</strong>d. Die zulässigen, s<strong>in</strong>nvollen Operationens<strong>in</strong>d an<strong>de</strong>re als bei ganzen Zahlen. Hausnummern s<strong>in</strong>d Zahlen, die Multiplikation zweierHausnummern 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örigeVariable *p durch Voransetzen <strong>de</strong>s Dereferenzierungsoperators *. Referenziert wer<strong>de</strong>nkann 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 Konstante28 . Dereferenziert wer<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> Objekt im Speicherverweist, <strong>de</strong>r also e<strong>in</strong>e Speicheradresse enthält. E<strong>in</strong>e Speicheradresse 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> Zeilen s<strong>in</strong>dzulässig beziehungsweise nicht:<strong>in</strong>t x = 12, *py;*py = x; /* zu frueh, unzulaessig */py = &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 ihr zugleich e<strong>in</strong>en Wert zu. Sie istdamit <strong>de</strong>f<strong>in</strong>iert und belegt e<strong>in</strong>en Speicherplatz. 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üht und führt zu e<strong>in</strong>em tödlichenBus 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 enthaltenkönnte. Der Po<strong>in</strong>ter ist <strong>de</strong>klariert, aber nicht <strong>de</strong>f<strong>in</strong>iert. Wohl aber kann ich die <strong>de</strong>klarierteund <strong>de</strong>f<strong>in</strong>ierte Variable x referenzieren und ihre Adresse <strong>de</strong>m Po<strong>in</strong>ter py zuweisen. Damit26 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 aufke<strong>in</strong>en bestimmten Typ zeigt.28 Konstanten s<strong>in</strong>d Teil <strong>de</strong>s Programmco<strong>de</strong>s.


58 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>enthält auch er e<strong>in</strong>en Wert – und zwar die Adresse von x – und darf beliebig weiterverwen<strong>de</strong>twer<strong>de</strong>n. Ausgegeben wird zweimal <strong>de</strong>r Wert 12. Die Zuweisung <strong>de</strong>s Wertes von x an *pyist überflüssig, da py auf die 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 und zeigt, dass man e<strong>in</strong>e Variable– genauso e<strong>in</strong>en Po<strong>in</strong>ter – außer auf <strong>de</strong>r l<strong>in</strong>ken Seite e<strong>in</strong>er Zuweisung erst dann verwen<strong>de</strong>ndarf, wenn sie e<strong>in</strong>en Wert hat.Der Name von Arrays ist die Adresskonstante ihres ersten Elementes (In<strong>de</strong>x 0). DieBezeichnung <strong>de</strong>s Arraynamens als Po<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> Arraynameist wie je<strong>de</strong> Konstante als L<strong>in</strong>kswert ungeeignet. Der Name von Funktionen ohne dasKlammernpaar ist die Adresskonstante mit <strong>de</strong>r E<strong>in</strong>sprungadresse <strong>de</strong>r Funktion, auf die ersteausfü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>ter genannt und zeigt aufke<strong>in</strong> gültiges Datenobjekt. Wie im richtigen Leben gibt es ke<strong>in</strong>e Hausnummer Null. Se<strong>in</strong>Auftreten kennzeichnet e<strong>in</strong>e Ausnahme o<strong>de</strong>r e<strong>in</strong>en Fehler. Der Wert NULL ist <strong>de</strong>r e<strong>in</strong>zige, <strong>de</strong>rdirekt e<strong>in</strong>em Po<strong>in</strong>ter zugewiesen wer<strong>de</strong>n kann; je<strong>de</strong> Zuweisung e<strong>in</strong>er Ganzzahl ist e<strong>in</strong> Fehler,da Po<strong>in</strong>ter ke<strong>in</strong>e Ganzzahlen s<strong>in</strong>d. Ansonsten dürfen nur Werte, die sich aus e<strong>in</strong>er Po<strong>in</strong>teroperationo<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>terzugewiesen wer<strong>de</strong>n.Für Po<strong>in</strong>ter s<strong>in</strong>d die Operationen Inkrementieren, Dekrementieren und Vergleichen zulässig.Die Multiplikation zweier Po<strong>in</strong>ter dürfen Sie versuchen, es kommt aber nichts Brauchbaresheraus, meist e<strong>in</strong> Laufzeitfehler (memory fault). Inkrementieren be<strong>de</strong>utet Erhöhungum 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. Dekrementierenentsprechend e<strong>in</strong>e Verm<strong>in</strong><strong>de</strong>rung. Sie brauchen nicht zu berücksichtigen, um wieviele Byteses geht, das weiß <strong>de</strong>r Compiler aufgrund <strong>de</strong>r Deklaration. Diese Po<strong>in</strong>ter-Arithmetikerleichtert das Programmieren erheblich; <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 Gebrauch von Po<strong>in</strong>tern ver<strong>de</strong>utlichenund <strong>de</strong>klarieren e<strong>in</strong> e<strong>in</strong>dimensionales Array 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. Essei mit <strong>de</strong>n Zahlen 4, 7, 1 und 2 besetzt. 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. Der Wert <strong>de</strong>s Po<strong>in</strong>ters a – dieAdresse also, unter <strong>de</strong>r die Zahl 4 abgelegt ist – ist irgen<strong>de</strong><strong>in</strong>e kaum verständliche und völligbelanglose Hexa<strong>de</strong>zimalzahl. Der Wert <strong>de</strong>r Variablen a[0] h<strong>in</strong>gegen ist 4 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 Elementa[4] führt spätestens zur Laufzeit auf e<strong>in</strong>en Fehler. Bei <strong>de</strong>r Deklaration <strong>de</strong>s Arrays muss se<strong>in</strong>eLänge bekannt se<strong>in</strong>. Später, wenn es nur um <strong>de</strong>n Typ 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), abgeschlossen mit <strong>de</strong>m unsichtbarenASCII-Zeichen Nr. 0, hier dargestellt durch ⊗. Infolge<strong>de</strong>ssen muss das Array immer e<strong>in</strong> Elementlänger se<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 ausreichend langenStr<strong>in</strong>g und belegen ihn gleichzeitig mit <strong>de</strong>m Wort 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>gkonstantendie Länge weiß. Der Str<strong>in</strong>g ist unnötig lang, aber vielleicht wollen wir später e<strong>in</strong>an<strong>de</strong>res Wort dar<strong>in</strong> unterbr<strong>in</strong>gen. Das Array sieht dann so aus:


1.3. BAUSTEINE EINES QUELLTEXTES 59Po<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 mit e<strong>in</strong>em bestimmten Wertbelegt ist. Der Zugriff ist erlaubt; was dar<strong>in</strong> steht, ist nicht abzusehen. Man darf nicht davonausgehen, dass Str<strong>in</strong>gs immer mit Spaces <strong>in</strong>itialisiert wer<strong>de</strong>n o<strong>de</strong>r Zahlen mit Null.Wir <strong>de</strong>klarieren nun e<strong>in</strong> zweidimensionales Array von Ganzzahlen, e<strong>in</strong>e nichtquadratischeMatrix:<strong>in</strong>t a[3][4];die mit folgen<strong>de</strong>n Werten belegt sei:⎛Im Arbeitsspeicher steht dann folgen<strong>de</strong>s:⎝ 1 2 3 45 6 7 89 10 11 12Po<strong>in</strong>ter 2. Po<strong>in</strong>ter 1. Speicher Wert (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] = 4a + 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] = 12⎞⎠Der Po<strong>in</strong>ter 2. Ordnung a zeigt auf e<strong>in</strong> Array aus 3 Po<strong>in</strong>tern 1. 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 je4 Ganzzahlen. Gespeichert s<strong>in</strong>d 12 Ganzzahlen, die Po<strong>in</strong>ter 1. Ordnung s<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 nichtsdaran, das Element a[1][2], nämlich die Zahl 7, als Element a[0][6] aufzufassen. Diegespeicherten Werte lassen sich auch als e<strong>in</strong>dimensionales Array b[12] verstehen. SolcheTricks müssen sorgfältig kommentiert wer<strong>de</strong>n, sonst blickt man nach kurzer Zeit nicht mehrdurch und Außenstehen<strong>de</strong> nie. Versuchen Sie, an Hand obigen Schemas folgen<strong>de</strong> Behauptungennachzuvollziehen:∗ ∗ (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 36 haben wir e<strong>in</strong> Array von Str<strong>in</strong>gs kennengelernt,also e<strong>in</strong> Array von Arrays von Zeichen, abgeschlossen jeweils mit <strong>de</strong>m ASCII-Zeichen Nr. 0.Es enthält die Namen <strong>de</strong>r Wochentage, mit Spaces aufgefüllt auf gleiche Länge:char *ptag[] = {"Sonntag, ", "Montag, ", ...};


60 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Hier wird e<strong>in</strong> Array von 7 Po<strong>in</strong>tern gespeichert. Dazu kommen natürlich noch die Str<strong>in</strong>gs, diewegen <strong>de</strong>s Aussehens auf <strong>de</strong>m Bildschirm 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↔ 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>mptag[0] abgelegt ist. ptag[0] ist die Adresse <strong>de</strong>s Speicherplatzes, <strong>in</strong> <strong>de</strong>m das Zeichen S abgelegtist. Durch zweimaliges Dereferenzieren von ptag erhalten wir das Zeichen S. Die an<strong>de</strong>renZeichen 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 normalerweise die zweidimensionaleStruktur <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 nichtunterzubr<strong>in</strong>gen s<strong>in</strong>d. Greifen wir die letzte Zeile heraus, das n von Montag. Re<strong>in</strong> mit Indizesgeschrieben gilt:ptag[1][2] = nSo entwerfen wir vermutlich e<strong>in</strong> Programm, weil wir das Arbeiten mit Indizes aus <strong>de</strong>r Mathematikgewohnt 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 Arbeit verbun<strong>de</strong>n, da er Adressenkennt und Indizes erst <strong>in</strong> Adressen umrechnen muß./* array2.c, Indizes und Po<strong>in</strong>ter */#<strong>in</strong>clu<strong>de</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>klarieren und <strong>in</strong>itialisierene<strong>in</strong>en Str<strong>in</strong>g a[]. Mit Hilfe <strong>de</strong>r Standardfunktion pr<strong>in</strong>tf() geben wir das Element mit <strong>de</strong>rHausnummer 2 aus, also das Zeichen c. Dann greifen wir auf dasselbe Element 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 Arrays um 2 hochzählen und anschließend <strong>de</strong>referenzieren.


1.3. BAUSTEINE EINES QUELLTEXTES 61Jetzt fällt uns e<strong>in</strong>, dass die Addition – auch <strong>in</strong> <strong>de</strong>r Po<strong>in</strong>ter-Arithmetik – kommutativ ist, wirvertauschen die bei<strong>de</strong>n Summan<strong>de</strong>n. Erwartungsgemäß geht das gut. Schließlich wan<strong>de</strong>lnwir 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 gemischtwer<strong>de</strong>n dürfen. Der gleiche Fall liegt auch <strong>in</strong> <strong>de</strong>r L<strong>in</strong>guistik vor, wenn über Wörtergesprochen wird. 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 Kursivschreibungo<strong>de</strong>r Gänsefüßchen ange<strong>de</strong>utet wird. Der erste Satz ist e<strong>in</strong>faches Deutsch, <strong>de</strong>rzweite gehört e<strong>in</strong>er Metasprache an, <strong>in</strong> <strong>de</strong>r Aussagen über die <strong>de</strong>utsche Sprache vorgenommenwer<strong>de</strong>n, verwirren<strong>de</strong>rweise mit <strong>de</strong>nselben Wörtern und <strong>de</strong>rselben Grammatik. Genausokann x e<strong>in</strong>e Variable 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>ter auf e<strong>in</strong>en Po<strong>in</strong>terauf e<strong>in</strong>e Variable. Erst e<strong>in</strong> Blick auf die Deklaration schafft Klarheit.In C-Programmen wird gern von Po<strong>in</strong>tern Gebrauch gemacht. In <strong>de</strong>r C-Bibel von BRIANW. KERNIGHAN und DENNIS M. RITCHIE ist ihnen daher e<strong>in</strong> ganzes, gut lesbares Kapitelgewidmet.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ürC-Datentypen schaffen. Der neue Name muss e<strong>in</strong><strong>de</strong>utig se<strong>in</strong>, darf also nicht mit e<strong>in</strong>em bereitsan<strong>de</strong>rweitig belegten Namen übere<strong>in</strong>stimmen. type<strong>de</strong>f erzeugt ke<strong>in</strong>en neuen 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>eDef<strong>in</strong>ition zu ersetzen, was man zur Prüfung auch von Hand machen kann. Der neue Typnameist e<strong>in</strong> Synonym. Der Zweck neuer Typnamen ist e<strong>in</strong>e Verbesserung <strong>de</strong>r Lesbarkeit undPortierbarkeit <strong>de</strong>s Quelltextes.E<strong>in</strong>ige Beispiele. Wir wollen uns e<strong>in</strong>en Typnamen BOOLEAN schaffen, <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>r Deklarationen 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ßend e<strong>in</strong>e Variable jane<strong>in</strong> alsBOOLEAN <strong>de</strong>klarierenBOOLEANjane<strong>in</strong>;Der Compiler ersetzt <strong>de</strong>n Str<strong>in</strong>g BOOLEAN <strong>in</strong> Deklarationen durch <strong>de</strong>n Str<strong>in</strong>g <strong>in</strong>t, ähnlichwie 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> C durch 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 Strukturtyp struct geschaffen wor<strong>de</strong>n.Dann <strong>de</strong>klarieren wir die komplexe Variable: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 nochnicht alles erledigt, <strong>de</strong>nn die arithmetischen Operatoren von C gelten nur für Ganz- undGleitkommazahlen, nicht für Strukturen. Wir müssen noch Funktionen für die Operationen


62 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>mit komplexen Variablen schreiben. In FORTRAN h<strong>in</strong>gegen gelten die gewohnten arithmetischenOperatoren auch für komplexe Daten. In <strong>C++</strong> lassen sich die Be<strong>de</strong>utungen <strong>de</strong>r Operatorenerweitern (ü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>r Weg ist gangbar, erfülltaber 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> Deklaration fehlerhaft, 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 zweimaliges Dereferenzierenfü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 Buch gefun<strong>de</strong>n, wur<strong>de</strong> aber nichtvon unserem Compiler angenommen.Ist man darauf angewiesen, dass e<strong>in</strong> Datentyp e<strong>in</strong>e bestimmte Anzahl 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 ist dann nur die Typ<strong>de</strong>f<strong>in</strong>itionanzupassen. Es wer<strong>de</strong> e<strong>in</strong>e Ganzzahl von vier Byte Länge verlangt. Dann <strong>de</strong>klariert man:type<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 packt man 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 man fü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 Variable und braucht nicht eigens angegebenzu wer<strong>de</strong>n. Variablen dieser Klasse leben nur <strong>in</strong>nerhalb <strong>de</strong>s Bereiches, <strong>in</strong> <strong>de</strong>m sie<strong>de</strong>klariert wur<strong>de</strong>n, und sterben beim Verlassen <strong>de</strong>s Bereiches, <strong>de</strong>r von ihnen belegte Speicherwird 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. Erstrecktsich e<strong>in</strong> Programm über mehrere getrennt zu kompilieren<strong>de</strong> Dateien, so darf sie nur <strong>in</strong> e<strong>in</strong>er<strong>de</strong>r Dateien <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 die Variable hier als extern <strong>de</strong>klariert. Globale Variables<strong>in</strong>d per Default extern. Funktionen gehören stets <strong>de</strong>r Speicherklasse extern an.


1.3. BAUSTEINE EINES QUELLTEXTES 63register-Variable wer<strong>de</strong>n nach Möglichkeit <strong>in</strong> Registern nahe <strong>de</strong>m Rechenwerk gehaltenund s<strong>in</strong>d damit schnell verfügbar. Ansonsten verhalten sie sich wie auto-Variable. Siemüssen vom Typ <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 Variable dieser Speicherklasse zu. Auf register-Variable kann <strong>de</strong>r Referenzierungs-Operator & nicht angewen<strong>de</strong>t wer<strong>de</strong>n. Es ist auch unsicher,ob das System <strong>de</strong>r register-Anweisung folgt. Am besten verzichtet man auf dieseSpeicherklasse.Lokale Operan<strong>de</strong>n gelten und leben nur <strong>in</strong>nerhalb <strong>de</strong>s Blockes, <strong>in</strong> <strong>de</strong>m sie <strong>de</strong>klariert wur<strong>de</strong>n.Durch die Zuordnung zur 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 Blockeshatte.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 29sie <strong>de</strong>klariert wor<strong>de</strong>n ist. Ihr Sichtbarkeits- 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>runsichtbar (existent, aber nicht zugänglich). Der Name <strong>de</strong>r Variablen ist <strong>in</strong> diesem Zusammenhangbe<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ßtim ganzen Programm, wenn dieses nur aus e<strong>in</strong>er Datei besteht. Variable, die zu Beg<strong>in</strong>n e<strong>in</strong>erFunktion – vor allen Anweisungen <strong>in</strong> <strong>de</strong>r Funktion – <strong>de</strong>klariert wer<strong>de</strong>n, gelten <strong>in</strong>nerhalbdieser Funktion, aber nicht außerhalb. Sie s<strong>in</strong>d lokal gültig. Variable, die zu Beg<strong>in</strong>n e<strong>in</strong>esBlockes – vor allen Anweisungen im Block – <strong>de</strong>klariert wer<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 gelten zu 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>rDatei, aber nicht für das gesamte Programm. Soll e<strong>in</strong> Operand global im gesamten Programmgelten, so ist er <strong>in</strong> je<strong>de</strong>r Datei erneut zu <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. Der Ausweg 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 dieDeklaration das Wort extern zu setzen. Damit ist <strong>de</strong>r For<strong>de</strong>rung nach E<strong>in</strong><strong>de</strong>utigkeit Genügegetan, und <strong>de</strong>r Compiler weiß trotz<strong>de</strong>m bei je<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 Bereiches nochmals <strong>de</strong>klariert, sohat für diesen Bereich die lokale Deklaration Vorrang vor <strong>de</strong>r äußeren Deklaration. Es wir<strong>de</strong><strong>in</strong> neuer, lokaler Operand erzeugt. Der Geltungsbereich <strong>de</strong>s äußeren Operan<strong>de</strong>n hat e<strong>in</strong>eLü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. Dieexportierten 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 man mit <strong>de</strong>r Schreibberechtigungumgehen.29 In <strong>C++</strong> dürfen Variable an beliebiger Stelle <strong>in</strong>nerhalb e<strong>in</strong>es Bereiches <strong>de</strong>klariert wer<strong>de</strong>n,jedoch muss dies vor ihrer ersten Verwendung erfolgen.


64 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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>ierten Variablen Speicherzugewiesen (allokiert). Beim Verlassen <strong>de</strong>s Bereiches wird <strong>de</strong>r Speicher freigegeben, von <strong>de</strong>nVariablen bleibt ke<strong>in</strong>e Spur zurück. Ihre Lebensdauer (lifetime) ist die aktive Zeitspanne<strong>de</strong>s Bereiches. Beim nächsten Aufruf <strong>de</strong>s Bereiches wird neuer Speicher zugewiesen und<strong>in</strong>itialisiert. Diese Speicherklasse wird als auto bezeichnet und ist die Standardklasse allerVariablen, 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, so muss man die Variable <strong>de</strong>rSpeicherklasse static zuweisen. Der Geltungsbereich wird davon nicht berührt, aber <strong>de</strong>rSpeicher samt Inhalt bleibt beim Verlassen <strong>de</strong>r Funktion bestehen. Die Variable besteht, istaber vorübergehend unsichtbar (existent, aber nicht zugänglich).1.3.7 Operationen1.3.7.1 AusdrückeWir haben bisher Operan<strong>de</strong>n betrachtet, aber nichts mit ihnen gemacht. Nun wollen wir unsansehen, was man mit <strong>de</strong>n Operan<strong>de</strong>n anstellen kann. Der Operator bestimmt, was mit <strong>de</strong>mOperand geschieht. Unäre Operatoren wirken auf genau e<strong>in</strong>en Operan<strong>de</strong>n, b<strong>in</strong>äre auf zwei,ternäre auf drei. Mehr Operan<strong>de</strong>n s<strong>in</strong>d selten. Operator plus Operan<strong>de</strong>n bezeichnet man alsAusdruck (expression). E<strong>in</strong> Ausdruck hat nach se<strong>in</strong>er Auswertung e<strong>in</strong>en Wert und kannüberall dort stehen, wo e<strong>in</strong> Wert verlangt wird. E<strong>in</strong>e Funktion, die e<strong>in</strong>en Wert zurückgibt,kann anstelle e<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 Wert zu. Der Operator ist dasGleichheitszeichen (ohne Doppelpunkt wie <strong>in</strong> PASCAL, wegen Faulheit). Das Gleichheitszeichendarf von Spaces umgeben se<strong>in</strong> und sollte es wegen <strong>de</strong>r besseren Lesbarkeit auch. Wertund Variable sollten vom selben Typ se<strong>in</strong>. Es gibt zwar <strong>in</strong> C automatische Typumwandlungen,aber man sollte wenig Gebrauch davon machen. Sie führen zu <strong>de</strong>n berüchtigten unlesbarenC-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 Zuweisungselbst liefert <strong>de</strong>n zugewiesenen Wert zurück und kann daher als Wert <strong>in</strong> e<strong>in</strong>em übergeordnetenAusdruck auftreten.Auf <strong>de</strong>r rechten Seite e<strong>in</strong>er Zuweisung kann alles stehen, was e<strong>in</strong>en Wert hat, beispielsweisee<strong>in</strong>e Konstante, e<strong>in</strong> berechenbarer Ausdruck o<strong>de</strong>r e<strong>in</strong>e Funktion, aber ke<strong>in</strong> Array unddamit auch 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>rl<strong>in</strong>ken Seite e<strong>in</strong>er Zuweisung kann alles stehen, was e<strong>in</strong>en Wert annehmen kann, beispielsweisee<strong>in</strong>e Variable, aber ke<strong>in</strong>e Konstante und ke<strong>in</strong>e Funktion. Diese Glie<strong>de</strong>r heiß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)ist als Gleichung für je<strong>de</strong>n endlichen Wert von x falsch, als Zuweisung dagegen ist sie gebräuchlichund be<strong>de</strong>utet: Addiere 1 zu <strong>de</strong>m Wert von x und schreibe das Ergebnis <strong>in</strong> dieSpeicherstelle von x. Damit erhält die Variable x e<strong>in</strong>en neuen Wert. Bei e<strong>in</strong>er Gleichung gibtes 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 undNachher. 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ündung kommt 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. BAUSTEINE EINES QUELLTEXTES 651.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 Operator kann vor o<strong>de</strong>r nach <strong>de</strong>m Operan<strong>de</strong>n(Präfix, Postfix) stehen. Der Ausdrucki++gibt <strong>de</strong>n Wert von i zurück und erhöht ihn dann um e<strong>in</strong>s. Der Ausdruck++ierhöht <strong>de</strong>n Wert von i um e<strong>in</strong>s und gibt dann <strong>de</strong>n erhöhten Wert zurück. Für das Dekrementgilt das Entsprechen<strong>de</strong>. Der kompilierte Co<strong>de</strong> ist effektiver als <strong>de</strong>r <strong>de</strong>s äquivalentenAusdrucksi = i + 1Spielt es vom Programm her ke<strong>in</strong>e Rolle, ob man <strong>de</strong>n Präfix o<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>n schneller und daher zu bevorzugen. Ferner gibt es noch e<strong>in</strong>eabgekürzte Schreibweise 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>n zu und ist somit gleichbe<strong>de</strong>utendmit <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ührliche Schreibweise bleibt weiterh<strong>in</strong>erlaubt.Die Division für ganze Zahlen ist e<strong>in</strong>e an<strong>de</strong>re Operation als für Gleitkommazahlen (die übrigenOperationen auch, nur fällt es da nicht auf). In manchen Programmiersprachen wer<strong>de</strong>nfolgerichtig unterschiedliche Operatoren verwen<strong>de</strong>t, <strong>in</strong> C nicht. Der Compiler entnimmt aus<strong>de</strong>m Zusammenhang, welche Division geme<strong>in</strong>t ist. Diese Mehrfachverwendung e<strong>in</strong>es Operatorswird Überladung genannt und spielt <strong>in</strong> objektorientierten Sprachen wie <strong>C++</strong> e<strong>in</strong>eRolle. In FORTRAN, das <strong>de</strong>n komplexen Zahlentyp kennt, gelten die arithmetischen Operatorenauch für diesen. Vorstellbar ist ebenso e<strong>in</strong>e Addition (Verkettung) von Str<strong>in</strong>gs.


66 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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) &&• 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>n an<strong>de</strong>ren Abkürzungen.Der Unterschied zwischen e<strong>in</strong>er ausdrucksweisen und e<strong>in</strong>er bitweisen logischen Operationist folgen<strong>de</strong>r: In C gilt <strong>de</strong>r Zahlenwert 0 als logisch falsch (false), je<strong>de</strong>r Wert ungleich0 als logisch 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 alleBits auf 0 stehen. Sowie e<strong>in</strong> beliebiges Bit auf 1 stün<strong>de</strong>, hätte die Variable e<strong>in</strong>en Wertungleich 0 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. Die bitweise Negation hätte hierzwar <strong>de</strong>nselben Erfolg, wäre jedoch nicht 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 Bitfolge 1000111 dargestellt. Ihre bitweiseNegation ist 0111000, was <strong>de</strong>r Ziffer 8 entspricht. Das M<strong>in</strong>i-Programm:/* 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;}


1.3. BAUSTEINE EINES QUELLTEXTES 67Quelle 1.24 : C-Programm zur Veranschaulichung <strong>de</strong>r bitweisen Negationgibt <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,die nicht <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. Beispielsweise lässt sich die Information, ob e<strong>in</strong> Gerät e<strong>in</strong>o<strong>de</strong>rausgeschaltet ist, <strong>in</strong> e<strong>in</strong>em Bit unterbr<strong>in</strong>gen. In <strong>de</strong>r Anwendungsprogrammierung istman meist großzügiger und spendiert e<strong>in</strong>e ganze Integer-Variable dafür.Merke: Ausdrucksweise logische Operationen und die noch folgen<strong>de</strong>n Vergleichs-Operationen haben e<strong>in</strong> Ergebnis, das wahr o<strong>de</strong>r falsch lautet (nicht-0 o<strong>de</strong>r 0). Bitweise logischeOperationen können je<strong>de</strong>s beliebige Ergebnis im Bereich <strong>de</strong>r ganzen Zahlen haben.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 ?:Das Ergebnis e<strong>in</strong>es Vergleichs ist e<strong>in</strong> boolescher Wert, also true o<strong>de</strong>r false beziehungsweise<strong>in</strong> C die entsprechen<strong>de</strong>n Zahlen nicht-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 Gleichheitszeichens für die Abfrageauf Gleichheit. Dieser Fehler ist schwierig 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 beabsichtigten Vergleichs:if (x = 0) { ... /* statt (x == 0) */Der Compiler protestiert nicht. Da <strong>in</strong> Vergleichen oft auf e<strong>in</strong>er Seite Ausdrücke wie Konstantenvorkommen, die nicht auf <strong>de</strong>r l<strong>in</strong>ken Seite e<strong>in</strong>er Zuweisung stehen können (r-values),empfiehlt es 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>r Syntaxprüfer. E<strong>in</strong>fach e<strong>in</strong>ekle<strong>in</strong>e Angewohnheit, die die Arbeit erleichtert.Pfiffig ist die Bed<strong>in</strong>gte Bewertung (conditional operator), auch Bed<strong>in</strong>gter Ausdruckgenannt. 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 Gleichheitszeichens stehen dreiAusdrücke, die auch zusammengesetzt se<strong>in</strong> dürfen. Die ganze Bed<strong>in</strong>gte Bewertung ist selbstwie<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 verlangtwird. Die Bed<strong>in</strong>gte Bewertung ist e<strong>in</strong>er <strong>de</strong>r seltenen ternären o<strong>de</strong>r triadischen Operatoren(drei Operan<strong>de</strong>n) und führt zu schnellerem Co<strong>de</strong> als if - else. Welchen Wert nimmt z <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 Aufruf e<strong>in</strong>er Funktion auf Seite 96.


68 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>utend mit e<strong>in</strong>er Multiplikationmit 2, e<strong>in</strong> Shiften nach rechts mit e<strong>in</strong>er Division durch 2. Auf die l<strong>in</strong>ks o<strong>de</strong>r rechtswegfallen<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> beziehen sich e<strong>in</strong>ige logische Operationen auf Bits (sieheoben). Auch hier s<strong>in</strong>d Abkürzungen möglich:=Der Ausdrucky


1.3. BAUSTEINE EINES QUELLTEXTES 69• 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 Operationen fü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>stimmung ist immer möglich, e<strong>in</strong> Vergleichgrößer-kle<strong>in</strong>er setzt e<strong>in</strong>e bestimmte Ordnung <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 */Bei <strong>de</strong>r Addition o<strong>de</strong>r Subtraktion e<strong>in</strong>er ganzen Zahl be<strong>de</strong>utet die ganze Zahl nicht e<strong>in</strong>e Anzahlvon Bytes, son<strong>de</strong>rn e<strong>in</strong>e Anzahl von Objekten <strong>de</strong>s zum Po<strong>in</strong>ter gehörigen Datentyps.Man braucht sich also nicht darum zu kümmern, wieviele Bytes <strong>de</strong>r Datentyp 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>ter liefert 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>n Datenobjekte.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, vergleichbar mit read o<strong>de</strong>r write<strong>in</strong> PASCAL o<strong>de</strong>r FORTRAN. Statt<strong>de</strong>ssen greift 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>r C-Standardbibliothek,die letzten En<strong>de</strong>s auch Systemaufrufe verwen<strong>de</strong>n, nur <strong>in</strong>telligent verpackt. Die Systemaufrufehaben e<strong>in</strong>e etwas schwierigere Syntax, erlauben dafür aber auch D<strong>in</strong>ge außerhalb <strong>de</strong>sÜblichen. Wer portabel für verschie<strong>de</strong>ne Betriebssysteme programmieren möchte, bevorzugtdie 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 Handbuchs zu f<strong>in</strong><strong>de</strong>n, die wichtigstenlauten 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>


70 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}/* 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 erstes Argument übergeben wird,zum Schreiben. Die DAtei muss bereits 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 Programm geöffneten Dateien, beg<strong>in</strong>nendmit 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-Deskriptorund schließ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 Handbuchs zu f<strong>in</strong><strong>de</strong>n, die wichtigstenlauten 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. */<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);}


1.3. BAUSTEINE EINES QUELLTEXTES 71return 0;}Quelle 1.27 : C-Programm Ausgabe per Standardfunktion fputs(3)Das Programm macht im Grun<strong>de</strong> das Gleiche wie das vorangegangene, die Schreibfunktionfputs(3) ist jedoch optimiert für das Schreiben von Str<strong>in</strong>gs <strong>in</strong> e<strong>in</strong>e Datei. Es gibt auche<strong>in</strong>e Standardfunktion fwrite(3) zum Schreiben e<strong>in</strong>es Blocks b<strong>in</strong>ärer Daten aus e<strong>in</strong>emPuffer <strong>in</strong> e<strong>in</strong>e Datei. E<strong>in</strong> DAtei-Po<strong>in</strong>ter ist 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>r Inclu<strong>de</strong>-Datei stdio.h <strong>de</strong>f<strong>in</strong>iert ist.1.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>eskalare Typbezeichnung ohne Speicherklasse 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 als Argument e<strong>in</strong>e Gleitkommazahldoppelter Genauigkeit. Die Typumwandlung von 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 Dezimalstellen verlorengehen,wenn <strong>de</strong>r neue Typ kürzer ist als <strong>de</strong>r alte. Die Typumwandlung gilt nur im Zusammenhangmit <strong>de</strong>m cast-Operator und hat für die weiteren Anwendungen <strong>de</strong>r Variablen ke<strong>in</strong>eBe<strong>de</strong>utung. Manche Compiler beanstan<strong>de</strong>n e<strong>in</strong>en cast-Operator auf <strong>de</strong>r l<strong>in</strong>ken Seite e<strong>in</strong>erZuweisung (als l-Wert).Der Komma-Operator trennt <strong>in</strong> e<strong>in</strong>er Auflistung von Ausdrücken diese vone<strong>in</strong>an<strong>de</strong>r. Siewer<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>s rechts 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 und schließlich <strong>de</strong>m gesamten Ausdruck<strong>de</strong>r Wert 999 zugewiesen. j hat also nach <strong>de</strong>n Operationen <strong>de</strong>n Wert 111, i <strong>de</strong>n Wert999, <strong>de</strong>r ausgegeben wird. Der Komma-Operator wird oft im Kopf von 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 istke<strong>in</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> Bytes zurück. Der Operand kanne<strong>in</strong>e Variable, e<strong>in</strong> Ausdruck o<strong>de</strong>r e<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>r Bitfel<strong>de</strong>r nicht alsOperand von sizeof auftreten. Mit Hilfe <strong>de</strong>s Operators vermei<strong>de</strong>t man Annahmen über dieGröße von Variablen bei 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 (nicht jedoch vom Präprozessor) und verhält sich zur Laufzeitwie e<strong>in</strong>e konstante ganze Zahl.


72 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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 jedoch nicht sicher, dass alle C-Compiler sich genau an dieVorgaben <strong>de</strong>s ANSI-Vorschlags halten. Zu<strong>de</strong>m hat man beim Programmieren meist nicht alleRegeln im Kopf, so dass es besser ist, die Ausdrücke durch run<strong>de</strong> Klammern klar un<strong>de</strong><strong>in</strong><strong>de</strong>utig zu kennzeichnen. Überflüssige Klammerpaare stören <strong>de</strong>n Compiler nicht. Hier dieListe <strong>de</strong>r Operatoren von C mit nach unten abnehmen<strong>de</strong>m Rang:( ) [ ] -> .! ~ ++ -- - (cast) * & sizeof* / %+ ->< >=== !=&^|&&||? := += -= *= /= %= = &= ^= |=,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 Vorrangvor allen an<strong>de</strong>ren Operatoren auß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ät o<strong>de</strong>r Leserichtung (associativity).Die Auswertung e<strong>in</strong>es Ausdrucks wie: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, wenn auf bei<strong>de</strong>n Seiten e<strong>in</strong>es Operan<strong>de</strong>n Operatoren <strong>de</strong>sselbenRanges stehen. Durch <strong>de</strong>n Compiler – nicht durch die Syntax <strong>de</strong>r Sprache, die lässtdie Frage offen – ist nun festgelegt, dass die arithmetischen 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 die Summe wie folgtausgewertet wird:(a + b) + cMan könnte auch sagen, dass <strong>de</strong>r Ausdruck von l<strong>in</strong>ks nach rechts gelesen wird. E<strong>in</strong>e Zuweisungdagegen ist von rechts nach l<strong>in</strong>ks zu lesen, sie ist rechts-assoziativ. Zuerst wird dierechte Seite <strong>de</strong>r Zuweisung ausgewertet und dann das Ergebnis <strong>de</strong>r l<strong>in</strong>ken Seite zugewiesen.Im Beispiel:a = b = cwird <strong>de</strong>r Wert c <strong>de</strong>r Variablen b zugewiesen und dann das Ergebnis dieser Zuweisung (<strong>de</strong>rWert b) <strong>de</strong>r Variablen a. Die Reihenfolge e<strong>in</strong>er Auswertung wird also zuerst durch <strong>de</strong>n Rangund dann durch die Assoziativität <strong>de</strong>r Operatoren bestimmt. Im Anhang <strong>in</strong> Abschnitt D.2Operatoren auf Seite 200 s<strong>in</strong>d alle Operatoren von C/<strong>C++</strong> mit Rang und Assoziativität aufgelistet.Bei Funktionsaufrufen ist ungewiss, <strong>in</strong> welcher Reihenfolge etwaige Argumente ausgewertetwer<strong>de</strong>n. Im Beispiel:<strong>in</strong>t n = 5;pr<strong>in</strong>tf("%d %d\n", ++n, n * n);


1.3. BAUSTEINE EINES QUELLTEXTES 73ist unsicher, ob n erst <strong>in</strong>krementiert und dann quadriert wird o<strong>de</strong>r umgekehrt. Das Ergebnisist entwe<strong>de</strong>r 6, 25 o<strong>de</strong>r 6, 36. Die Argumente von pr<strong>in</strong>tf() arbeitet <strong>de</strong>r e<strong>in</strong>e Compiler vonrechts ab, <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ämlich von l<strong>in</strong>ks nach rechts. Über dieReihenfolge <strong>de</strong>r Rechenschritte besagt die Leserichtung nichts. Die obige mehrfache Zuweisungwäre als Gleichung unzulässig, bei <strong>de</strong>r Addition spielt die Reihenfolge ke<strong>in</strong>e Rolle fürdas Ergebnis.Mißachtung von Rang und Assoziativität führt zu schwierig aufzu<strong>de</strong>cken<strong>de</strong>n logischenFehlern im Programm. Syntaktisch ist das Programm richtig, es tut nur etwas an<strong>de</strong>res, alssich <strong>de</strong>r Programmierer vorgestellt hat. Deshalb ist dr<strong>in</strong>gend anzuraten, die Reihenfolge e<strong>in</strong>erAuswertung durch Klammern o<strong>de</strong>r E<strong>in</strong>zelanweisungen zw<strong>in</strong>gend vorzuschreiben undAusdrücke zu vermei<strong>de</strong>n, <strong>de</strong>ren Wert von Vermutungen über die Reihenfolge <strong>de</strong>r Auswertungabhängt.1.3.8 Anweisungen1.3.8.1 Leere AnweisungAnweisungen (statement) haben e<strong>in</strong>e Wirkung, aber ke<strong>in</strong>en Wert, im Gegensatz zu Ausdrücken.Die e<strong>in</strong>fachste Anweisung ist die leere Anweisung, also die Auffor<strong>de</strong>rung an <strong>de</strong>nComputer, nichts zu tun. Das sieht zwar auf <strong>de</strong>n ersten Blick schwachs<strong>in</strong>nig aus, ist abergelegentlich nützlich. Da <strong>in</strong> C je<strong>de</strong> Anweisung mit e<strong>in</strong>em Semikolon abgeschlossen wer<strong>de</strong>nmuss, ist das nackte Semikolon die leere Anweisung. In an<strong>de</strong>ren Sprachen f<strong>in</strong><strong>de</strong>t sich dafürdie Anweisung nop o<strong>de</strong>r noop (no operation). E<strong>in</strong> Beispiel:while ((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 geschweifteKlammer) trifft. Das wird auch 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 Semikolons e<strong>in</strong>e Anweisung. Kommt e<strong>in</strong>eZuweisung beispielsweise als Argument e<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. Die Zuweisung wird ausgeführtund ihr Wert an ihre Stelle gesetzt. Steht die Zuweisung alle<strong>in</strong>, muss sie mit e<strong>in</strong>em Semikolonbeen<strong>de</strong>t wer<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 bewirkt hier erst das Semikolon, dassetwas geschieht.1.3.8.3 KontrollanweisungenKontrollanweisungen steuern <strong>in</strong> Abhängigkeit von <strong>de</strong>m Wert e<strong>in</strong>es booleschen Ausdrucks(Bed<strong>in</strong>gung) die Abarbeitung von Programmteilen (e<strong>in</strong>zelnen Anweisungen o<strong>de</strong>r Blöcken),weshalb die E<strong>in</strong>richtung auch Ablaufkontrolle genannt wird. Die Kontrollanweisungen vonC wie von vielen an<strong>de</strong>ren Sprachen s<strong>in</strong>d die Bed<strong>in</strong>gung, die Verzweigung, die Auswahl, dieSchleife und <strong>de</strong>r Sprung.


74 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Sequenz Die e<strong>in</strong>fachste Kontrollanweisung ist ke<strong>in</strong>e, die Anweisungen im 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>rVollständigkeit halber erwähnt.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ängiggemacht wer<strong>de</strong>n. Die Bed<strong>in</strong>gung ist 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 dann im Programm fortgefahren.Ist die Bed<strong>in</strong>gung false, wird <strong>de</strong>r Block übersprungen. Kann die Bed<strong>in</strong>gung niemalstrue wer<strong>de</strong>n, hat man toten (unerreichbaren) Co<strong>de</strong> geschrieben. Ist die Bed<strong>in</strong>gung immertrue, 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 Unterschiedzu 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 aufdie geschweiften Klammern 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>t sich <strong>de</strong>r Computer, <strong>in</strong> Abhängigkeitvon e<strong>in</strong>er Bed<strong>in</strong>gung <strong>in</strong> e<strong>in</strong>em von zwei Programmzweigen weiterzumachen. ImGegensatz zur Schleife kommt ke<strong>in</strong> Rücksprung vor. Verzweigungen dürfen geschachtelt wer<strong>de</strong>n.Dem Computer macht das nichts aus, aber vielleicht verlieren Sie die Übersicht.Oft, aber nicht notwendigerweise treffen die bei<strong>de</strong>n Zweige im weiteren Verlauf wie<strong>de</strong>rzusammen. Die Syntax sieht folgen<strong>de</strong>rmaßen aus: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 Wege offen, so spricht man vone<strong>in</strong>er Auswahl (selection). Sie lässt sich grundsätzlich durch e<strong>in</strong>e Schachtelung e<strong>in</strong>facherVerzweigungen mit if - else darstellen, das ist jedoch unübersichtlich.Zur Konstruktion e<strong>in</strong>er Auswahl braucht man die Schlüsselwörter switch, case, breakund <strong>de</strong>fault. Die Syntax ist die folgen<strong>de</strong>:switch(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>stimmung mit <strong>de</strong>r typgleichenKonstanten 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 dasbreak, wird dann x auf Übere<strong>in</strong>stimmung mit b o<strong>de</strong>r c geprüft. Trifft ke<strong>in</strong> case zu, wirddie <strong>de</strong>fault-Anweisungsfolge ausgeführt. Fehlt diese, macht das Programm nach <strong>de</strong>r Auswahlweiter, ohne e<strong>in</strong>e <strong>de</strong>r Anweisungen ausgeführt zu haben. Wenn ke<strong>in</strong>e an<strong>de</strong>ren Grün<strong>de</strong>dagegen sprechen, 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>fachenVerzweigung e<strong>in</strong>e Auswahl wer<strong>de</strong>n könnte, soll man gleich zu dieser greifen. Auswahlendürfen geschachtelt wer<strong>de</strong>n.


1.3. BAUSTEINE EINES QUELLTEXTES 75Mit etwas Phantasie kann man sich die Bed<strong>in</strong>gung als e<strong>in</strong>e Auswahl mit nur e<strong>in</strong>er Wahlmöglichkeitvorstellen, die Verzweigung als 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>nselben Vorgang millionenmal zu wie<strong>de</strong>rholen.Das ist se<strong>in</strong>e Stärke. Wie<strong>de</strong>rholungen von Anweisungen kommen daher <strong>in</strong> fastallen Programmen vor, 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 Schleifenhaben auch e<strong>in</strong>en Ausgang, sonst kä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).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 oftdie 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üllt ist, unter Umstän<strong>de</strong>n alsonie. Sie wird <strong>de</strong>shalb abweisen<strong>de</strong> Schleife genannt, auch kopfgesteuerte Schleife. Wenndie E<strong>in</strong>trittsbed<strong>in</strong>gung nicht mehr erfüllt ist, macht das Programm nach <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>mverwen<strong>de</strong>t, weil das Programm dadurch 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 dann so lange wie<strong>de</strong>rholt, wiedie Rücksprungbed<strong>in</strong>gung zutrifft. Sie heißt daher nichtabweisen<strong>de</strong> Schleife, auch fußgesteuerteSchleife. Ist die Rücksprungbed<strong>in</strong>gung nicht mehr erfüllt, macht das Programmnach <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ßen aus:#<strong>de</strong>f<strong>in</strong>e Please...Please do {Block} while (Bed<strong>in</strong>gung);In 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 Schleife mit for, die aber stetsdurch e<strong>in</strong>e while-Schleife ersetzt wer<strong>de</strong>n kann. 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>r Ausdruck bed<strong>in</strong>gung geprüft und falls ungleich 0 <strong>de</strong>r Schleifenrumpf betreten.Zuletzt wird <strong>de</strong>r Ausdruck <strong>in</strong>krementierung ausgewertet 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>rShell o<strong>de</strong>r <strong>de</strong>r Programmiersprache PASCAL. Je<strong>de</strong>r <strong>de</strong>r drei Ausdrücke darf fehlen:


76 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>for (;;);ist die ewige und zugleich leere Schleife. Die Initialisierung und die Inkrementierung dürfenmehrere, 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 bereits vom Compiler die Zahl10 e<strong>in</strong>gesetzt wor<strong>de</strong>n; die E<strong>in</strong>trittsbed<strong>in</strong>gung i < 10 ist anfangs erfüllt, <strong>de</strong>r Schleifenrumpfwird 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ähleri um 1 erhöht, und zur Bed<strong>in</strong>gung i < 10 zurückgesprungen. Das wie<strong>de</strong>rholt sich,bis i <strong>de</strong>n Wert 10 erreicht hat. Die Bed<strong>in</strong>gung ist dann nicht mehr erfüllt, die Ausfü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ßbrauche<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 belegt und – getrennt durch <strong>de</strong>nKomma-Operator – mittels <strong>de</strong>r Standard-Funktion puts(3) e<strong>in</strong> Str<strong>in</strong>g ausgegeben. In <strong>de</strong>rE<strong>in</strong>trittsbed<strong>in</strong>gung wird gerechnet; wichtig ist nur, dass schließlich e<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 Rumpfauf die Variablen i und j <strong>de</strong>s Schleifenkopfes zugegriffen wird. Abschließend wird <strong>de</strong>r Schlei-


1.3. BAUSTEINE EINES QUELLTEXTES 77fenzähler i <strong>in</strong>krementiert und – wie<strong>de</strong>r durch <strong>de</strong>n Komma-Operator getrennt – nochmals mitHilfe e<strong>in</strong>er Funktion sum(x) verän<strong>de</strong>rt. Wenn die Schleife nach e<strong>in</strong>igen Durchläufen verlassenwird, 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-Schleifelässt sich allerhand unterbr<strong>in</strong>gen, auch Anweisungen, die mit <strong>de</strong>r Schleife nichts zu tun haben.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>rSchleife gefangen, man hat e<strong>in</strong>e ewige Schleife programmiert. Das kann gewollt se<strong>in</strong>, istaber 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>d erlaubt, verr<strong>in</strong>gern aber die Übersicht und s<strong>in</strong>d sparsamzu verwen<strong>de</strong>n. Bei <strong>de</strong>r Behandlung von Ausnahmen (Division durch Null) braucht mansie 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 alsschwerer Stilfehler.Die Anweisung break im Rumpf führt zum sofortigen und endgültigen Verlassen e<strong>in</strong>erSchleife. Die Anweisung cont<strong>in</strong>ue bricht <strong>de</strong>n augenblicklichen Durchlauf ab und spr<strong>in</strong>gt zurückvor die Schleife, bei <strong>de</strong>r for-Schleife vor die Initialisierung. Der Systemaufruf exit(2)veranlasst <strong>de</strong>n sofortigen Abbruch <strong>de</strong>s ganzen Programmes, ist also für unheilbare Ausnahmezustän<strong>de</strong>zu gebrauchen (Notschlachtung).In vielen Schleifen zählt man die Anzahl <strong>de</strong>r Durchläufe (und verzählt sich dabei oft ume<strong>in</strong>s 30 ). Die zugehörige Variable ist <strong>de</strong>r Schleifenzähler. Auf se<strong>in</strong>e Initialisierung ist zuachten. Der Schleifenzähler steht <strong>in</strong> und nach <strong>de</strong>r Schleife für Rechnungen zur Verfügung,an<strong>de</strong>rs als <strong>in</strong> FORTRAN.Schleifen dürfen geschachtelt wer<strong>de</strong>n. Mit mehrfach geschachtelten Schleifen geht <strong>de</strong>rSpaß erst richtig los. Der Rumpf <strong>de</strong>r <strong>in</strong>nersten Schleife wird am häufigsten durchlaufen undhat daher auf das Zeitverhalten <strong>de</strong>s Programmes e<strong>in</strong>en großen E<strong>in</strong>fluss. Dort sollte man nurdie 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 Schleifesollte so e<strong>in</strong>fach und knapp wie möglich gefasst se<strong>in</strong>.Sprung Es gibt die Anweisung goto, gefolgt von e<strong>in</strong>em Label (Marke). In seltenen Fällenkann 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 syntaktischrichtig und tut auch das, was es soll, nämlich die e<strong>in</strong>gegebene Zahl ausgeben, falls siedurch 5 teilbar ist, an<strong>de</strong>rnfalls die nächstgrößere durch 5 teilbare Zahl e<strong>in</strong>schließlich <strong>de</strong>r Zwischenergebnisse.Das Programm enthält e<strong>in</strong>e schwere programmiertechnische Sün<strong>de</strong>, <strong>de</strong>nSprung 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);30 Sogenannter Zaunpfahl-Fehler (fencepost error): Wenn Sie bei e<strong>in</strong>em Zaun von 100 mLänge alle 10 m e<strong>in</strong>en Pfahl setzen, wieviele Pfähle brauchen Sie? 9? 10? 11?31 Real programmers aren’t afraid to use goto’s.


78 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}}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 */#<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-Programmenbesteht äußerst selten die Notwendigkeit für diese Anweisung, aber gebräuchliche Anweisungenwie break, cont<strong>in</strong>ue und return s<strong>in</strong>d bei Licht besehen auch nur gotos, die aufbestimmte 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> hemmungslosesH<strong>in</strong>undherhüpfen im 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>heit zurückzugeben. Sie ist dannvom Typ void. Ihre Be<strong>de</strong>utung liegt alle<strong>in</strong> <strong>in</strong> <strong>de</strong>m, was sie tut, zum Beispiel <strong>de</strong>n Bildschirmputzen. In diesem Fall en<strong>de</strong>t sie ohne return-Anweisung (schlechter Stil) o<strong>de</strong>r mit e<strong>in</strong>erreturn-Anweisung ohne Argument. Was sie 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>e eigentlicheProzedur.Gibt man <strong>de</strong>r return-Anweisung e<strong>in</strong>en Wert mit, so kann die Funktion von <strong>de</strong>r aufrufen<strong>de</strong>nE<strong>in</strong>heit wie e<strong>in</strong> Ausdruck angesehen wer<strong>de</strong>n. Der Rückgabewert (return value) darfnur 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>g zurückgeben, gehtdas nur über <strong>de</strong>n Po<strong>in</strong>ter auf <strong>de</strong>n Anfang <strong>de</strong>s Str<strong>in</strong>gs. Der zurückzugeben<strong>de</strong> Wert brauchtnicht e<strong>in</strong>geklammert zu wer<strong>de</strong>n; bei zusammengesetzten Ausdrücken sollte man <strong>de</strong>r Lesbarkeithalber Klammern setzen:return 0;return (x + y);return arrayname;Besteht das Ergebnis aus mehreren Werten, so muss man mit globalen Variablen o<strong>de</strong>r mitPo<strong>in</strong>tern arbeiten. Der Rückgabewert kann 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 weiterverwen<strong>de</strong>t wird. In diesem Fall warnt 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 Funktion ma<strong>in</strong>() f<strong>in</strong><strong>de</strong>t man <strong>in</strong> <strong>de</strong>rShell-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:


1.3. BAUSTEINE EINES QUELLTEXTES 79/* 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));pr<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++) ;


80 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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 exit(n); dieselbe Wirkung. Inan<strong>de</strong>ren Funktionen führt return zur Rückkehr <strong>in</strong> die nächsthöhere E<strong>in</strong>heit, exit zum Abbruch<strong>de</strong>s gesamten Programmes. In <strong>de</strong>r Syntax unterschei<strong>de</strong>n sich bei<strong>de</strong> Aufrufe: returnist 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 vorkommen können.1.3.9 Memo Bauste<strong>in</strong>e• Kommentar ist für <strong>de</strong>n menschlichen Leser bestimmt, <strong>de</strong>r Compiler übergeht ihn o<strong>de</strong>rbekommt ihn gar nicht erst zu Gesicht.• Namen bezeichnen Funktionen, Konstanten, Variable aller Art, Makros o<strong>de</strong>r Sprungmarken(Labels). Sie sollen mit e<strong>in</strong>em Buchstaben beg<strong>in</strong>nen.• Operan<strong>de</strong>n haben Namen, Typ, Geltungsbereich, Lebensdauer und spätestens bei ihrererstmaligen Benutzung e<strong>in</strong>en Wert und belegen damit e<strong>in</strong>en Platz und e<strong>in</strong>e Adresse imSpeicher.• 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>emOperan<strong>de</strong>n Name und Typ zu 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>erAnweisung vere<strong>in</strong>igt wer<strong>de</strong>n.• Der Typ entschei<strong>de</strong>t über Wertebereich, Operationen und Speicherbedarf. Der Typ e<strong>in</strong>esOperan<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 und Zeichen. Der Aufzählungstypist 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 gleichen Typs.• E<strong>in</strong>e Struktur ist e<strong>in</strong>e ungeordnete Menge von Operan<strong>de</strong>n beliebigen 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 immerauf e<strong>in</strong>en Typ, unter Umstän<strong>de</strong>n auf 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. Er hat e<strong>in</strong>en Wert und kannüberall dort stehen, wo e<strong>in</strong> Wert verlangt wird.• Die e<strong>in</strong>fachste Operation ist die Zuweisung, nicht zu verwechseln mit e<strong>in</strong>er mathematischenGleichung. Sie hat e<strong>in</strong>e l<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>e Variable o<strong>de</strong>r e<strong>in</strong> Po<strong>in</strong>ter, aberniemals 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 Semikolons e<strong>in</strong>e Anweisung.• Die Kontrollanweisungen Bed<strong>in</strong>gung (if), Verzweigung (if-else), Auswahl (switch),Schleife (while, do-while, for) und Sprung (break, cont<strong>in</strong>ue, return, goto) steuern <strong>de</strong>nProgrammablauf.


1.4. FUNKTIONEN 811.3.10 Übung Bauste<strong>in</strong>eÜberlegen Sie, welche Operan<strong>de</strong>n mit welchen Typen Sie für das Beispiel <strong>de</strong>r Weganalyse(o<strong>de</strong>r <strong>de</strong>s Vokabeltra<strong>in</strong>ers) aus <strong>de</strong>m vorigen Abschnitt brauchen. E<strong>in</strong>e gute Datenstruktur istschon fast das halbe Programm. Um e<strong>in</strong> richtiges Programm schreiben zu können, fehlt unsnoch <strong>de</strong>r nächste Abschnitt.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 übere<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 kompilierbare E<strong>in</strong>heit (nicht: ausführbare E<strong>in</strong>heit, dasist 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. Mit wenigerals e<strong>in</strong>er Funktion kann <strong>de</strong>r Compiler nichts anfangen.Da die Def<strong>in</strong>itionen von Funktionen nicht geschachtelt wer<strong>de</strong>n dürfen (wohl aber ihreAufrufe), gelten Funktionen grundsä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> wesentlicher Unterschied zu PAS-CAL, wo Funktionen <strong>in</strong>nerhalb von Unterprogrammen <strong>de</strong>f<strong>in</strong>iert wer<strong>de</strong>n dürfen. In C gibtes zu e<strong>in</strong>er Funktion ke<strong>in</strong>e übergeordnete Funktion, <strong>de</strong>ren Variable <strong>in</strong> <strong>de</strong>r untergeordnetenFunktion gültig s<strong>in</strong>d.E<strong>in</strong>e Funktion übernimmt von <strong>de</strong>r aufrufen<strong>de</strong>n Anweisung e<strong>in</strong>en festgelegten Satz vonArgumenten o<strong>de</strong>r Parametern, tut etwas 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>r Typ ihres Rückgabewertes)bekannt se<strong>in</strong>. An<strong>de</strong>rnfalls nimmt <strong>de</strong>r Compiler <strong>de</strong>n Standardtyp <strong>in</strong>t an. Entsprechend <strong>de</strong>mANSI-Vorschlag bürgert es sich zunehmend e<strong>in</strong>, Funktionen durch ausführliche Prototypenvor 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;..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 Argumente zu Beg<strong>in</strong>n <strong>de</strong>s Programmsherrscht sofort Klarheit. Die Namen <strong>de</strong>r Parameter s<strong>in</strong>d unerheblich; Anzahl, Typund Reihenfolge s<strong>in</strong>d wesentlich. Noch nicht alle Compiler unterstützen die Angabe <strong>de</strong>r Argumenttypen.Auch <strong>de</strong>n Standardtyp <strong>in</strong>t sollte man <strong>de</strong>klarieren, um zu ver<strong>de</strong>utlichen, daßman ihn nicht vergessen hat. Än<strong>de</strong>rungen wer<strong>de</strong>n erleichtert.


82 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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 Klammern ist <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 Funktion dienen. In funktionalenProgrammiersprachen ist die Möglichkeit, Funktionen als Argumente höherer Funktionenzu verwen<strong>de</strong>n, noch weiter entwickelt. Arrays von Funktionen s<strong>in</strong>d nicht zulässig,wohl aber Arrays von Po<strong>in</strong>tern auf Funktionen, siehe Programm 1.90 auf Seite 155.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>ssen gibt es auch ke<strong>in</strong>e Po<strong>in</strong>terauf Makros. Zu Makros siehe Abschnitt 1.9 Präprozessor auf Seite 129.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 Funktion die entsprechen<strong>de</strong>n Variablen als Platzhalter o<strong>de</strong>rformale Parameter vorkommen und <strong>de</strong>klariert se<strong>in</strong>. Im Aufruf <strong>de</strong>r Funktion kommt <strong>de</strong>rgleiche Satz von Variablen – gegebenenfalls unter an<strong>de</strong>rem Namen – mit jeweils aktuellenWerten vor; sie wer<strong>de</strong>n als aktuelle Parameter o<strong>de</strong>r Argumente bezeichnet. Die Schnittstellevon Programm und Funktion muß zusammenpassen wie Stecker und Kupplung e<strong>in</strong>erelektrischen 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 formalenParameter nach Anzahl, Reihenfolge und Typ <strong>de</strong>r Parameter ü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>e Kopie <strong>de</strong>r aktuellen Parameter<strong>de</strong>s aufrufen<strong>de</strong>n Programmes übergeben. Daraus folgt, daß die Funktion die aktuellenParameter <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>r Funktion die Speicheradressen<strong>de</strong>r aktuellen Parameter <strong>de</strong>s aufrufen<strong>de</strong>n Programmes übergeben. Die Funktion kann daherdie Werte <strong>de</strong>r Parameter mit Wirkung für das aufrufen<strong>de</strong> Programm verän<strong>de</strong>rn. Sie arbeitetmit <strong>de</strong>n Orig<strong>in</strong>alen <strong>de</strong>r Parameter. Das kann erwünscht se<strong>in</strong> o<strong>de</strong>r auch nicht. Bei bei<strong>de</strong>nMechanismen wer<strong>de</strong>n die Parameter vollständig ausgerechnet, ehe die Funktion betretenwird.Wie die Parameterübergabe <strong>in</strong> C, FORTRAN und PASCAL aussieht, entnimmt man ambesten <strong>de</strong>n Beispielen. Die Parameter s<strong>in</strong>d vom Typ <strong>in</strong>teger, um die Beispiele e<strong>in</strong>fach zuhalten. Ferner ist noch e<strong>in</strong> Shellscript angegeben, das e<strong>in</strong>e C-Funktion aufruft, die <strong>in</strong> diesemFall e<strong>in</strong> selbständiges Programm (Funktion ma<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>facherTyp 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 Typ void und macht sich alle<strong>in</strong> durch ihre Nebeneffektebemerkbar.Für die Systemaufrufe von UNIX und die Standardfunktionen von 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 Funktionswert s<strong>in</strong>d. Da diese Funktionen allesamt C-Funktionen s<strong>in</strong>d, lassen sie sichohne Probleme <strong>in</strong> C-Programme e<strong>in</strong>b<strong>in</strong><strong>de</strong>n. Bei an<strong>de</strong>ren Sprachen ist es <strong>de</strong>nkbar, daß ke<strong>in</strong>e<strong>in</strong>em C-Typ entsprechen<strong>de</strong>r Variablentyp verfügbar ist. Auch bei Str<strong>in</strong>gs gibt es wegen <strong>de</strong>runterschiedlichen Speicherung <strong>in</strong> <strong>de</strong>n e<strong>in</strong>zelnen Sprachen Reibereien. Falls die Übergabemechanismenunverträ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> Programm e<strong>in</strong>e e<strong>in</strong>heitliche Programmiersprachesieht. Das Vorgehen dabei kann masch<strong>in</strong>enbezogen se<strong>in</strong>, was man eigentlichvermei<strong>de</strong>n will.In <strong>de</strong>n folgen<strong>de</strong>n Programmbeispielen wird die Summe aus zwei Summan<strong>de</strong>n berechnet,zuerst im Hauptprogramm direkt und 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>rnihre Summan<strong>de</strong>n, was im ersten Fall ke<strong>in</strong>e Auswirkung im Hauptprogramm hat.Hauptprogramme und Funktionen s<strong>in</strong>d <strong>in</strong> C, FORTRAN und PASCAL geschrieben, wasneun Komb<strong>in</strong>ationen ergibt. Wir betreten damit zugleich das 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:


1.4. FUNKTIONEN 83/* 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);z = *px + *py;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 */*px = 66; *py = 88;return(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 bleibtdaher bei nur e<strong>in</strong>er Funktion, die – wie <strong>in</strong> FORTRAN üblich – ihre Parameter by 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>reSchwierigkeit stoßen. Vorläufig s<strong>in</strong>d wir jedoch hoffnungsvoll:{Pascal-Funktion (Summe) call by value}{Compileraufruf pc -c psv.p}


84 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>module b;import StdOutput;exportfunction psv(x, y: <strong>in</strong>teger): <strong>in</strong>teger;implementfunction 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 jeweiligen Compilers kompiliert,wodurch Objektfiles mit <strong>de</strong>r Kennung .o entstehen, die beim Kompilieren <strong>de</strong>r Hauptprogrammeaufgefü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));


1.4. FUNKTIONEN 85pr<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 reference an C-Funktionen übergibtNun das C-Hauptprogramm, das e<strong>in</strong>e FORTRAN-Funktion aufruft, e<strong>in</strong> <strong>in</strong> <strong>de</strong>r Numerikhä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);return 0;}Quelle 1.40 : C-Programm, das Parameter by reference an e<strong>in</strong>e FORTRAN-Funktion übergibtDie L<strong>in</strong>ker-Option -lcl ist erfor<strong>de</strong>rlich, wenn FORTRAN- o<strong>de</strong>r PASCAL-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 FORTRANundPASCAL-Laufzeitbibliothek /usr/lib/libcl.a, ohne die Bezüge (Referenzen) aufFORTRAN- o<strong>de</strong>r PASCAL-Rout<strong>in</strong>en unter Umstän<strong>de</strong>n offen bleiben. An<strong>de</strong>rs gesagt, <strong>in</strong> <strong>de</strong>nFORTRAN- o<strong>de</strong>r PASCAL-Funktionen kommen Namen vor – zum Beispiel write – <strong>de</strong>renDef<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ßenganzen ähnlich, es gibt aber Unterschie<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;}


86 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Quelle 1.41 : C-Programm, das Parameter by value und by reference an PASCAL-FunktionenübergibtHiernach sollte klar se<strong>in</strong>, warum die C-Standardfunktion pr<strong>in</strong>tf(3) mit Variablen alsArgument arbeitet, während die ä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 ist fü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 legtdas allerd<strong>in</strong>gs fest). H<strong>in</strong>gegen soll scanf(3) Werte mit Wirkung für die aufrufen<strong>de</strong> Funktione<strong>in</strong>lesen. Falls es sich nur um e<strong>in</strong>en Wert han<strong>de</strong>lte, könnte das noch über <strong>de</strong>n Returnwertbewerkstelligt wer<strong>de</strong>n, aber scanf(3) soll mehrere Werte – dazu noch verschie<strong>de</strong>nen Typs– verarbeiten. Das geht nur über von scanf(3) und <strong>de</strong>r aufrufen<strong>de</strong>n Funktion geme<strong>in</strong>samverwen<strong>de</strong>te Po<strong>in</strong>ter.Nun die drei FORTRAN-Hauptprogramme mit Aufruf <strong>de</strong>r Funktionen <strong>in</strong> C, FORTRANund 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)endQuelle 1.42 : FORTRAN-Programm, das Parameter by value und by 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, fsrCwrite (6, 100)read (5, *) a, bwrite (6, 102) a, bs = a + bwrite (6, 103) scall by value nicht moeglich


1.4. FUNKTIONEN 87Ccall 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 reference an 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, psrCCwrite (6, 100)read (5, *) a, bwrite (6, 102) a, bs = a + bwrite (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 und by reference an PASCAL-Funktionen übergibtDie FORTRAN-Compiler-Anweisung $ALIAS veranlaßt <strong>de</strong>n Compiler, <strong>de</strong>r jeweiligenFunktion die Parameter entgegen se<strong>in</strong>er Gewohnheit by value zu übergeben. Zum gutenSchluß die PASCAL-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;{call by value}


88 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>function csr(var x, y: <strong>in</strong>teger): <strong>in</strong>teger;external C;{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);write(’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 und by 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 reference an 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;external;{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;


1.4. FUNKTIONEN 89write(’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 und by reference an PASCAL-Funktionen übergibtSollten Sie die Beispiele nachvollzogen haben, müßte Ihr L<strong>in</strong>ker <strong>in</strong> zwei Fällen mit e<strong>in</strong>erFehlermeldung unsatisfied symbol: output (data) die Arbeit verweigert haben.Die PASCAL-Funktionen psv() und psr() geben etwas auf das Term<strong>in</strong>al aus. Bei getrenntkompilierten Modulen erfor<strong>de</strong>rt dies die Zeile:import StdOutput;Das importierte, vorgefertigte PASCAL-Modul StdOutput macht von e<strong>in</strong>em Textfile outputGebrauch, 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>ter stdout ebenso wie <strong>in</strong>FORTRAN-Programmen die Unit 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>stimmung mit 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-Programme<strong>in</strong>b<strong>in</strong><strong>de</strong>n, müssen die Funktionen auf Term<strong>in</strong>alausgabe verzichten (e<strong>in</strong>e Ausgabe <strong>in</strong> e<strong>in</strong>eDatei wäre möglich):{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;


90 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>{ 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>zelnen Programmiersprachen ihreAusgabe 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 C-Compiler. Aber wennnichts vorgesehen ist, muß <strong>de</strong>r gewöhnliche Programmierer solche Unverträglichkeiten h<strong>in</strong>nehmen.Auch Shellscripts können Funktionen aufrufen. Diese müssen selbständige Programmewie externe Kommandos se<strong>in</strong>, <strong>de</strong>r Mechanismus 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, siehe das Shellscript ?? Türmevon Hanoi auf Seite ??.Entschuldigen Sie bitte, daß dieser Abschnitt etwas breit geraten ist. Die Parameterübergabemuß sitzen, wenn man mehr als Trivialprogramme schreibt, und man ist nicht immer <strong>in</strong><strong>de</strong>r glücklichen Lage, re<strong>in</strong> <strong>in</strong> C programmieren zu können. Verwen<strong>de</strong>t man 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 hatman sich mit 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>utsamen Unverträglichkeitenherumzuschlagen.1.4.4 Kommandozeilenargumente, ma<strong>in</strong>()Auch das Hauptprogramm ma<strong>in</strong>() ist e<strong>in</strong>e Funktion, die Parameter o<strong>de</strong>r Argumente übernehmenkann, 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.


1.4. FUNKTIONEN 91Der Mechanismus ist stets <strong>de</strong>rselbe. Die Argumente, getrennt durch 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>gs mit <strong>de</strong>m Namen argv (Argumentvektor) gestellt.Gleichzeitig zählt e<strong>in</strong> Argumentzähler argc die Anzahl <strong>de</strong>r übergebenen Argumente, wobei<strong>de</strong>r Funktionsname selbst das erste Argument (In<strong>de</strong>x 0) ist. Bei e<strong>in</strong>em Programmaufrufohne Argumente steht also <strong>de</strong>r Programmname <strong>in</strong> argv[0], <strong>de</strong>r Argumentzähler argc hat<strong>de</strong>n Wert 1. Das erste nichtbelegte Element <strong>de</strong>s Argumentvektors enthält e<strong>in</strong>en leeren Str<strong>in</strong>g.Die Umwandlung <strong>de</strong>r Argumente vom Typ Str<strong>in</strong>g <strong>in</strong> <strong>de</strong>n gewünschten Typ besorgt die Funktionsscanf(3).Der Anfang e<strong>in</strong>es Hauptprogrammes mit Kommandozeilenargumenten sieht folgen<strong>de</strong>rmaßenaus:<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 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. Da dies <strong>de</strong>r Defaulttyp für Funktionenist, könnte die Typ<strong>de</strong>klaration weggelassen 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> Deklarationen gü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>utung gleich, die weiterengelten bei Argumenten <strong>in</strong> <strong>de</strong>r Kommandozeile. Die Norm ISO/IEC 9899:1999 sieht für C-Programme, die unter e<strong>in</strong>em Betriebssystem laufen (hosted environment), nur die bei<strong>de</strong>nfolgen<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 Betriebssystemen kann e<strong>in</strong> drittes Argumenth<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>erreturn-Anweisung ausdrücklich festlegen (0 bei Erfolg). Er wird von <strong>de</strong>r Shell übernommen.


92 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>1.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>e wechseln<strong>de</strong> Anzahl von Argumentenübernimmt. Auch für an<strong>de</strong>re Funktionen als ma<strong>in</strong>() gibt es e<strong>in</strong>en Mechanismus zudiesem Zweck, schauen Sie bitte unter varargs(5) nach. Der Mechanismus ist nicht übermäßig<strong>in</strong>telligent, son<strong>de</strong>rn an e<strong>in</strong>ige Voraussetzungen gebun<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 bekannt se<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 SystemV 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>r Funktion 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;/* 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 */


1.4. FUNKTIONEN 93while (*format >= ’0’ && *format


94 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 Weise die Funktion, hierpr<strong>in</strong>ti(). Ihre Argumentenliste heißt va_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 istvom Typ va_list, nicht zu verwechseln mit <strong>de</strong>r Argumentenliste va_alist. Die weiterenVariablen 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) aufgerufen wer<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ßentsprechend mit <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 pvarzeigt, und zwar <strong>in</strong> <strong>de</strong>r Form <strong>de</strong>s angegebenen Typs, <strong>de</strong>n man also kennen muß. Gleichzeitigwird <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 Argumentenlistevon pr<strong>in</strong>ti() zu. Damit ist <strong>de</strong>r Formatstr<strong>in</strong>g wie je<strong>de</strong>r an<strong>de</strong>re Str<strong>in</strong>g zugänglich. Zugleichwird <strong>de</strong>r Po<strong>in</strong>ter pvar auf das nächste Argument gestellt, üblicherweise e<strong>in</strong>e Konstante o<strong>de</strong>rVariable. Aus <strong>de</strong>r Auswertung <strong>de</strong>s Formatstr<strong>in</strong>gs ergeben sich Anzahl und Typen <strong>de</strong>r weiterenArgumente.Damit wird auch klar, was geschieht, wenn die Platzhalter (%d, %6u usw.) im Formatstr<strong>in</strong>gnicht 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, unter Umstän<strong>de</strong>n auch <strong>de</strong>r <strong>de</strong>m Programm zugewieseneSpeicherbereich verlassen. Stimmen Platzhalter und Argumente im Typ nicht übere<strong>in</strong>,wird <strong>de</strong>r Po<strong>in</strong>ter pvar falsch <strong>in</strong>krementiert, und die Typumwandlung geht vermutlich auchdaneben.Es gibt e<strong>in</strong>e Fallgrube bei <strong>de</strong>r Typangabe. Je nach Compiler wer<strong>de</strong>n die Typen char undshort <strong>in</strong>tern als <strong>in</strong>t und float 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, ambesten 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 bestimmter Programmschritte, wobeidas Ergebnis e<strong>in</strong>es Schrittes als E<strong>in</strong>gabe für die nächste Wie<strong>de</strong>rholung dient. Viele mathematischeNäherungsverfahren machen von Iterationen Gebrauch. Programmtechnisch führenIterationen auf Schleifen. Entsprechend muß e<strong>in</strong>e Bed<strong>in</strong>gung angegeben wer<strong>de</strong>n, die die


1.4. FUNKTIONEN 95Iteration been<strong>de</strong>t. Da auch bei e<strong>in</strong>em richtigen Programm e<strong>in</strong>e Iteration manchmal aus mathematischenGrü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 solcheFälle e<strong>in</strong>zubauen wie <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> 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);}Quelle 1.54 : C-Programm zur iterativen Berechnung <strong>de</strong>r QuadratwurzelDie Funktion, die iterativ aufgerufen wird, ist die Mittelwertbildung von a und b; es lohntsich nicht, sie auch programmtechnisch als selbständige Funktion zu <strong>de</strong>f<strong>in</strong>ieren, aber daskann <strong>in</strong> an<strong>de</strong>ren Aufgaben an<strong>de</strong>rs se<strong>in</strong>.


96 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</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 ist etwas schwierig vorzustellenund nicht <strong>in</strong> allen Programmiersprachen erlaubt. Die Nähe zum Zirkelschluß ist nichtgeheuer. Es gibt aber Probleme, die ursprünglich rekursiv s<strong>in</strong>d und sich durch e<strong>in</strong>e Rekursionelegant programmieren lassen. E<strong>in</strong>e Zirkel<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 diesen selbst <strong>in</strong> <strong>de</strong>r Def<strong>in</strong>ition enthält, damit es nicht sofort auffällt, gegebenenfalls ume<strong>in</strong>ige Ecken herum. E<strong>in</strong> Zirkelschluss ist e<strong>in</strong>e Folgerung, die Teile <strong>de</strong>r zu beweisen<strong>de</strong>nAussage bereits zur Voraussetzung 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 Schritten erfüllt, d. h. die Rekursionstiefeist begrenzt.In <strong>de</strong>m Buch von ROBERT SEDGEWICK f<strong>in</strong><strong>de</strong>t sich Näheres zu diesem Thema, mit Programmbeispielen.Im ersten Band <strong>de</strong>r Informatik von FRIEDRICH L. BAUER und GERHARD GOOSwird die Rekursion allgeme<strong>in</strong>er abgehan<strong>de</strong>lt.Zwei Beispiele sollen die Rekursion veranschaulichen. Das erste Programm berechnet <strong>de</strong>ngröß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 man an<strong>de</strong>rs vielleicht e<strong>in</strong>fachererledigen 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[]){<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));


1.4. FUNKTIONEN 97}return 0;/* funktion fak() */<strong>in</strong>t fak(<strong>in</strong>t n){return(n


98 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</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);}}en<strong>de</strong> = (max > END) ? END : max;time(&z1); /* Zeit holen *//* Rechnung */**f = (unsigned long)1;for (i = 1; i


1.4. FUNKTIONEN 99}flag = 0;pr<strong>in</strong>tf("\n\t%4d ! = ", i);for (j = GRP - 1; j >= 0; j-) {if (!(*(*(f + i) + j)) && !flag);elseif (!flag) {pr<strong>in</strong>tf("%9lu ", *(*(f + i) + j));flag = 1;}elsepr<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 0) ? 0 : e; /* f[1] wird das naechste f[0] */s = (s > 0) ? 0 : e;}/* En<strong>de</strong> Weitermachen *//* Anzahl <strong>de</strong>r Stellen von max! */


100 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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 - z1);else {pr<strong>in</strong>tf("\tDie Rechnung brauchte %4ld s.\n", z2 - z1);pr<strong>in</strong>tf("\tDie Ausgabe brauchte %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 Quick Assembler für <strong>de</strong>n IBM-PCbietet e<strong>in</strong>en e<strong>in</strong>fachen E<strong>in</strong>stieg <strong>in</strong> die Assemblerprogrammierung, da das große Programmnach wie vor <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>e liegt die größte vorzeichenlose Ganzzahl etwas über4 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 langen Ganzzahlen, und zwar packenwir immer neun Dezimalstellen <strong>in</strong> e<strong>in</strong> Array-Element:unsigned long f[END + 1][GRP]Bei asymmetrischen Verschlüsselungsverfahren braucht man große Zahlen. Die Arithmetikzu diesem Datentyp müssen wir selbst schreiben. Dazu ersetzen wir die eigentlich bei <strong>de</strong>rBerechnung von Fakultäten erfor<strong>de</strong>rliche Multiplikation durch die Addition. Diese beschleunigenwir durch E<strong>in</strong>satz e<strong>in</strong>er Assemblerfunktion aadd():COMMENT +C-Funktion aadd() <strong>in</strong> MS-Assembler, die e<strong>in</strong>


1.4. FUNKTIONEN 101Array 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-Programmaadd 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:retaaddENDPENDQuelle 1.59 : Assemblerfunktion 1 zur Addition von Fel<strong>de</strong>rnDie Fakultäten wer<strong>de</strong>n berechnet, gespeichert und zum Schluß zusammen ausgegeben.So können wir die Rechenzeit von <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>e Rolle spielt.


102 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Auf diesem Weg kommen wir bis <strong>in</strong> die Gegend von 260!, dann ist e<strong>in</strong> Speichersegement(64 KByte) unter PC-DOS voll. Wir können nicht mehr alle Ergebnisse speichern, son<strong>de</strong>rnnur die vorangegangene und die laufen<strong>de</strong> Fakultät. Sowie e<strong>in</strong> Ergebnis vorliegt, wird es ausgegeben.Die Assemblerfunktion laadd() zur Addition unterschei<strong>de</strong>t sich <strong>in</strong> e<strong>in</strong>er Zeile amAnfang. Die im Programm vorgesehene Grenze MAX = 1023 ist noch nicht die durch dasSpeichersegment bestimmte Grenze, son<strong>de</strong>rn willkürlich. Irgendwann erheben sich Zweifelam 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örtauch ma<strong>in</strong>().• E<strong>in</strong>e Funktion übernimmt bei ihrem Aufruf e<strong>in</strong>en festgelegten Satz von Parameterno<strong>de</strong>r Argumenten. Der Satz beim 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 Stecker und Kupplung e<strong>in</strong>er elektrischenSteckverb<strong>in</strong>dung.• Bei <strong>de</strong>r Parameterübergabe by value arbeitet die Funktion mit Kopien <strong>de</strong>r übergebenenParameter, kann also die Orig<strong>in</strong>alwerte nicht verän<strong>de</strong>rn.• Bei <strong>de</strong>r Parameterübergabe by reference erfährt die Funktion die Adressen (Po<strong>in</strong>ter) <strong>de</strong>rOrig<strong>in</strong>alwerte und kann diese verä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).• Es gibt auch Funktionen wie pr<strong>in</strong>tf(), die e<strong>in</strong>e von Aufruf zu Aufruf wechseln<strong>de</strong> Anzahlvon 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 Ergebnis an die aufrufen<strong>de</strong> Funktionzurück. Dieser Wert kann 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 (rekursiver Aufruf).• 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 Programm dadurch nicht.1.4.10 Übung FunktionenJetzt verfügen Sie über die Kenntnisse, die zum Schreiben e<strong>in</strong>facher C-Programme notwendigs<strong>in</strong>d. Schreiben das Programm zur Weganalyse, aufbauend auf <strong>de</strong>r Aufgabenanalyse und<strong>de</strong>r Datenstruktur, die Sie bereits erarbeitet haben. Falls Sie sich an <strong>de</strong>n Vokabeltra<strong>in</strong>er wagenwollen, reduzieren Sie die Aufgabe zunächst auf e<strong>in</strong> M<strong>in</strong>imum, sonst wer<strong>de</strong>n Sie nichtfertig 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 wird daher geme<strong>in</strong>sam kompiliert.Sie muss wie ma<strong>in</strong>() <strong>in</strong> C geschrieben se<strong>in</strong>, mehrsprachige Compiler gibt esnicht.


1.5. FUNKTIONS-BIBLIOTHEKEN 103• 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 kompiliert und 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 sie gebraucht wer<strong>de</strong>n o<strong>de</strong>r nicht.Wegen <strong>de</strong>r getrennten Compilierung darf die Datei <strong>in</strong> e<strong>in</strong>er an<strong>de</strong>ren Programmiersprachegeschrieben, muß aber für dieselbe Masch<strong>in</strong>e kompiliert se<strong>in</strong>.• Die getrennt kompilierte Funktion steht zusammen mit weiteren <strong>in</strong> e<strong>in</strong>er Bibliothekund wird beim L<strong>in</strong>ken zu ma<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>() gebraucht wer<strong>de</strong>n. Man kann also vieleFunktionen <strong>in</strong> e<strong>in</strong>er Bibliothek zusammenfassen, ohne befürchten zu müssen, se<strong>in</strong>eProgramme mit Ballast zu befrachten. Die Bibliothek kann auf Quellfiles unterschiedlicherProgrammiersprachen 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ürUNIX und PC-DOS <strong>in</strong> e<strong>in</strong>er Bibliothek zu 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 25 im Rahmen <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 Standardbibliothek zusammen mit<strong>de</strong>m Compiler geliefert wer<strong>de</strong>n. Sie s<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>em<strong>in</strong>imale Standardbibliothek auf. Ohne sie kö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 viel Arbeit, die an<strong>de</strong>reProgrammierer vor und für uns erledigt haben. Die Systemaufrufe (Sektion 2) gehörendagegen nicht zur Standardbibliothek (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 portiert wer<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 mitgelieferte Standardbibliothek wird imReferenz-Handbuch unter <strong>in</strong>tro(3) vorgestellt und umfaßt mehrere Teile:• die Standard-C-Bibliothek, meist gekoppelt mit <strong>de</strong>r Standard-Input-Output-Bibliothek,<strong>de</strong>n Netzfunktionen und <strong>de</strong>n Systemaufrufen (weil sie zusammen gebraucht wer<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 Messen und Regeln,• gegebenenfalls Datenbankfunktionen und weitere Spezialitäten.Außer Funktionen enthält sie Inclu<strong>de</strong>-Dateien mit Def<strong>in</strong>itionen und Makros, die von <strong>de</strong>nFunktionen 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 (/lib und /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 und braucht daher nicht als Option mitgegeben zu wer<strong>de</strong>n. Für e<strong>in</strong>engetrennten L<strong>in</strong>ker-Aufruf lautet die Option -lc. Mit <strong>de</strong>m Kommando:ar -t /lib/libc.aschauen Sie sich das Inhaltsverzeichnis <strong>de</strong>r Bibliothek an. Außer bekannten Funktionen wiepr<strong>in</strong>tf() und Systemaufrufen wie stat(2) wer<strong>de</strong>n Sie viele Unbekannte treffen. Auskunftüber diese erhalten Sie mittels <strong>de</strong>r man-Seiten, beispielsweise:


104 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>man ruserokman <strong>in</strong>squesofern die Funktionen zum Gebrauch durch Programmierer und nicht etwa nur für <strong>in</strong>terneZwecke bestimmt s<strong>in</strong>d.Input/Output Für die E<strong>in</strong>- und Ausgabe stehen <strong>in</strong> C ke<strong>in</strong>e Operatoren zur Verfügung,son<strong>de</strong>rn nur die Systemaufrufe <strong>de</strong>s Betriebssystems (unter UNIX open(2), write(2),read(2) usw.) und die Standardfunktionen aus <strong>de</strong>r zum Compiler gehören<strong>de</strong>n Bibliothek.In <strong>de</strong>r Regel s<strong>in</strong>d die Funktionen vorzuziehen, da die Programme dann leichter aufan<strong>de</strong>re Systeme übertragen wer<strong>de</strong>n können. Die Eigenheiten <strong>de</strong>r Systeme wer<strong>de</strong>n durch dieBibliothek ver<strong>de</strong>ckt. In diesem Fall ist im Programmkopf stets die Inclu<strong>de</strong>-Datei stdio.he<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 Standardbibliothek stehen rund40 Funktionen zur E<strong>in</strong>- und Ausgabe bereit, von <strong>de</strong>nen die bekanntesten pr<strong>in</strong>tf(3) zurformatierten Ausgabe nach stdout und scanf(3) zur formatierten E<strong>in</strong>gabe von 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, abgeschlossen mit <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-Bibliotheksteht e<strong>in</strong>e reiche Auswahl von Str<strong>in</strong>gfunktionen bereit. Gewarnt wird vor <strong>de</strong>r Funktiongets(3), die e<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 verursachenkann. Grundsätzlich soll man beim Arbeiten mit Str<strong>in</strong>gs <strong>de</strong>n Fall berücksichtigen,dass e<strong>in</strong> Str<strong>in</strong>g gelegentlich länger ist als <strong>de</strong>r Puffer, <strong>in</strong> <strong>de</strong>n er geschrieben wer<strong>de</strong>n soll.Da e<strong>in</strong> Str<strong>in</strong>g – wie je<strong>de</strong>s Array – ke<strong>in</strong>en Wert hat, kann er nicht per Zuweisung e<strong>in</strong>erStr<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 Arrays kümmern. Die Str<strong>in</strong>gfunktionenerwarten die Inclu<strong>de</strong>-Datei str<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"#<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);


1.5. FUNKTIONS-BIBLIOTHEKEN 105/* 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);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 Funktionen f<strong>in</strong><strong>de</strong>t sich <strong>in</strong> <strong>in</strong>tro(3N).Beispiele s<strong>in</strong>d Funktionen zur Verarbeitung von Netzadressen, Protokolle<strong>in</strong>trägen, RemoteProcedure Calls, zum Mounten ferner Datei-Systeme, zur Verwaltung von Benutzern undPasswörtern im Netz. Geht über <strong>de</strong>n Rahmen dieses Textes h<strong>in</strong>aus. Falls Sie sich e<strong>in</strong> eigenesProgramm telnet 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 automatischaufgerufen – 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 hyperbolischeFunktionen. Weiteres siehe math(5).Eigentlich sollte man bei diesen Funktionen <strong>de</strong>n zugrun<strong>de</strong> liegen<strong>de</strong>n Algorithmus undse<strong>in</strong>e Programmierung kennen, da je<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änkt sich untertrig(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 */#<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[])


106 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>{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 FunktionenDer l<strong>in</strong>t(1) gibt bei diesem Programm e<strong>in</strong>e längere Liste von Warnungen aus, die daherrühren, daß <strong>in</strong> viele Funktionen <strong>de</strong>klariert wer<strong>de</strong>n, die im Programm nichtauftauchen. 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ürnoch ke<strong>in</strong>en Standard gibt und Grafik 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 Bibliothekenthält Funktionen zum Setzen von 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, sonst gä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 alphanumerischenBildschirms. In diesem Fall ist die curses(3)-Bibliothek beim Compileraufruf zunennen:cc .... -lcursesVergißt man die Nennung, weiß <strong>de</strong>r Compiler mit <strong>de</strong>n Namen <strong>de</strong>r curses(3)-Funktionennichts anzufangen und mel<strong>de</strong>t sich mit <strong>de</strong>r Fehleranzeige unsatisfied symbols.


1.5. FUNKTIONS-BIBLIOTHEKEN 107Bei Verwendung von curses(3)-Funktionen ist die Inclu<strong>de</strong>-Datei curses.h <strong>in</strong> das Programmaufzunehmen, das stdio.h e<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 machen wollen, greifen auf untersterEbene auf Funktionen <strong>de</strong>r Xlib-Bibliothek zurück. Die Xlib stellt für je<strong>de</strong> Möglichkeit <strong>de</strong>sX-Protokolls e<strong>in</strong>e C-Funktion bereit; sie ist die Schnittstelle zwischen C-Programmen und<strong>de</strong>m X-Protokoll.Auf nächsthöherer Ebene wer<strong>de</strong>n Funktionen e<strong>in</strong>er Toolbox wie <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>sicsbezeichnet. 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 Widget gehö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 Toolkit Xm, <strong>de</strong>r e<strong>in</strong>e Menge nach e<strong>in</strong>heitlichenRegeln gebauter Widgets zur 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 sichverhä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 Bibliothek zu arbeiten, weil ersich dabei am wenigsten um E<strong>in</strong>zelheiten zu kümmern braucht.1.5.4 NAG-BibliothekDie NAG-Bibliothek <strong>de</strong>r Numerical Algorithms Group, Oxford soll hier als e<strong>in</strong> Beispielfür e<strong>in</strong>e umfangreiche kommerzielle Bibliothek stehen, die bei vielen numerischen Aufgabendie Arbeit erleichtert. Die FORTRAN-Bibliothek umfaßt etwa 1200 Subrout<strong>in</strong>en, die C-Bibliothek etwa 250 Funktionen. Sie stammen aus 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.1.5.5 Eigene BibliothekenWir haben bereits <strong>in</strong> Abschnitt 1.2.6 Bibliotheken, Archive auf Seite 25 gelernt, e<strong>in</strong>e eigeneProgrammbibliothek mittels <strong>de</strong>s UNIX-Kommandos ar(1) herzustellen. Zunächst macht esArbeit, 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>male<strong>in</strong>en Grundstock hat, zahlt es sich aus.32 E<strong>in</strong> Gadget ist laut Wörterbuch e<strong>in</strong> geniales D<strong>in</strong>gsbums.


108 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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 auch nur e<strong>in</strong>e Standardbibliothek.Unter PC-DOS h<strong>in</strong>gegen ist die Speichersegmentierung zu beachten, d. h. die Unterteilung<strong>de</strong>s Arbeitsspeichers <strong>in</strong> Segmente zu je 64 kByte, e<strong>in</strong> lästiges Überbleibsel aus uralten Zeiten.Die Adressierung <strong>de</strong>r Speicherplätze ist unterschiedlich, je nach<strong>de</strong>m ob man sich nur <strong>in</strong>nerhalbe<strong>in</strong>es Segmentes o<strong>de</strong>r im ganzen Arbeitsspeicher bewegt. Für je<strong>de</strong>s Speichermo<strong>de</strong>ll iste<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>emFehler 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 Compiler e<strong>in</strong>en Default an, MS-Quick-C (qcl) beispielsweise das Mo<strong>de</strong>ll small.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 man beschränkt.Das Mo<strong>de</strong>ll small packt Co<strong>de</strong> und Daten <strong>in</strong> je e<strong>in</strong> Segment von 64 kByte. Damit lassensich 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 mehrere Segmente für Programmco<strong>de</strong>zur Verfügung, bis zur Grenze <strong>de</strong>s freien Arbeitsspeichers. Typische Anwendungen s<strong>in</strong>dlängere Programme mit wenigen Daten.Das 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>, mehrereSegmente für die Daten. Geeignet für kurze Programme mit vielen Daten. E<strong>in</strong> e<strong>in</strong>zelnesDatenelement – 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>re<strong>in</strong> e<strong>in</strong>zelnes Datenelement nicht größ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änkung auf, aber die Beschränkungauf die Größe <strong>de</strong>s freien Arbeitsspeichers bleibt, PC-DOS schwoppt nicht.Die Schlüsselwörter near, far und huge <strong>in</strong> Verb<strong>in</strong>dung mit Po<strong>in</strong>tern o<strong>de</strong>r Funktionenhaben Vorrang vor <strong>de</strong>m vom Compiler benutzten Speichermo<strong>de</strong>ll. Bei near s<strong>in</strong>d alle Adressen16 Bits lang, bei far s<strong>in</strong>d die Adressen 32 Bits lang, die Po<strong>in</strong>terarithmetik geht jedoch von16 Bits aus, und bei huge schließlich läuft alles mit 32 Bits und entsprechend langsam ab.Falls Ihnen das zu 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>er e<strong>in</strong>zigen Datei.• E<strong>in</strong>e Bibliothek hat nichts mit Verschlüsseln o<strong>de</strong>r Komprimieren zu 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 Kompiliervorgang wer<strong>de</strong>n genau die benötigtenFunktionen ausgewählt und <strong>in</strong>s Programm e<strong>in</strong>gebun<strong>de</strong>n.• Es gibt Standardbibliotheken, die zum Compiler gehören und von diesem automatischherangezogen wer<strong>de</strong>n.• Weiter gibt es Standardbibliotheken, die zum Compiler gehören, aber eigens über e<strong>in</strong>eOption herangezogen wer<strong>de</strong>n mü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 von Bibliotheken, beispielsweisefür numerische Aufgaben o<strong>de</strong>r das X W<strong>in</strong>dow System.• Man kann auch eigene Funktionen <strong>in</strong> Privatbibliotheken zusammenfassen. Das lohntsich, wenn man längere Zeit für e<strong>in</strong> bestimmtes Thema programmiert.1.5.8 Übung BibliothekenFassen Sie die Funktionen <strong>de</strong>s Weganalyse-Projektes außer ma<strong>in</strong>() <strong>in</strong> e<strong>in</strong>er Privatbibliothekzusammen und b<strong>in</strong><strong>de</strong>n sie diese beim Kompiliervorgang dazu.


1.6. KLASSEN 1091.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 Stelle kommen dann dieProgrammiersprachen, die die e<strong>in</strong>e o<strong>de</strong>r an<strong>de</strong>re Denkweise unterstützen. Man kann mit objektorientiertenSprachen prozedural aufgebaute Programme schreiben und mit prozeduralenSprachen objektorientierte Programme. Da <strong>de</strong>r Ausgangspunkt die Aufgabenanalyse ist,macht sich die Objektorientierung bei kle<strong>in</strong>en Programmen (wo es nichts zu analysieren gibt)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 Objektorientierung und Klassen ist da nochnichts 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];cout « "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 Input Stream, auf das zweite, <strong>de</strong>nStr<strong>in</strong>g v. Das Stream-Konzept zur 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>r Typen, was er vor sich hat). In <strong>C++</strong> gibt es e<strong>in</strong>e Vielzahlsolcher Verbesserungen o<strong>de</strong>r Erweiterungen von C, aber sie s<strong>in</strong>d nichts grundsätzlich Neues;sie erfor<strong>de</strong>rn ke<strong>in</strong> Um<strong>de</strong>nken, son<strong>de</strong>rn nur das Lesen <strong>de</strong>s Referenzmaterials.Obiges Programm hallo.cpp ist mit <strong>de</strong>m GNU gcc kompiliert 96 kB groß. E<strong>in</strong> Assemblerprogramm,das dasselbe tut, belegt 120 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> Datentyp e<strong>in</strong>e Menge von Wertensamt <strong>de</strong>n zugehörigen Operationen. Die Datentypen s<strong>in</strong>d durch <strong>de</strong>n Compiler festgelegt, <strong>de</strong>rBenutzer kann 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>ierter Typ, <strong>de</strong>ssen Schnittstelle (Interface,Außenseite, Verb<strong>in</strong>dung zum ü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 bestimmtennach außen sichtbaren Eigenschaften. Klassen s<strong>in</strong>d <strong>in</strong> e<strong>in</strong>er Programmierspracheformulierte Beschreibungen abstrakter Datentypen. Objekte s<strong>in</strong>d Vertreter (Exemplare,Instanzen, Verwirklichungen) von Klassen. C-Typen und <strong>C++</strong>-Klassen sowie C-Variable


110 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>und <strong>C++</strong>-Objekte entsprechen sich. Aus Klassen lassen sich untergeordnete Klassen ableiten.E<strong>in</strong>e Klasse o<strong>de</strong>r e<strong>in</strong> Objekt enthält Daten (data member) und Operationen auf diesenDaten. 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>r mittels Botschaften. E<strong>in</strong>eBotschaft (message, member function call) ist die Auffor<strong>de</strong>rung an e<strong>in</strong> Objekt, e<strong>in</strong>e se<strong>in</strong>erMetho<strong>de</strong>n auszufü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 reelleZahlenwerte (Realteil und Imag<strong>in</strong>rrteil) sowie als Metho<strong>de</strong>n die Grundrechenarten fürkomplexe Zahlen 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 Objektezur Umwelt. Private Members s<strong>in</strong>d nur <strong>de</strong>n Metho<strong>de</strong>n <strong>de</strong>r Klasse zugänglich. Publicund private wer<strong>de</strong>n als Member Access Specifier bezeichnet. Meist s<strong>in</strong>d die Daten privat,die Metho<strong>de</strong>n teils 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>mselben Namen wie die Klasse - ist <strong>de</strong>r Constructor,<strong>de</strong>r zur Initialisierung dient. Diese Metho<strong>de</strong> wird automatisch aufgerufen, wenne<strong>in</strong> Objekt <strong>de</strong>r Klasse erzeugt wird. E<strong>in</strong> Constructor kann public, protected o<strong>de</strong>r private se<strong>in</strong>;er hat niemals e<strong>in</strong>en Rückgabewert e<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. Es rechnet die Zeiten von UTCnach 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 */#<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 sichtbar,// 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, pruefen


1.6. KLASSEN 111void 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// 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 nach MEZ1.6.3 Klassenhierarchie, abstrakte Klassen, VererbungObjektorientiertes Programmieren besteht im Programmieren e<strong>in</strong>er Menge von Klassen, <strong>de</strong>renzughörige Objekte <strong>de</strong>n Programmablauf verwirklichen. Das folgen<strong>de</strong> Programm zeigt,wie aus e<strong>in</strong>er Basisklasse weitere Klassen abgeleitet wer<strong>de</strong>n, die die public und protectedmembers erben. Von e<strong>in</strong>er abstrakten Klasse können nur weitere Klassen abgeleitet, jedochke<strong>in</strong>e Objekte gebil<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>e re<strong>in</strong> virtu-


112 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>elle 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>erabgeleiteten Klasse e<strong>in</strong>en Inhalt 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. Funktionen// public fuer abg. Klasse,// ansonsten private// nach aussen unsichtbar// 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.virtual double <strong>in</strong>halt(double, double) = 0;private:};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 {public:Kreis() {a = x = y = 0;}// abgel. konkr. Klasse// Constructor


1.6. KLASSEN 113void 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;u = 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. Klassepublic:


114 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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;// 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;// Erzeugen <strong>de</strong>s Objektes f


1.6. KLASSEN 115}return 0;}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();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 Programmierung nahe, da sie e<strong>in</strong>eHierarchie bil<strong>de</strong>n, ähnlich wie Pflanzen o<strong>de</strong>r Tiere. Im Beispiel wird als erstes e<strong>in</strong>e abstrakteBasisklasse Form <strong>de</strong>f<strong>in</strong>iert, die das enthält, was allen Formen geme<strong>in</strong>sam ist. Das ist nichtviel und steht <strong>in</strong> <strong>de</strong>n bei<strong>de</strong>n re<strong>in</strong> virtuellen Funktionen lesen() und schreiben.Aus <strong>de</strong>r Klasse Form wer<strong>de</strong>n die bei<strong>de</strong>n immer noch abstrakten Klassen Flaeche undKoerper abgeleitet. Von Flächen läß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 Funktionen umfang() und <strong>in</strong>halt().Für Körper haben wir entsprechend die abstrakte Klasse Koerper mit <strong>de</strong>n re<strong>in</strong> virtuellenFunktionen flaeche() (Oberfläche) und volumen().Im nächsten Schritt gelangen wir endlich zu konkreten Klassen. Aus <strong>de</strong>r Klasse flaechewer<strong>de</strong>n die Klassen Kreis und Rechteck abgeleitet, aus <strong>de</strong>r Klasse Rechteck noch dieKlasse Quadrat. Während aus abstrakten Klassen nur weitere, abstrakte o<strong>de</strong>r konkreteKlassen abgeleitet wer<strong>de</strong>n können, lassen sich aus konkreten Klassen weitere konkrete Klassenableiten o<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 Klasse Koerper die konkretenKlassen Kugel und Qua<strong>de</strong>r ab, aus Qua<strong>de</strong>r nochmals Wuerfel.In <strong>de</strong>n konkreten Klassen erhalten die virtuellen Funktionen auch e<strong>in</strong>en konkreten Inhalt,das heißt, die Platzhalter wer<strong>de</strong>n mit <strong>de</strong>n Formeln für <strong>de</strong>n Flächen<strong>in</strong>halt e<strong>in</strong>es Kreiseso<strong>de</strong>r Rechtecks besetzt usw. Diese Formeln sehen für je<strong>de</strong> konkrete geometrische Form an<strong>de</strong>rsaus.


116 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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>n Klasse (Basisklasse)die public members als public und die protected members als protected geerbt wer<strong>de</strong>n. Dieprivate members wer<strong>de</strong>n <strong>in</strong> ke<strong>in</strong>em Fall vererbt. Hätten wir dagegen das Wort privategebraucht, 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, auch Freun<strong>de</strong> können erben, un<strong>de</strong><strong>in</strong>e Klasse kann aus zwei Basisklassen abgeleitet 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>n Vorteil, dass man aufje<strong>de</strong>r Stufe genau das festlegt, was sich dort festlegen läßt, nicht mehr und nicht weniger.Kontrollen und Ä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 Benutzerdialogwer<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>iertenFunktionen lesen() und schreiben(). 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>r Außenseite streng getrennt(Black Box).• Klassen s<strong>in</strong>d <strong>in</strong> e<strong>in</strong>er Programmiersprache formulierte Beschreibungen abstrakter Datentypen.• Objekte s<strong>in</strong>d Verwirklichungen von Klassen, so wie Variable Verwirklichungen von Typens<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 (memberfunctions).• Daten und Metho<strong>de</strong>n s<strong>in</strong>d öffentlich (public), geschützt (protected) o<strong>de</strong>r privat. Die Datens<strong>in</strong>d meist privat. M<strong>in</strong><strong>de</strong>stens e<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, die die öffentlichen und geschützten(protected) Daten und Metho<strong>de</strong>n erben. 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 abgeleitetwer<strong>de</strong>n. Meist <strong>in</strong> <strong>de</strong>n oberen Etagen <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>e Klassenhierarchie nahelegt.Bei an<strong>de</strong>ren h<strong>in</strong>wie<strong>de</strong>rum wirkt die Objektorientierung verkrampft. Mit C/<strong>C++</strong> s<strong>in</strong>d alle Wegeoffen.Überlegen Sie, welche Klassen und Objekte man bei <strong>de</strong>r Aufgabe zur Weganalyse zweckmäßige<strong>in</strong>richtet. S<strong>in</strong>d die Wegstrecken o<strong>de</strong>r die Fahrzeuge/Personen als Objekte anzusehen?Skizzieren Sie – ohne genau auf die Syntax zu achten – e<strong>in</strong>e Klassenhierarchie samt Datenund Metho<strong>de</strong>n.In <strong>de</strong>m Beispielprogramm zur Befeuerung von B<strong>in</strong>nenschiffen kann man sich gut e<strong>in</strong>eHierarchie von Fahrzeugen und entsprechen<strong>de</strong>n Klassen vorstellen, wobei an <strong>de</strong>r Spitze dieKlasse <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 dieKlassen, Daten und Metho<strong>de</strong>n aussehen? Welche Vorteile hätte hier die Objektorientierungvor <strong>de</strong>r prozeduralen Denkweise?


1.7. KLASSEN-BIBLIOTHEKEN 1171.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, ohne die man nicht weit kommt.Die Benutzer betrachten sie als festen Bestandteil <strong>de</strong>r Compiler, obwohl sie im strengen S<strong>in</strong>nnicht Bestandteil <strong>de</strong>r Sprache s<strong>in</strong>d. Zu <strong>C++</strong> gehört ebenso wie zu C e<strong>in</strong>e Standardbibliothek,<strong>de</strong>ren Umfang und Funktionalität durch e<strong>in</strong>e ISO/ANSI-Norm festgelegt ist. Im wesentlichengehören dazu:• die C-Standardbibliothek (damit man sie nicht extra zu nennen 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 als die C-Standardbibliothek, sieerfor<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 Library spielt e<strong>in</strong>e beson<strong>de</strong>re Rolle, weilsie 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 StandardTemplate Library (STL) als Erweiterung <strong>de</strong>r <strong>C++</strong>-Standard-Bibliothek durch dasANSI-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 bestimmtenWert durchsuchen will, sieht die Funktion 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>d dagegen allgeme<strong>in</strong> gültig,<strong>in</strong><strong>de</strong>m sie mit Hilfe von Templates <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 Funktion o<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 als Parameter mitgegeben wer<strong>de</strong>n – ähnlich wiebei e<strong>in</strong>em Funktionsaufruf die Typen <strong>de</strong>r Argumente. Der Compiler erzeugt dann aus <strong>de</strong>mTemplate die gewünschte Klasse o<strong>de</strong>r Funktion und nimmt 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>n e<strong>in</strong>gesetzt, um auf Elementevon Conta<strong>in</strong>ern zuzgreifen, so wie man mittels Po<strong>in</strong>terarithmetik auf die Elementee<strong>in</strong>es Arrays zugreift. Im Gegensatz zu Po<strong>in</strong>tern br<strong>in</strong>gen sie jedoch e<strong>in</strong>e gewisse eigene Intelligenzmit, so daß <strong>de</strong>r Programmierer – wenn er erst e<strong>in</strong>mal ihre Funktionsweise begriffenhat – weniger Arbeit 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 Datenstrukturen o<strong>de</strong>r Objekte enthalten. Damit lässt sich e<strong>in</strong>e Gruppe vonObjekten unter e<strong>in</strong>em Namen geme<strong>in</strong>sam handhaben. Sequentielle Conta<strong>in</strong>er speichernihre 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>ren Objekte über e<strong>in</strong>en


118 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Schlüssel o<strong>de</strong>r In<strong>de</strong>x zugänglich s<strong>in</strong>d. Der e<strong>in</strong>fachste sequentielle Conta<strong>in</strong>er ist <strong>de</strong>r Vektor,e<strong>in</strong> Array variabler Größe. Der e<strong>in</strong>fachste assoziative Conta<strong>in</strong>er ist die Menge (Set), <strong>in</strong> <strong>de</strong>rje<strong>de</strong>r Schlüssel nur e<strong>in</strong>mal vorkommen darf. Zu je<strong>de</strong>r Art von Conta<strong>in</strong>ern gehört e<strong>in</strong> Satz vonMetho<strong>de</strong>n. Auch hier braucht sich <strong>de</strong>r Programmierer nicht um die E<strong>in</strong>zelheiten <strong>de</strong>r Speicherungund <strong>de</strong>r Zugriffe zu kümmern, das hat die Bibliothek bereits erledigt.E<strong>in</strong> Adaptor schließlich macht das, was auch an<strong>de</strong>re Adapter machen: er paßt das Aussehene<strong>in</strong>er Schnittstelle an neue Erfor<strong>de</strong>rnisse an, er verpackt e<strong>in</strong>en Iterator o<strong>de</strong>r e<strong>in</strong>enConta<strong>in</strong>er <strong>in</strong> e<strong>in</strong>e neue Umhüllung. Damit wird nicht e<strong>in</strong> neues Objekt geschaffen, son<strong>de</strong>rnnur se<strong>in</strong>e Außenseite verän<strong>de</strong>rt. Das ist oftmals effektiver, als e<strong>in</strong> neues Objekt zu schreiben.Um die STL ganz zu verstehen, muß man sie benutzen. Da sie auf e<strong>in</strong>er hohen Abstraktionsebenezu Hause ist, machen sich ihre Vorteile erst bei umfangreicheren Aufgaben bemerkbar.Für Hallo-Welt-Programme ist sie e<strong>in</strong>ige Nummern zu groß. Wir verweisen daherauf das Buch von ROBERT ROBSON und auf unsere Technik-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 Angewandte Mathematik <strong>de</strong>r UniversitätKarlsruhe e<strong>in</strong>e Klassenbibliothek C-XSC als Ergänzung e<strong>in</strong>es <strong>C++</strong>-Compilers entwickelt33 . Das Kürzel XSC ist als Exten<strong>de</strong>d Scientific Comput<strong>in</strong>g zu <strong>de</strong>uten. Die wichtigstenBestandteile von C-XSC s<strong>in</strong>d:• Arithmetik reeller und komplexer Zahlen sowie Intervallarithmetik mit mathematischbestimmten Eigenschaften,• dynamische Vektoren und Matrizen mit zur Laufzeit verän<strong>de</strong>rbarer Größe,• Teilfel<strong>de</strong>r (Subarrays) aus Vektoren und Matrizen,• arithmetische Operatoren und mathematische Standardfunktionen von hoher, bekannterGenauigkeit,• 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>r Behandlung numerischer Aufgabenüber FORTRAN und an<strong>de</strong>re Programmiersprachen h<strong>in</strong>aus.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 Operatoren und <strong>de</strong>n mathematischenStandardfunktionen. Alle vor<strong>de</strong>f<strong>in</strong>ierten arithmetischen Operatoren liefern Ergebnisse mite<strong>in</strong>er Genauigkeit 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>dsie maximal genau im S<strong>in</strong>ne <strong>de</strong>s wissenschaftlichen Rechnens. Die von <strong>de</strong>n arithmetischenOperatoren vorgenommenen Rundungen lassen sich durch <strong>de</strong>n Gebrauch <strong>de</strong>r Datentypen<strong>in</strong>terval und c<strong>in</strong>terval steuern. Funktionen zur Typumwandlung s<strong>in</strong>d für alle mathematischs<strong>in</strong>nvollen Komb<strong>in</strong>ationen verfügbar. Alle mathematischen Standardfunktionen füre<strong>in</strong>fache numerische Datentypen können mit ihrem gewohnten Namen aufgerufen wer<strong>de</strong>nund liefern Ergebnisse von garantierter hoher Genauigkeit für beliebige Argumente aus <strong>de</strong>m33 Dieser Abschnitt ist die gekürzte Übersetzung e<strong>in</strong>es Aufsatzes (1992) vonDipl.-Math. ANDREAS WIETHOFF, Mitarbeiter <strong>de</strong>s genannten Institutes, siehewww.uni-karlsruhe.<strong>de</strong>/˜iam/html/language/cxsc/cxsc.html.


1.7. KLASSEN-BIBLIOTHEKEN 119Def<strong>in</strong>itosnbereich. Die Standardfunktionen für die Datentypen <strong>in</strong>terval und c<strong>in</strong>tervalliefern 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 die entsprechen<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 Laufzeit zuordnen und freigeben.Auf diese Weise kann dasselbe Programm für Arrays unterschiedlicher Größe benutzt wer<strong>de</strong>n,begrenzt nur durch <strong>de</strong>n Arbeitsspeicher. Es wird nicht mehr Speicher von <strong>de</strong>n Datenbelegt, als wirklich benötigt wird. Beim Zugriff auf Arrays wird <strong>de</strong>r In<strong>de</strong>xbereich zur Laufzeitgeprüft, um Programmabstürze durch unzulässige Speicherzugriffe (memory faults) zuverh<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>er Matrix:...<strong>in</strong>t n, m;cout > 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 nach stdout geschrieben, dannwer<strong>de</strong>n mit c<strong>in</strong> die bei<strong>de</strong>n In<strong>de</strong>xgrenzen n und m von std<strong>in</strong> e<strong>in</strong>gelesen. Die Vere<strong>in</strong>barunge<strong>in</strong>es Vektors o<strong>de</strong>r e<strong>in</strong>er Matrix ohne Angabe <strong>de</strong>r In<strong>de</strong>xgrenzen liefert e<strong>in</strong>en Vektor mit e<strong>in</strong>erKomponente o<strong>de</strong>r e<strong>in</strong>e Matrix mit je e<strong>in</strong>er Zeile und Spalte. Speicher für diese Objekte wir<strong>de</strong>rst an 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. Die Resize-Anweisung br<strong>in</strong>gt die Matrix B zur Laufzeit andieser Programmstelle 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>e Matrix kann auch implizit –ohne e<strong>in</strong>e ausdrückliche Anweisung wie Resize – durch e<strong>in</strong>e Zuweisung erfolgen. Falls dieIn<strong>de</strong>xgrenzen <strong>de</strong>s Objektes auf <strong>de</strong>r rechten Seite e<strong>in</strong>er Zuweisung nicht 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 eshier mit <strong>de</strong>r Matrix C geschieht.Der dynamisch zugewiesene Speicherplatz e<strong>in</strong>es lokal vere<strong>in</strong>barten Arrays wird automatischbeim Verlassen <strong>de</strong>s Gültigkeitsbereiches freigegeben. H<strong>in</strong>sichtlich Lebensdauer undGültigkeitsbereich besteht ke<strong>in</strong> Unterschied zu <strong>de</strong>n aus C gewohnten Arrays.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>rzeit durch Aufrufen <strong>de</strong>r FunktionenLb() und Ub() für die untere bzw. 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 von Teilfel<strong>de</strong>rn (Subarrays) vonVektoren und Matrizen zur Verfügung. Subarrays s<strong>in</strong>d beliebige rechteckige Ausschnitte ausArrays. Alle vor<strong>de</strong>f<strong>in</strong>ierten Operatoren nehmen auch Subarrays als Operan<strong>de</strong>n an. E<strong>in</strong> Subarraye<strong>in</strong>er Matrix o<strong>de</strong>r e<strong>in</strong>es Vektors wird über <strong>de</strong>n ()-Operator o<strong>de</strong>r über <strong>de</strong>n []-Operatorangesprochen. Der ()-Operator bezeichnet e<strong>in</strong> Subarray e<strong>in</strong>es Objektes vom selben Typ wiedas ursprüngliche Objekt. Ist beispielsweise A e<strong>in</strong>e reelle n x n-Matrix, dann ist A(i,i) diel<strong>in</strong>ke obere i x i-Submatrix. Man beachte, daß die Klammern <strong>in</strong> <strong>de</strong>r Deklaration e<strong>in</strong>es dynamischenVektors 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>nIn<strong>de</strong>xbereich <strong>de</strong>s anzulegen<strong>de</strong>n Objektes 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 x n-rmatrix ist, dann ist A[i] diei-te Zeile von A mit <strong>de</strong>m Typ rvector, und A[i][j] ist das (i,j)-te Element von A mit <strong>de</strong>m Typreal.


120 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Bei<strong>de</strong> Arten <strong>de</strong>s Zugriffs auf Subarrays können auch verbun<strong>de</strong>n wer<strong>de</strong>n, beispielsweiseist A[k](i,j) e<strong>in</strong> Subvektor von In<strong>de</strong>x i 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-Faktorisierunge<strong>in</strong>er n * n-Matrix A beschreibt:for (j = 1; j


1.7. KLASSEN-BIBLIOTHEKEN 121Quelle 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-Akkumulator accu ohne Rundungsfehler. Dieidotprecision-Variable accu wird 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 Weises<strong>in</strong>d die Grenzen von INCL[i] entwe<strong>de</strong>r gleich o<strong>de</strong>r zwei beanchbarte Gleitkommazahlen.Für alle Dotprecision-Datentypen steht e<strong>in</strong> verr<strong>in</strong>gerter Satz vor<strong>de</strong>f<strong>in</strong>ierter Operatorenzur Verfügung, um fehlerfreie Ergebnisse zu berechnen. Die überla<strong>de</strong>ne Skalarprodukt-Funktion accumulate() und die Rundungsfunktion rnd() s<strong>in</strong>d für alle s<strong>in</strong>nvollen Typkomb<strong>in</strong>ationenverfügbar.1.7.3.5 Dynamische Langzahl-ArithmetikNeben <strong>de</strong>n Klassen real und <strong>in</strong>terval gibt es die dynamischen Klassen l_real (long real)und l_<strong>in</strong>terval (long <strong>in</strong>terval) ebenso wie die entsprechen<strong>de</strong>n dynamischen Vektoren undMatrizen samt allen arithmetischen und relationalen Operatoren und allen Standardfunktionenmit 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_realund l_<strong>in</strong>terval <strong>in</strong> <strong>de</strong>n Deklarationen wird e<strong>in</strong> Anwendungsprogramm zu e<strong>in</strong>em Programmmit mehrfacher Genauigkeit. Dieses Konzept gibt <strong>de</strong>m Benutzer e<strong>in</strong> mächtiges und e<strong>in</strong>fachzu handhaben<strong>de</strong>s Werkzeug zur Fehleranalyse <strong>in</strong> die Hand. Weiterh<strong>in</strong> ist es möglich Programmezu schreiben, die numerische Ergebnisse mit e<strong>in</strong>er vom Benutzer vorgegebenen Genauigkeitliefern, <strong>in</strong><strong>de</strong>m man <strong>in</strong>tern die Rechengenauigkeit zur 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 Typenl_real und l_<strong>in</strong>terval verfügbar. Zusätzlich s<strong>in</strong>d auch alle möglichen Komb<strong>in</strong>ationenvon Operatoren für Typen e<strong>in</strong>facher und mehrfacher Genauigkeit vorhan<strong>de</strong>n. Im folgen<strong>de</strong>nwird e<strong>in</strong> Programm mit e<strong>in</strong>facher Genauigkeit und sie entsprechen<strong>de</strong> Version mit mehrfacherGenauigkeit gezeigt: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


122 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Quelle 1.67 : C-XSC-Programm mehrfacher GenauigkeitZur Laufzeit bestimmt die vor<strong>de</strong>f<strong>in</strong>ierte globale <strong>in</strong>t-Variable stagprec (staggered precision)die Rechengenauigkeit <strong>de</strong>r Langzahl-Arithmetik <strong>in</strong> Schritten e<strong>in</strong>er real-Zahl (64-Bit-Masch<strong>in</strong>enwort). Die Genauigkeit e<strong>in</strong>er Langzahl ist als die Anzahl von real-Zahlen <strong>de</strong>f<strong>in</strong>iert,die zur Speicherung <strong>de</strong>r langen Zahl verwen<strong>de</strong>t wer<strong>de</strong>n. E<strong>in</strong> Objekt <strong>de</strong>s Typs l_realo<strong>de</strong>r l_<strong>in</strong>terval kann se<strong>in</strong>e Genauigkeit zur Laufzeit än<strong>de</strong>rn. Komponenten e<strong>in</strong>es Vektorso<strong>de</strong>r e<strong>in</strong>er Matrix dürfen von unterschiedlicher Genauigkeit se<strong>in</strong>. Alle Standardfunktionenund sonstigen Funktionen <strong>de</strong>r Langzahl-Arithmetik berechnen numerische Ergebnisse mite<strong>in</strong>er Genauigkeit, die durch <strong>de</strong>n augenblicklichen Wert von stagprec bestimmt ist. Speicherzuweisung,das Än<strong>de</strong>rn <strong>de</strong>r Größe von Arrays und das Arbeiten mit Subarrays verlaufenähnlich wie bei <strong>de</strong>n entsprechen<strong>de</strong>n Datentypen e<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 überladbaren Operatoren >von <strong>C++</strong> ermöglicht C-XSC das Run<strong>de</strong>n und Formatieren aller se<strong>in</strong>er Datentypen während<strong>de</strong>r E<strong>in</strong>- und Ausgabe, auch für die Dotprecision- und Langzahldatentypen. E<strong>in</strong>-/Ausgabe-Parameter wie die Richtung <strong>de</strong>r Rundung, Feldbreite usw. benutzen auch die überla<strong>de</strong>nenI/O-Operatoren zum Formatieren <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>ternen Stack gespeichert undbei Bedarf zurückgeholt wer<strong>de</strong>n. Das folgen<strong>de</strong> Beispiel zeigt die Möglichkeiten von C-XSCzur E<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>t */cout > b; /* lies b aufwaerts gerun<strong>de</strong>t */"[0.11, 0.22]" >> c; /* Str<strong>in</strong>g nach Intervall */cout


1.7. KLASSEN-BIBLIOTHEKEN 1231.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 reellen Funktion f(x). Die erste Ableitungf ′ (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>e verbesserte E<strong>in</strong>schließungX n+1 mittels <strong>de</strong>r Formel:(X n+1 := m(X n ) − f(m(X )n))f ′ ∩ X n(X n )berechnet, wobei m(X) e<strong>in</strong> Punkt im Intervall X ist, üblicherweise die Mitte. Die Funktionsei <strong>in</strong> diesem Beispiel:f(x) = √ x + (x + 1) · cos xNun das Programm:/* 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"#<strong>in</strong>clu<strong>de</strong> "imath.hpp"// Interval arithmetic package// 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


124 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>} while (y != y_old);elsecout


1.7. KLASSEN-BIBLIOTHEKEN 125# 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.mocQuelle 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 = 0);// 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>n// an dieser Stelle wird das moc-File e<strong>in</strong>gebun<strong>de</strong>n;// es enthaelt die Prototypen fuer unsere Klasse#<strong>in</strong>clu<strong>de</strong> "qhello.moc"


126 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>// 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<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-Toolkit


1.8. ÜBERLADEN VON OPERATOREN 127Für das Hauptfenster wer<strong>de</strong>n e<strong>in</strong> neues Widget von <strong>de</strong>r Widget-Oberklasse QWidgetabgeleitet, das Beschriftung und Knopf erzeugt und das Signal clicked(), welches <strong>de</strong>rKnopf bei Betätigung aussen<strong>de</strong>t, mit <strong>de</strong>m klasseneigenen Slot tschuess() verbun<strong>de</strong>n. DieserSlot sen<strong>de</strong>t das ebenfalls klasseneigene Signal neuerText() aus, das vorher mit <strong>de</strong>mSlot setText() <strong>de</strong>s Beschriftungsfel<strong>de</strong>s verbun<strong>de</strong>n wur<strong>de</strong>. Dieser Slot setzt, se<strong>in</strong>em Namengemäß, <strong>de</strong>n Text <strong>de</strong>s Beschriftungsfel<strong>de</strong>s neu. Gleichzeitig wird e<strong>in</strong> Timer erzeugt und gestartet,<strong>de</strong>r nach 1500 ms das Signal timeout() aussen<strong>de</strong>t, welches wie<strong>de</strong>rum mit <strong>de</strong>m Slotquit() <strong>de</strong>r Hauptapplikation verbun<strong>de</strong>n wird. Die Funktion dieses Slots ergibt sich ebenfallsaus se<strong>in</strong>em Namen.Dieses Basisprogramm läßt sich unter Zuhilfename <strong>de</strong>r exzellenten Onl<strong>in</strong>e-Dokumentation zu Qt, die sich auf <strong>de</strong>m Webserver von Troll Tech (www.troll.no)f<strong>in</strong><strong>de</strong>t, schnell erweitern. Probieren Sie 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 zu erlernen und zeitigtschnell Erfolgserlebnisse.1.8 Überla<strong>de</strong>n von OperatorenDie arithmetischen Operationen auf Ganzzahlen unterschei<strong>de</strong>n sich 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. DasProgramm erkennt aus <strong>de</strong>m Zusammenhang, welche Art von Operation gefragt ist. DieseMöglichkeit, e<strong>in</strong>em Operator je nach Zusammenhang 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 fast je<strong>de</strong>n Operator undje<strong>de</strong> Funktion aus<strong>de</strong>hnen.Wir sehen uns am Beispiel e<strong>in</strong>es <strong>C++</strong>-Programmes zur Berechnung von Primzahlen nach<strong>de</strong>m Divisionsverfahren an, wie e<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 2005/02/06 19:44:00 wu#<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 *//************/PRIM::PRIM(<strong>in</strong>t anzahl = 1, <strong>in</strong>t primzahl = 2) // Constructor{prim count = anzahl;


128 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}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 Anzahlreturn(*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 ausgeben


1.9. PRÄPROZESSOR 129cout « "\nPrimzahlen bis " « max « " <strong>in</strong>kl.: \n\n";// Primzahlen berechnen und ausgebenwhile (pzahl.get prim()


130 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>#<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äblich durch die <strong>de</strong>f<strong>in</strong>ierteFolge. Das spart Tipperei und verbessert die Ü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ührt wer<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 Umgebunge<strong>in</strong>gebettet se<strong>in</strong>, das Makro wird 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:PROD(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, und das ist vermutlich nicht dasGewü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 willunbed<strong>in</strong>gt die 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 die anschließ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 dieserzum eigentlichen Compiler gelangt. Die Inclu<strong>de</strong>-Dateien ihrerseits enthalten symbolischeKonstanten und Makros. Grundsätzlich jedoch dürfen sie alles enthalten, was nicht gegendie Regeln von C/<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 eigenerInclu<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 auch das Quellprogramm steht. Falls <strong>de</strong>r Präprozessor dort nicht fündig wird, o<strong>de</strong>r falls<strong>de</strong>r Name <strong>in</strong> spitzen Klammern e<strong>in</strong>geschlossen ist, wird <strong>in</strong> vorgegebenen Verzeichnissen wie/usr/<strong>in</strong>clu<strong>de</strong> gesucht. Durch Compileroptionen (siehe man cpp) läßt sich die Suche 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 Benutzererstellte Inclu<strong>de</strong>-Dateien im selben Verzeichnis wie die Programmquelle. Die Datei-Kennung .h ist üblich, aber nicht notwendig. Als Beispiel sehen wir uns die häufig gebrauchteDatei <strong>in</strong> gekürzter Form an:


1.9. PRÄPROZESSOR 131/* @(#) $Revision: 1.1.1.1 $ */#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)#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)))


132 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>#<strong>de</strong>f<strong>in</strong>e feof(p)#<strong>de</strong>f<strong>in</strong>e ferror(p)#<strong>de</strong>f<strong>in</strong>e fileno(p)#elsevoid clearerr();#endif not l<strong>in</strong>t((p)->_flag & _IOEOF)((p)->_flag & _IOERR)(p)->_fileextern 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> beliebiger Reihenfolge im Programmaufgeführt wer<strong>de</strong>n, auch mehrmals. Es dürfen auch zwei Standard-Inclu<strong>de</strong>-Dateienaufgeführt wer<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>-Dateischließt niemals e<strong>in</strong>e an<strong>de</strong>re Standard-Inclu<strong>de</strong>-Datei e<strong>in</strong>. Wie sich Nichtstandard-Inclu<strong>de</strong>-Dateien verhalten, ist offen.1.9.3 Bed<strong>in</strong>gte Kompilation (#if<strong>de</strong>f)Bei <strong>de</strong>r Programmentwicklung möchte man gelegentlich leicht vone<strong>in</strong>an<strong>de</strong>r abweichen<strong>de</strong>Fassungen e<strong>in</strong>es ausführbaren Programms erzeugen, ohne dafür verschie<strong>de</strong>ne Quellfilesschreiben zu müssen. Unser C-Programm 1.89 auf Seite 153 zur Berechnung von Primzahlenhat verschie<strong>de</strong>ne Obergrenzen, je nach<strong>de</strong>m ob es unter PC-DOS o<strong>de</strong>r UNIX läuft. ImProgrammkopf vor 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 auf UNIX-Systemen e<strong>in</strong>en höherenWert 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>n Option 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äprozessorausgewertet mit <strong>de</strong>r Folge, daß die Konstante MAX, die <strong>de</strong>n untersuchten Zahlenbereichnach oben begrenzt, auf e<strong>in</strong>e Million gesetzt wird. Beim Kompilieren unter PC-DOS entfälltdie Option -DUNIX.E<strong>in</strong>e zweite Anwendung ist die Erzeugung von Programmversionen, die zwecks Fehlersucheetwas gesprächiger s<strong>in</strong>d als die Endfassung. Man gibt beispielsweise Zwischenwertefolgen<strong>de</strong>rmaßen aus:34 Manche Compiler verlangen, daß das Doppelkreuz <strong>in</strong> je<strong>de</strong>m Fall am Beg<strong>in</strong>n <strong>de</strong>r Zeilesteht.


1.9. PRÄPROZESSOR 133#<strong>de</strong>f<strong>in</strong>e DEBUG 1<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 Konstante DEBUG 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 Programmangewen<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>rnicht./* 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>.");cont<strong>in</strong>ue;}#if<strong>de</strong>f DEBUGpr<strong>in</strong>tf("\nb = %d#endifx = %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, b);for (i = MAX - 1; i >= 0; i-) {pr<strong>in</strong>tf("%d ", r[i]);}


134 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>} /* 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 135E<strong>in</strong>e Dokumentation 35 gehört zu je<strong>de</strong>m Programm, das länger als e<strong>in</strong>e Seite ist und längerals e<strong>in</strong>en Tag benutzt wer<strong>de</strong>n soll.An<strong>de</strong>rerseits zählt das Schreiben von Dokumentationen nicht zu <strong>de</strong>n Liebl<strong>in</strong>gsbeschäftigungen<strong>de</strong>r Programmierer, das Erfolgserlebnis fehlt. Wir stellen hier e<strong>in</strong>ige Regeln auf,die für Programme zum Eigengebrauch gelten; bei kommerziellen Programmen gehen dieFor<strong>de</strong>rungen weiter.Die erste Gelegenheit zum Dokumentieren ist <strong>de</strong>r Kommentar im Programm. Man sollreichlich kommentieren, aber ke<strong>in</strong>e nichtssagen<strong>de</strong>n Bemerkungen e<strong>in</strong>flechten. Wenn <strong>de</strong>rKommentar etwa die Hälfte <strong>de</strong>s ganzen Programms ausmacht, ist das noch nicht übertrieben.1.10.2 Anfor<strong>de</strong>rungen (DIN 66 230)Zur Dokumentation legt die Norm DIN 66 230 Programmdokumentation Begriffe und Regelnfest. 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• 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>rungen35 Real programmers write programs, not documentation.


136 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Das sieht nach Arbeit aus. Man braucht nicht <strong>in</strong> allen Fällen alle Punkte zu berücksichtigen,aber ohne e<strong>in</strong>e solche Dokumentation läßt sich e<strong>in</strong> Programm nicht zuverlässig benutzenund weiterentwickeln. Im Netz f<strong>in</strong><strong>de</strong>n sich Werkzeuge, die <strong>in</strong> Verb<strong>in</strong>dung mit <strong>de</strong>m Kommentarund <strong>de</strong>r Struktur e<strong>in</strong>es Programmes halbautomatisch e<strong>in</strong>e Dokumentation erstellen. E<strong>in</strong>Beispiel ist Doxygen:http://www.doxygen.org/Zweckmäßig beschäftigt man sich mit solchen Werkzeugen frühzeitig, nicht erst, wenn <strong>de</strong>rCo<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 mannach? auf Seite ?? erläutert. Hier geht es um die technische Herstellung. Hilfreich s<strong>in</strong>d dieman-Seiten zu man(1) und man(5).Das Kommando man(1) sucht die Dokumentationen <strong>in</strong> <strong>de</strong>n durch die Umgebungs-Variable MANPATH bekannten Verzeichnissen. Das ist heute e<strong>in</strong>e lange Aufzählung, oft längerals die unter PATH. Vom Benutzer e<strong>in</strong>gerichtete o<strong>de</strong>r erstellte man-Seiten liegen vor allemunter:• /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 9 bis 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 Dokumentationenkomprimiert mit compress(1) (unter LINUX mit GNU-zip), die bei<strong>de</strong>nan<strong>de</strong>ren Verzeichnisse die unkomprimierten Texte. Die man-Verzeichnisse enthaltennroff(1)-Quelltexte, die cat-Verzeichnisse die formatierten, druckfertigen Texte.Im Verzeichnis /usr/share/man/man1.Z/ f<strong>in</strong><strong>de</strong>t sich beispielsweise die Datei ls.1mit <strong>de</strong>r komprimierten nroff-Quelle <strong>de</strong>r man-Seite zum Kommando ls(1). Gegebenenfallsliegt unter /usr/share/man/man1/ die entkomprimierte nroff-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 es e<strong>in</strong>facher.Will man selbst e<strong>in</strong>e man-Seite schreiben, kopiert man sich am 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 etwas mit <strong>de</strong>m nroff-Format ause<strong>in</strong>an<strong>de</strong>rsetzenund mit <strong>de</strong>n unter man(5) beschriebenen Makros. Die so erzeugte unkomprimiertenroff(1)-Quelle gehört <strong>in</strong> e<strong>in</strong> man-Verzeichnis. Die mittels compress(1) verdichtete Qellekommt ohne die Kennung .Z nach man.Z/. Dann formatiert man die Quelle:nroff mycommand.1 > mycommand.1.cat


1.11. WEITERE C-PROGRAMME 137und kopiert sie unter <strong>de</strong>m Namen mycommand.1 <strong>in</strong> e<strong>in</strong> cat-Verzeichnis. Schließlich ist dieformatierte Datei zu komprimieren und <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 sich aus <strong>de</strong>m jeweiligen Verzeichnis.Man braucht nicht alle Formate zu 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 samt Suchmasch<strong>in</strong>e veröffentlicht. E<strong>in</strong>eSuche nach <strong>de</strong>m Begriff time ergab 43 Seiten, von at(1) bis xshrealtime(). Die Zusammenstellunggehört zur S<strong>in</strong>gle UNIX Specification und enthält nicht die Seiten von zusätzlichenProgrammen wie sendmail(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>sKommandos <strong>in</strong>fo(1) gelesen wird. E<strong>in</strong>zelheiten am besten im WWW. Damit kommen wirzu e<strong>in</strong>em dritten Weg für onl<strong>in</strong>e-Dokumentationen, nämlich HTML-Seiten, die mit e<strong>in</strong>emWWW-Browser gelesen wer<strong>de</strong>n. Trotz <strong>de</strong>r erweiterten Möglichkeiten (Unterteilung e<strong>in</strong>es umfangreichenThemas, Hyperl<strong>in</strong>ks, Grafik) dieser neueren Formate s<strong>in</strong>d die dürren man-Seitenimmer noch am weitesten verbreitet. Inhaltlich s<strong>in</strong>d sie <strong>de</strong>n Hilfen an<strong>de</strong>rer Betriebssystemeohneh<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 nochmalsdarauf 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 Quelltext vor (<strong>in</strong> FORTRAN o<strong>de</strong>rPASCAL 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>r Name, unter <strong>de</strong>m das Programm aufgerufen wird.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, hat die Kennung .c; die meistenProgrammierwerkzeuge erwarten das. Die UNIX-Compiler schreiben standardmäßig daskompilierte Programm <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>n Fällen kann man mit <strong>de</strong>r Compiler-Option -o fürdas Ausgabefile e<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> Programm zusammensetzt. Wie sieht e<strong>in</strong>vollständiges Programm aus? Zunächst e<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önnenzu e<strong>in</strong>em durch geschweifte Klammern zusammengefaßten Block vere<strong>in</strong>igt wer<strong>de</strong>n.Nach außen wirkt dieser Block wie e<strong>in</strong>e e<strong>in</strong>zige Anweisung. Der Block ist zugleich die kle<strong>in</strong>steE<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 Funktion zusammengefaßt. DieFunktion ist die kle<strong>in</strong>ste kompilierbare E<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 Datei abgelegt se<strong>in</strong>. Dem Compiler übergibt man im M<strong>in</strong>imum e<strong>in</strong>e Datei, die e<strong>in</strong>eFunktion enthält. Mehrere Dateien h<strong>in</strong>wie<strong>de</strong>rum können e<strong>in</strong> vollständiges, nach <strong>de</strong>m Kompilierenlauffähiges Programm bil<strong>de</strong>n. Er<strong>in</strong>nern Sie sich an das Werkzeug make(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-Programm


138 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>Der 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>n Klammern. 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ückgabewertvon ma<strong>in</strong>() un<strong>de</strong>f<strong>in</strong>iert ist, was stimmt, uns aber nicht weiter stört. Der Compilererzeugt aus diesem Quellco<strong>de</strong> etwa 16 kB ausführbaren Co<strong>de</strong>. H<strong>in</strong>ter ma<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ückgabewertsorgen und – wie es sich gehört – mittels e<strong>in</strong>es Kommentars das Verständniserleichtern:/* 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 Deklaration von ma<strong>in</strong>() als <strong>in</strong>tkönnte entfallen, da sie unabän<strong>de</strong>rlich ist, aber wir wollen uns angewöhnen, alle Größenausdrücklich zu <strong>de</strong>klarieren. Den Rückgabewert können Sie sich mit <strong>de</strong>m Shell-Kommandopr<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>ige Zeilen angereichert wer<strong>de</strong>n.Wir <strong>de</strong>klarieren e<strong>in</strong>e <strong>in</strong>t-Variable namens 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 die Ausgabe auf stdout, <strong>de</strong>nBildschirm. pr<strong>in</strong>tf(3) erwartet als erstes und notwendiges Argument e<strong>in</strong>en Formatstr<strong>in</strong>g,<strong>de</strong>ssen reichhaltige 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>fachNun soll auch <strong>de</strong>r Präprozessor Arbeit bekommen. Wir <strong>de</strong>f<strong>in</strong>ieren e<strong>in</strong>e symbolische KonstanteNUMBER und schließen vorsichtshalber die 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>n wir e<strong>in</strong>en arithmetischenOperator 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;}


1.11. WEITERE C-PROGRAMME 139Quelle 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>r Funktion pr<strong>in</strong>tf(3) anstellevon x auch die Summe h<strong>in</strong>schreiben. Als Rückgabewert unseres Hauptprogrammeswollen wir <strong>de</strong>n Rückgabewert <strong>de</strong>r Funktion pr<strong>in</strong>tf(3) haben, nämlich die Anzahl <strong>de</strong>r ausgegebenenZeichen. Das Programm wird kürzer, aber auch schwieriger zu verstehen (fallsman 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, VarianteDer ausführbare Co<strong>de</strong> ist damit auf 35 KB angewachsen. Jetzt wollen wir die bei<strong>de</strong>nSumman<strong>de</strong>n im Dialog erfragen und die Summe als Makro schreiben. Außer<strong>de</strong>m soll dieRechnung wie<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>nnicht mit puts(3) ausgegeben, da diese Funktion e<strong>in</strong>en hier unerwünschten Zeilenvorschubanfügt. Denken Sie daran, daß die Funktion scanf(3) Po<strong>in</strong>ter als Argumente braucht!1.11.3 FehlersucheE<strong>in</strong>ige Gesichtspunkte s<strong>in</strong>d bereits im Abschnitt 1.2.4 Debugger auf Seite 23 behan<strong>de</strong>lt wor<strong>de</strong>n.Der erfahrene Programmierer unterschei<strong>de</strong>t sich vom Anfänger <strong>in</strong> drei Punkten:• Er macht raff<strong>in</strong>iertere Fehler.• Er weiß das.


140 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>• Er kennt die Wege und Werkzeuge zur Fehlersuche.Fehlerfreie Programme schreibt auch <strong>de</strong>r beste Programmierer nicht. Deshalb ist es wichtig,schon beim Programmentwurf an die Fehlersuche zu <strong>de</strong>nken und vor allem das Programmso zu gestalten, daß es bei e<strong>in</strong>em Fehler nicht e<strong>in</strong> richtiges Ergebnis vortäuscht. Das ist soungefähr das Schlimmste, was e<strong>in</strong> Programm machen kann. Dann lieber noch e<strong>in</strong> knallharterAbsturz. Besser ist 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 umfangreich wer<strong>de</strong>n. E<strong>in</strong> biszwei Seiten Quelltext überschaut man noch, wird es mehr, sollte man die Funktion unterteilen.Weiterh<strong>in</strong> gebe man im Entwicklungsstadium an kritischen Stellen die Werte mittelspr<strong>in</strong>tf() o<strong>de</strong>r fpr<strong>in</strong>tf() aus. Diese Zeilen kommentiert man später aus o<strong>de</strong>r klammertsie gleich <strong>in</strong> #if<strong>de</strong>f- und #endif-Anweisungen e<strong>in</strong>. Bewährt hat sich auch, die eigenen Programmee<strong>in</strong>em an<strong>de</strong>ren zu erklären, da wun<strong>de</strong>rt man sich manchmal über <strong>de</strong>n eigenen Co<strong>de</strong>.E<strong>in</strong> Programm, das man nach e<strong>in</strong> bis zwei Wochen Pause selbst nicht mehr versteht, war vonvornhere<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>r Saurier – 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, aberunerreichbaren Fehlerfreiheit – die Übersichtlichkeit. Erst wenn e<strong>in</strong> Programm sauberläuft, <strong>de</strong>nkt man über e<strong>in</strong>e Optimierung nach. Optimieren heißt schneller machen und Speichere<strong>in</strong>sparen, sowohl beim Co<strong>de</strong> wie auch zur Laufzeit. Diese bei<strong>de</strong>n Ziele wi<strong>de</strong>rsprechensich 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 Cgelten.Die optimieren<strong>de</strong> Compiler-Option -O ist mit Vorsicht zu gebrauchen. Es kommt vor,daß e<strong>in</strong> optimiertes Programm nicht mehr läuft. Die Gew<strong>in</strong>ne durch die Optimierung s<strong>in</strong>dauch nur mäßig. Immerh<strong>in</strong>, <strong>de</strong>r Versuch ist nicht strafbar.Als erstes schaut man sich die Schleifen an, von geschachtelten die <strong>in</strong>nersten. Dort solltenur das Allernotwendigste stehen.Bed<strong>in</strong>gungen sollten so e<strong>in</strong>fach wie möglich formuliert se<strong>in</strong>. Mehrfache Bed<strong>in</strong>gungensollten darauf untersucht wer<strong>de</strong>n, ob sie durch e<strong>in</strong>fache ersetzt wer<strong>de</strong>n können. Schleifensollten möglichst dadurch been<strong>de</strong>t wer<strong>de</strong>n, daß die Kontrollvariable <strong>de</strong>n Wert Null und nichtirgen<strong>de</strong><strong>in</strong>en an<strong>de</strong>ren Wert erreicht. Kontrollvariable können auch heruntergezählt wer<strong>de</strong>nstatt herauf.E<strong>in</strong>e Bed<strong>in</strong>gung mit mehreren ands o<strong>de</strong>r ors wird so lange ausgewertet, bis die Richtigkeito<strong>de</strong>r Falschheit <strong>de</strong>s gesamten Ausdrucks erkannt ist. S<strong>in</strong>d mehrere Bed<strong>in</strong>gungen durch orverbun<strong>de</strong>n, wird die Auswertung nach Erkennen <strong>de</strong>s ersten richtigen Glie<strong>de</strong>s abgebrochen.Zweckmäßig stellt man das Glied, das am häufigsten richtig ist, an <strong>de</strong>n Anfang. Umgekehrtist e<strong>in</strong> Ausdruck mit durch and verbun<strong>de</strong>nen Glie<strong>de</strong>rn falsch, sobald e<strong>in</strong> Glied falsch ist. Dasam häufigsten falsche Glied gehört an <strong>de</strong>n Anfang.Ähnliche Überlegungen gelten für die switch-Anweisung. Die häufigste Auswahl sollteals 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-Abfragevor <strong>de</strong>r Auswahl abgefangen wer<strong>de</strong>n.Überflüssige Typumwandlungen – <strong>in</strong>sbeson<strong>de</strong>re die unauffälligen impliziten – solltenzum<strong>in</strong><strong>de</strong>st <strong>in</strong> Schleifen vermie<strong>de</strong>n wer<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äßig vom Typ double s<strong>in</strong>d.Gleitkommarechnungen s<strong>in</strong>d aufwendiger als Rechnungen mit ganzen Zahlen und habenzu<strong>de</strong>m noch Tücken <strong>in</strong>folge von Rundungsfehlern. E<strong>in</strong>e Gleitkomma-Null ist nicht immer


1.11. WEITERE C-PROGRAMME 141wirklich null. Wer mit Geldbeträgen rechnet, sollte mit ganzzahligen Centbeträgen anstellevon gebrochenen Eurobeträgen arbeiten. Wenn schon mit Gleitkommazahlen gerechnetwer<strong>de</strong>n muß und <strong>de</strong>r Speicher ausreicht, ist <strong>de</strong>r Typ double vorzuziehen, <strong>de</strong>r <strong>in</strong>tern ausschließlichverwen<strong>de</strong>t wird.Von zwei möglichen Operationen ist immer die e<strong>in</strong>fachere zu wählen. Beispielsweise iste<strong>in</strong>e Addition e<strong>in</strong>facher als e<strong>in</strong>e Multiplikation, e<strong>in</strong>e Multiplikation e<strong>in</strong>facher als e<strong>in</strong>e Potenzund e<strong>in</strong>e Bitverschiebung e<strong>in</strong>facher als e<strong>in</strong>e Multiplikation mit 2. 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 Zwischenergebnisse speichert o<strong>de</strong>r besser je<strong>de</strong>smal neuberechnet, ist nicht allgeme<strong>in</strong> zu entschei<strong>de</strong>n.Kle<strong>in</strong>e Funktionen lassen sich durch Makros ersetzen, die vom 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. Damit erspart 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 Funktionzu verlegen, da je<strong>de</strong>r Funktionsaufruf Zeit kostet.Die maßvolle Verwendung globaler Variabler verbessert zwar nicht <strong>de</strong>n Stil, aber dieGeschw<strong>in</strong>digkeit von Programmen mit vielen Funktionsaufrufen, da die Parameterübergabeentfällt.Die Verwendung von Bibliotheksfunktionen kann <strong>in</strong> oft durchlaufenen Schleifen stärkerverzögern als <strong>de</strong>r E<strong>in</strong>satz spezialisierter selbstgeschriebener 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>fachste Funktion, die <strong>de</strong>nZweck erfüllt, also puts(3) anstelle von pr<strong>in</strong>tf(3), wenn es nur um die Ausgabe e<strong>in</strong>esStr<strong>in</strong>gs samt Zeilenwechsel geht.Die Adressierung von Arrayelementen durch Indizes ist langsamer als die Adressierungdurch Po<strong>in</strong>ter. Der Prozessor kennt nur Adressen, also muß er Indizes erst <strong>in</strong> Adressenumrechnen. Das erspart man ihm, wenn man gleich mit Adressen sprich Po<strong>in</strong>tern arbeitet.Wer die Po<strong>in</strong>terei noch nicht gewohnt ist, schreibt das Programm zunächst mit Indizes, testetes aus und stellt 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];/* 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 auf das erste Element (mit <strong>de</strong>mIn<strong>de</strong>x 0). Experimente mit verschie<strong>de</strong>nen Compilern haben allerd<strong>in</strong>gs <strong>de</strong>n Verdacht geschürt,dass manche Compiler von sich aus die schnellere Variante (Po<strong>in</strong>ter) wählen. Übergeben Siegroße Strukturen als Po<strong>in</strong>ter, nicht als Variable. Dadurch spart man das Kopieren <strong>de</strong>r Daten.Input/Output ist immer zeitaufwendig. In vielen Programmen geht 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 manchmal auch zugleich an Speicherplatzerzielt man durch e<strong>in</strong>e zweckmäßige Datenstruktur 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>es Profilers anzusehen, wodie Zeit verbraten wird, und vielleicht auch e<strong>in</strong>ige kritische Programmteile <strong>in</strong> Assemblerschreiben.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 die curses(3)-Bibliothek ist früherwegen ihrer vielen Fehler oft verwü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>nen mit e<strong>in</strong>em e<strong>in</strong>fachen


142 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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>nBildschirm zu löschen, wobei <strong>de</strong>r Term<strong>in</strong>altyp aus <strong>de</strong>r Umgebungsvariablen TERM und diezugehö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 nichtverschrottet):/* 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 */#<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 von DateienDas Kommando /usr/local/b<strong>in</strong>/xclear ist e<strong>in</strong>e recht praktische Erweiterung von/b<strong>in</strong>/clear. Die Funktion setupterm() ermittelt vor allem <strong>de</strong>n Term<strong>in</strong>altyp. putp()schickt die Steuersequenz zum Term<strong>in</strong>al, und reset_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>fachenFällen wie <strong>de</strong>m obigen arbeiten, <strong>in</strong> <strong>de</strong>r Regel s<strong>in</strong>d die <strong>in</strong>telligenteren curses(3)-Funktionen vorzuziehen.


1.11. WEITERE C-PROGRAMME 143Im folgen<strong>de</strong>n Beispiel verwen<strong>de</strong>n wir curses(3)-Funktionen zur Bildschirmsteuerungzum Erzeugen e<strong>in</strong>es Hilfe-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);for (c = 0; c


144 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>ren. Das Gegenstück dazu ist endw<strong>in</strong>(), die das Term<strong>in</strong>al wie<strong>de</strong>r <strong>in</strong> se<strong>in</strong>en ursprünglichenZustand versetzt.• noecho() schaltet das Echo <strong>de</strong>r Tastature<strong>in</strong>gaben auf <strong>de</strong>m Bildschirm aus.• cbreak() bewirkt, daß je<strong>de</strong>s e<strong>in</strong>gegebene Zeichen sofort an das Programm weitergeleitetwird – ohne RETURN.• mvpr<strong>in</strong>tw() bewegt (move) <strong>de</strong>n Cursor an die durch die ersten bei<strong>de</strong>n Argumente bezeichnetePosition (0, 0 l<strong>in</strong>ks oben) und schreibt dann <strong>in</strong> das Standardfenster (sofernnicht an<strong>de</strong>rs angegeben). Syntax wie die C-Standardfunktion pr<strong>in</strong>tf(3).• refresh() Die bisher aufgerufenen Funktionen haben nur <strong>in</strong> e<strong>in</strong>en Puffer geschrieben,auf <strong>de</strong>m tatsächlichen Bildschirm hat sich noch nichts gerührt. Erst mit refresh()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 von refresh()• neww<strong>in</strong>() erzeugt e<strong>in</strong> neues Fenster – hier mit <strong>de</strong>m Namen frame – auf <strong>de</strong>r angegebenenPosition mit e<strong>in</strong>er bestimmten Anzahl von Zeilen und Spalten.• wstandout() setzt das Attribut <strong>de</strong>s Fensters auf standout, d. h. auf umgekehrte Helligkeitenbeispielsweise. 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> Fenster vö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, man braucht sich beim Programmieren um<strong>de</strong>n Term<strong>in</strong>altyp nicht zu 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>eReihe von Vokabeln bunt durche<strong>in</strong>an<strong>de</strong>r abgefragt wer<strong>de</strong>n soll. S<strong>in</strong>d die Anfor<strong>de</strong>rungen nichtso hoch 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 Zufallabsolvieren muß, reichen e<strong>in</strong>ige Funktionen aus <strong>de</strong>r C-Standard-Bibliothek. Das folgen<strong>de</strong>Programm erzeugt e<strong>in</strong>e Folge mehr o<strong>de</strong>r weniger zufälliger natürlicher Zahlen und gibt sieauf 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#<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++) {


1.11. WEITERE C-PROGRAMME 145r = 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 Zufallszahlen im Bereich von 1 bis MODWir <strong>de</strong>f<strong>in</strong>ieren die Anzahl MAX von Zufallszahlen, die wir brauchen, sowie <strong>de</strong>n ModulusMOD, <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ürdie Funktion pr<strong>in</strong>tf(), time.h für <strong>de</strong>n Systemaufruf time() und stdlib.h für die Funktionensrandom() und random() e<strong>in</strong>. Die Variable i ist e<strong>in</strong> Schleifenzähler, r die jeweiligeZufallszahl und s <strong>de</strong>r sogenannte Seed (Samen), auch Salz genannt, <strong>de</strong>n wir brauchen, 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>r Sekun<strong>de</strong>n seit <strong>de</strong>m 1. Januar1970, 0 Uhr GMT. Damit ist sichergestellt, daß wir bei je<strong>de</strong>m Aufruf e<strong>in</strong>en an<strong>de</strong>renWert haben. Die Syntax von time() holt man sich mittels man 2 time. Das Argument vontime() 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 Generator rand() beziehungsweiserandom. Bei<strong>de</strong> Funktionspaare verwen<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 Zahlenbereichzu begrenzen. Da wir Zahlen von 1 bis MOD, die Grenzen e<strong>in</strong>geschlossen, habenwollen, addieren wir e<strong>in</strong>e 1 h<strong>in</strong>zu. Das Ergebnis dieser Rechnung wird wie üblich mittels <strong>de</strong>rFunktion 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 Funktionzufallszahl() durchgeführt wird und das 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){


146 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>static <strong>in</strong>t r = 0;unsigned s;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 Zufallszahlen im Bereich von 1 bis MOD,mit FunktionUm die Funktion zufallszahl() allgeme<strong>in</strong> verwendbar zu gestalten, übergeben wir <strong>de</strong>nModulus bei je<strong>de</strong>m Aufruf als Argument. Da <strong>de</strong>r Generator nur beim ersten Aufruf gestartetwer<strong>de</strong>n soll, <strong>de</strong>klarieren wir die Variable r als static, <strong>in</strong>itialisieren sie mit null undmißbrauchen sie als Flag für <strong>de</strong>n Generatorstart mittels srand(). Die Initialisierung wirdnur e<strong>in</strong>mal, beim Programmaufruf, ausgeführt. Danach hat r immer <strong>de</strong>n jeweils jüngstenZufallswert, <strong>de</strong>r m<strong>in</strong>imal 1 ist und negiert stets false liefert.Im wirklichen Leben verlangte die Aufgabe e<strong>in</strong>e C-Funktion für e<strong>in</strong> PASCAL-Programm.Hierzu müssen Funktion und Hauptprogramm <strong>in</strong> getrennten Dateien vorliegen, da es ke<strong>in</strong>ezweisprachigen Compiler gibt. Also wur<strong>de</strong>n die C-Funktion isoliert und e<strong>in</strong> Rahmenprogrammzum 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) {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 Bereich von 1 bis MODDie C-Funktion gibt pro Aufruf e<strong>in</strong>e Zufallszahl im Bereich von 1 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);


1.11. WEITERE C-PROGRAMME 147var 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 Zufallszahlen im Bereich von 1 bisMOD, mit C-FunktionDie Compileraufrufe lauten:cc -c zufallszahl.cpc -o prandom prandom.p zufallszahl.oDie gemischte Programmierung funktioniert hier reibungslos, weil bei<strong>de</strong> Sprachen <strong>de</strong>n TypGanzzahl kennen und die C-Funktion e<strong>in</strong>fach ist.Wie wir anfangs auf Seite ?? bemerkt haben, ist es pr<strong>in</strong>zipiell unmöglich, mit e<strong>in</strong>er <strong>de</strong>term<strong>in</strong>istischenMasch<strong>in</strong>e Zufallsergebnisse zu erzeugen. Die vorstehen<strong>de</strong>n Programme lieferndaher auch nur Pseudo-Zufallszahlen (pseudo random number), die h<strong>in</strong>sichtlich bestimmterEigenschaften 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>er sicherlich. E<strong>in</strong>e ausführliche Diskussion f<strong>in</strong><strong>de</strong>t sich bei DONALD 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 eleganten und schnellen Programmen führen. Wir wollenuns an Hand 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 von e<strong>in</strong>em Byte. Je<strong>de</strong>s Byte hate<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 mit e<strong>in</strong>em Namen und bestimmtenEigenschaften, 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, belegt Speicherplatz und damite<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ßt die 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 die Variable durch Dereferenzierung*px. Es ist nicht immer gleichgültig, ob man <strong>de</strong>n Po<strong>in</strong>ter o<strong>de</strong>r die Variable<strong>de</strong>klariert und das Gegenstück durch Referenzieren bzw. Dereferenzieren handhabt.• 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.• 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.


148 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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>em Po<strong>in</strong>ter zugewiesen wer<strong>de</strong>nkann. Auf dieser Adresse liegt ke<strong>in</strong> gültiges Datenobjekt, sie tritt nur <strong>in</strong> Verb<strong>in</strong>dung mitFehlern o<strong>de</strong>r Ausnahmen auf. Um die Beson<strong>de</strong>rheit dieser Adresse hervorzuheben, schreibtman sie meist nicht als Ziffer, son<strong>de</strong>rn als Wort NULL. In <strong>de</strong>r Inclu<strong>de</strong>-Datei stdio.h ist dasWort als symbolische 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 162 kommen beim Öffnen e<strong>in</strong>er Dateizum 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[1]);exit(1);}Die Funktion fopen(), die die Datei öffnet, gibt bei Mißerfolg – aus welchen Grün<strong>de</strong>n auchimmer – 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,also bei Mißerfolg, wird e<strong>in</strong>e Fehlermeldung ausgegeben und das Programm mit <strong>de</strong>mSystemaufruf exit() verlassen. Bei Erfolg enthä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 Variable von e<strong>in</strong>em zunächst noch unbekanntenTyp zeigt. Wenn es dann zur Sache geht, legt man <strong>de</strong>n Typ mittels <strong>de</strong>s cast-Operators fest.Früher nahm man dafür Po<strong>in</strong>ter auf <strong>de</strong>n Typ char, <strong>de</strong>nn dieser Typ belegt genau e<strong>in</strong>Byte, woraus man je<strong>de</strong>n an<strong>de</strong>ren Typ aufbauen kann. Nach ANSI ist hierfür <strong>de</strong>r Typ voidzu 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 aufvoid verwan<strong>de</strong>lt wer<strong>de</strong>n, und umgekehrt. Die Po<strong>in</strong>ter belegen ja selbst – unabhängig vomTyp, auf <strong>de</strong>n sie zeigen – 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>gabeals langen Str<strong>in</strong>g übernimmt und dann die E<strong>in</strong>gabe – erfor<strong>de</strong>rlichenfalls nach Prüfung – <strong>in</strong>e<strong>in</strong>en gewünschten Typ umwan<strong>de</strong>lt. Die Funktion ist e<strong>in</strong> Ersatz für scanf(3) mit <strong>de</strong>r Möglichkeit,fehlerhafte E<strong>in</strong>gaben nach Belieben zu behan<strong>de</strong>ln. Als erstes e<strong>in</strong> Programmrahmen,<strong>de</strong>r die Funktion 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;}


1.11. WEITERE C-PROGRAMME 149/* 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);}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 */*((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;


150 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}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>en Po<strong>in</strong>ter (aus <strong>de</strong>mselben Grundwie scanf(3), call by reference) auf die e<strong>in</strong>zulesen<strong>de</strong> Variable, als zweites Argument <strong>de</strong>ngewünschten Typ <strong>in</strong> Form e<strong>in</strong>es Str<strong>in</strong>gs. Auf e<strong>in</strong>e wechseln<strong>de</strong> Anzahl von Argumenten verzichtenwir 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 Funktion schreiben wollen, mußxread() e<strong>in</strong>en Po<strong>in</strong>ter auf e<strong>in</strong>en beliebigen Typ, 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 angefangen bis zu e<strong>in</strong>er oberenGrenze, die beim Aufruf e<strong>in</strong>gegeben wer<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 reichlich Po<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 Gewohnheitenentgegenkommt. Bei <strong>de</strong>r Optimierung wur<strong>de</strong>n alle Indizes durch Po<strong>in</strong>ter ersetzt, wieim Abschnitt 1.11.4 Optimierung auf Seite 140 erlä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 */


1.11. WEITERE C-PROGRAMME 151{<strong>in</strong>t r;<strong>in</strong>t i = 1, j, k;unsigned long en<strong>de</strong> = DEF;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,gegebenenfalls loeschen*/if (*(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;


152 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}}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


1.11. WEITERE C-PROGRAMME 153return 0;}/* En<strong>de</strong> Hauptprogramm *//* Funktion zum Testen <strong>de</strong>r Teilbarkeit *//* Parameteruebergabe zwecks Zeitersparnis vermie<strong>de</strong>n */void ttest(){register <strong>in</strong>t i;for (i = 1; *(p + i) * *(p + i)


154 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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++)<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);}


1.11. WEITERE C-PROGRAMME 155else {}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]])();/* 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


156 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>/*************//* 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 Funktionen auf. Das Unterverzeichnis enthälte<strong>in</strong>e eigene Inclu<strong>de</strong>-Datei und e<strong>in</strong> eigenes Makefile. In gleicher Weise s<strong>in</strong>d die übrigenFunktionen organisiert.Das Makefile <strong>de</strong>s Hauptprogramms ruft Makefiles <strong>in</strong> <strong>de</strong>n Unterverzeichnissen auf. Wirhaben 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 = feuerK = 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)


1.11. WEITERE C-PROGRAMME 157$(MAKE) allcd ..feuer o :cd $(F)$(MAKE) allcd ..kontur o :cd $(K)$(MAKE) allcd ..schall o :cd $(S)$(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) nur noch 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 Programmnicht auf an<strong>de</strong>re Systeme übertragbar. Man müßte eigene Grafikfunktionen verwen<strong>de</strong>n,die Verpackungen um die Grafikfunktionen <strong>de</strong>s jeweiligen Compilers darstellen. Dasselbegilt für die Funktion zum Tuten, e<strong>in</strong>e Assemblerrout<strong>in</strong>e. Vielleicht stellen wir das Programme<strong>in</strong>mal auf 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 ofchar, die mit <strong>de</strong>m ASCII-Zeichen Nr. 0 abgeschlossen s<strong>in</strong>d. In <strong>de</strong>r Standard-C-Bibliothekf<strong>in</strong><strong>de</strong>n sich fertige Funktionen für die häufigsten Aufgaben <strong>de</strong>r Str<strong>in</strong>gverarbeitung. Trotz<strong>de</strong>mhat 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 Überlauf mit nicht immer vorhersehbaren Folgen, manchmalauch zu von bösen Buben beabsichtigten Folgen. Man me<strong>in</strong>t, <strong>de</strong>r Puffer sei 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>gauf, <strong>de</strong>r <strong>de</strong>n Puffer sprengt. Das Gegenmittel besteht im Beschränken <strong>de</strong>s Schreibens aufmaximal e<strong>in</strong> Zeichen weniger als <strong>de</strong>r Puffer fasst. Wo E<strong>in</strong>gaben verlangt wer<strong>de</strong>n, ist immerdamit 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 Ausnahmen voraus.gets() – fgets()


158 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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 Struktur bereits zur Übersetzungszeitbekannt se<strong>in</strong>, d. h. im Programm stehen 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öglichen Größe anlegen müßte.Die Standardfunktion malloc(3) samt Verwandtschaft hilft aus <strong>de</strong>r Klemme. Im folgen<strong>de</strong>nBeispiel wird e<strong>in</strong> Array zunächst nur als Po<strong>in</strong>ter la <strong>de</strong>klariert, dann mittels calloc(3)Speicher zugewiesen, mittels realloc(3) vergrößert und schließlich von free(3) wie<strong>de</strong>rfreigegeben:/* 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));if (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;}


1.11. WEITERE C-PROGRAMME 159Quelle 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>n Regeln <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 etwasabweichen./* "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 *//* 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,/* 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,


160 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>};/* 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[];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;


1.11. WEITERE C-PROGRAMME 161}}*mp = a;if (*mp == ’\n’) {flag = 0;ap[++i] = ++mp;}elsemp++;fclose(fp);/* Zeilenpo<strong>in</strong>ter sortieren */if (sort(i - 1) != 0) {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)


162 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}/* 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>n Regeln <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> Flag o<strong>de</strong>r e<strong>in</strong>e Schaltvariable,d. h. e<strong>in</strong>e Variable, die <strong>in</strong> Abhängigkeit von bestimmten Bed<strong>in</strong>gungen e<strong>in</strong>en Wert 0 o<strong>de</strong>rnicht-0 annimmt und 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>wandfreierProgrammiertrick.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> Programmschreibt, das unter <strong>de</strong>m X W<strong>in</strong>dow System 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"


1.11. WEITERE C-PROGRAMME 163char 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 context */XEvent 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 */<strong>in</strong>tmyscreen, i, num=2, <strong>de</strong>l=1, w<strong>in</strong>=1;chartext[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);mygc12 = XCreateGC(mydisplay, myw<strong>in</strong>2, 0, 0);


164 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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 = 0;/* 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 */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 */


1.11. WEITERE C-PROGRAMME 165case 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));XDrawImageStr<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, newgc,140, 100, WIN3, strlen(WIN3));XSetFont(mydisplay, newgc, \XLoadFont(mydisplay, "fgb-13"));XDrawImageStr<strong>in</strong>g(mydisplay, mypixmap, newgc, 25,180, DELSUB, strlen(DELSUB));XSetFont(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>, newgc, \0, 0, 400, 200, 0, 0);}elseXDestroySubw<strong>in</strong>dows(mydisplay, myw<strong>in</strong>1);


166 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>}break;w<strong>in</strong> = !w<strong>in</strong>;/* repa<strong>in</strong>t w<strong>in</strong>dow on expose event */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: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öglichkeitverwen<strong>de</strong>t man höhere Bibliotheken, die ihrerseits auf <strong>de</strong>r Xlib aufsetzen. Man erspart sichdamit viel Mühe.


1.11. WEITERE C-PROGRAMME 1671.11.11 cgi-ProgrammeDie Abkürzung cgi be<strong>de</strong>utet Common Gateway Interface. Das ist e<strong>in</strong> Protokoll zum Gedankenaustauschzwischen HTML-Forms und Programmen. Die Programme können <strong>in</strong> je<strong>de</strong>rSprache verfasst se<strong>in</strong>, die es ermöglicht, von std<strong>in</strong> zu lesen, nach stdout zu schreibenund 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 das nicht zw<strong>in</strong>gend,e<strong>in</strong> C-Programm tut es genau so gut und ist schneller.TestGET-FormularPOST-FormularQuelle 1.96 : Webseite cgi_test.html mit FORM-Elementen zum 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 hier nichts zur Sache und kann <strong>in</strong> HTML-Anleitungennachgelesen wer<strong>de</strong>n. Unter <strong>de</strong>n Attributen <strong>de</strong>s FORM-Elements f<strong>in</strong><strong>de</strong>n sich action undmethod. Die action gibt <strong>de</strong>n vollständigen o<strong>de</strong>r relativen URL <strong>de</strong>s Programms an, das auf<strong>de</strong>m Webserver 36 ausgeführt wer<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 post o<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-Elementenäher spezifiert s<strong>in</strong>d, und drückt dann e<strong>in</strong> Knöpfchen, das submit o<strong>de</strong>r ähnlich heißt. Daraufh<strong>in</strong> verlangt <strong>de</strong>r Brauser vom WWW <strong>de</strong>n unter action genannten URL unter Beifügung <strong>de</strong>re<strong>in</strong>gegebenen Werte. Der Webserver stellt fest, dass e<strong>in</strong>es se<strong>in</strong>er cgi-Skripte verlangt wird,und ruft dieses auf./** cgi.h* Teil e<strong>in</strong>er Implementation <strong>de</strong>r CGI-Schnittstelle <strong>in</strong> C.*/36 Etwas völlig an<strong>de</strong>res s<strong>in</strong>d aktive Inhalte (Anweisungen <strong>in</strong> Javascript, Java-Applets) vonWebseiten, die auf <strong>de</strong>m Computer <strong>de</strong>s Benutzers ausgeführt wer<strong>de</strong>n.


168 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>#<strong>de</strong>f<strong>in</strong>e MAX QUERY LEN 4095 /* gegen Missbrauch */struct list item {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");while (param list != NULL) {pr<strong>in</strong>tf("%s = %s\n", param list->key, param list->value);param 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->value);param array++;}}return 0;


1.11. WEITERE C-PROGRAMME 169Quelle 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]) - ’a’ + 10) « 4 |(isdigit(s[2]) ? s[2] - ’0’ : tolower(s[2]) - ’a’ + 10);memmove(s + 1, s + 3, i -= 2);}}/** Gibt <strong>de</strong>n query str<strong>in</strong>g zurueck, wenn ke<strong>in</strong>e Fehler auftreten,* ansonsten NULL. Unterschei<strong>de</strong>t dabei zwischen GET und POST.* 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 METHOD *//* 1. Fall: GET */if (strcmp(p, "GET") == 0) {p = getenv("QUERY STRING");if (p == NULL) return NULL; /* ke<strong>in</strong> QUERY STRING bei GET */len = 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 strcpy */return 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 LENGTH */len = 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> < CONTENT LENGTH */


170 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>q[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;/** 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 != ’&’ || *(query + 1) == ’\0’));if (*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 s<strong>in</strong>d.* 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;struct array item *first, *last;/* Anzahl Parameter bestimmen */for (count = 0, temp = query; *temp != ’\0’; count++) {do {temp++;} while (*temp != ’\0’ && (*temp != ’&’ || *(temp + 1) == ’\0’));}if (count == 0) return NULL;/* Array allozieren */


1.12. OBFUSCATED C 171last = 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 != ’&’ || *(query + 1) == ’\0’));if (*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 vomBenutzer 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>r Umgebungs-Variablen QUERY_STRING, bei <strong>de</strong>r Metho<strong>de</strong> post wird <strong>de</strong>r Str<strong>in</strong>g vonstd<strong>in</strong> gelesen. Der Rest besteht im Aufdröseln (parsen) <strong>de</strong>s Str<strong>in</strong>gs, <strong>de</strong>r Verarbeitung <strong>de</strong>re<strong>in</strong>zelnen Werte und <strong>de</strong>r Ausgabe e<strong>in</strong>es HTML-konformen Dokumentes nach stdout. DiesesDokument schickt <strong>de</strong>r Webserver an <strong>de</strong>n anfragen<strong>de</strong>n Brauser zurück. Das wars. Fehlermacht man vor allem bei <strong>de</strong>n Kle<strong>in</strong>igkeiten wie Gänsefüßchen o<strong>de</strong>r Semikolons. E<strong>in</strong> großerTeil <strong>de</strong>s Programms besteht wie üblich im Abfangen unzulässiger E<strong>in</strong>gaben. Be<strong>de</strong>nken Sie,dass wildfrem<strong>de</strong> Benutzer dieses 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 sich auch Funktions- und Klassenbibliothekenfü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 9 bemerkt, f<strong>in</strong><strong>de</strong>t jährlich e<strong>in</strong> Wettbewerb um dasundurchsichtigste C-Programm statt (to obfuscate = vernebeln, verwirren). Die Siegerprogrammehaben außer Nebel auch noch e<strong>in</strong>en Witz aufzuweisen. Als Beispiel geben wir e<strong>in</strong>Programm von JACK APPLIN, Hewlett-Packard, Fort Coll<strong>in</strong>s/USA wie<strong>de</strong>r, das erfolgreich amContest 1986 teilgenommen hat. Es ist das Hello-World-Programm <strong>in</strong> e<strong>in</strong>er Fassung, die alsC-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-~-cat37 Unter www.ee.ryerson.ca:8080/˜elf/hack/multilang.htm liegt e<strong>in</strong> ähnlichesProgramm, das als C-Programm, Perl-Skript, Tcl-Skript und Shell-Skript gültig ist.


172 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>/*,’(*/,"Hello, world!",cat); putchar(~-~-~-cat); } /*,)’)end*/Auch 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 Default vom Typ <strong>in</strong>t – auf 13 gesetzt. Dannwird <strong>de</strong>r Systemaufruf write(1, "Hello, world!", 13) ausgeführt, <strong>de</strong>r 13 Zeichen <strong>de</strong>sStr<strong>in</strong>gs Hello, world! nach stdout (Datei<strong>de</strong>skriptor 1) schreibt, anschließend die Standardfunktionputchar(10). Der Gebrauch <strong>de</strong>s unären M<strong>in</strong>uszeichens samt <strong>de</strong>r bitweisenNegation ist ungewohnt. Man muß sich die Umrechnungen <strong>in</strong> Bits aufschreiben (negativeZahlen wer<strong>de</strong>n durch ihr Zweierkomplement dargestellt). Bei write():13 gibt 0000 0000 0000 0000 0000 0000 0000 1101-13 gibt 1111 1111 1111 1111 1111 1111 1111 0011~(-13) gibt 0000 0000 0000 0000 0000 0000 0000 110013 - (~(-13))gibt 0000 0000 0000 0000 0000 0000 0000 0001was <strong>de</strong>zimal 1 ist. Bei putchar() sieht die Geschichte so aus:13 gibt 0000 0000 0000 0000 0000 0000 0000 1101-13 gibt 1111 1111 1111 1111 1111 1111 1111 0011~(-13) gibt 0000 0000 0000 0000 0000 0000 0000 1100-(~(-13)) gibt 1111 1111 1111 1111 1111 1111 1111 0100~(-(~(-13)))gibt 0000 0000 0000 0000 0000 0000 0000 1011-(~(-(~(-13))))gibt 1111 1111 1111 1111 1111 1111 1111 0101~(-(~(-(~(-13)))))gibt 0000 0000 0000 0000 0000 0000 0000 1010was <strong>de</strong>zimal 10 = ASCII-Zeichen L<strong>in</strong>efeed ist.Für FORTRAN 77 bleiben folgen<strong>de</strong> Zeilen übrig:write(*, ’("Hello, world!")’)endZeilen, die an erster Stelle e<strong>in</strong> c o<strong>de</strong>r e<strong>in</strong> * enthalten, gelten als Kommentar. Zeilen, die ansechster Stelle irgen<strong>de</strong><strong>in</strong> Zeichen enthalten, wer<strong>de</strong>n als Fortsetzungen aufgefaßt. Anweisungenbeg<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 das Script verlassen. Mehr solcherScherze 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 die Qu<strong>in</strong>e-Programme dar. Das s<strong>in</strong>dProgramme, die ihren eigenen Quellco<strong>de</strong> ausgeben. Näheres unter:http://www.nyx.net/~gthompso/qu<strong>in</strong>e.htm


1.13. PORTIEREN VON PROGRAMMEN 1731.13 Portieren von Programmen1.13.1 RegelnUnter <strong>de</strong>m Übertragen o<strong>de</strong>r Portieren von Programmen versteht man 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, schlimmstenfalls bei<strong>de</strong>s zugleich.E<strong>in</strong> Programm läßt sich immer portieren, <strong>in</strong><strong>de</strong>m man bis zur Aufgabenstellung zurückgeht.Das ist mit <strong>de</strong>m maximalen Aufwand verbun<strong>de</strong>n; es läuft auf Neuschreiben h<strong>in</strong>aus.Unter günstigen Umstän<strong>de</strong>n kann e<strong>in</strong> Programm Zeile für Zeile übertragen wer<strong>de</strong>n, ohnedie Aufgabe und die Algorithmen zu kennen. In diesem Fall reicht die Intelligenz e<strong>in</strong>es Computerszum Portieren; es gibt auch Programme für diese Tätigkeit 38 . Die wirklichen Aufgabenliegen zwischen diesen bei<strong>de</strong>n Grenzfällen.Schon beim ersten Schreiben e<strong>in</strong>es Programmes erleichtert man 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, Funktionsargumenteno<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 von Namen,• Annahmen über die automatische Initialisierung von Variablen,• <strong>de</strong>n Gebrauch von stillschweigen<strong>de</strong>n (automatischen) Typumwandlungen, zum Beispielvon 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 vorzeichenbehafteten Werten,• die Dereferenzierung von Nullpo<strong>in</strong>tern (Null ist ke<strong>in</strong>e Adresse),• Annahmen über die Darstellung von Po<strong>in</strong>tern (Po<strong>in</strong>ter s<strong>in</strong>d ke<strong>in</strong>e Ganzzahlen), Zuweisungenvon 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>r nicht richtig auf e<strong>in</strong>e Datengrenzeausgerichtet ist (Alignment),• die Annahme, daß Groß- und Kle<strong>in</strong>buchstaben unterschie<strong>de</strong>n wer<strong>de</strong>n,• die Annahme, daß <strong>de</strong>r Typ char vorzeichenbehaftet o<strong>de</strong>r vorzeichenlos ist (EOF = -1?),• Bitoperationen mit vorzeichenbehafteten Ganzzahlen,• die Verwendung von Bitfel<strong>de</strong>rn mit an<strong>de</strong>ren Typen als unsigned,• Annahmen über das Vorzeichen <strong>de</strong>s Divisionsrestes bei <strong>de</strong>r ganzzahligen Division,• die Annahme, daß e<strong>in</strong>e extern-Deklaration <strong>in</strong> e<strong>in</strong>em Block auch außerhalb <strong>de</strong>s Blockesgilt.Diese und noch e<strong>in</strong>ige D<strong>in</strong>ge wer<strong>de</strong>n von unterschiedlichen Betriebssystemen und Compilernunterschiedlich gehandhabt, und man 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, um Abhä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ätselhaften Werten im Programm verwen<strong>de</strong>n,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 FORTRANnach C und e<strong>in</strong> Programm p2c zum Portieren von PASCAL nach C.


174 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>• 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öße von Typen o<strong>de</strong>r Variablenbraucht,• daran <strong>de</strong>nken, daß die Größe von Datentypen je nach Architektur unterschiedlich 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>re Funktionen die Herkunfto<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 Platzhalter verwen<strong>de</strong>n (%ld für long),• alle unvermeidlichen Systemabhängigkeiten auf wenige Stellen konzentrieren und<strong>de</strong>utlich kommentieren.Im folgen<strong>de</strong>n wollen wir e<strong>in</strong>ige Beispiele betrachten, die nicht allzu lang und daher auch nure<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 WAGNER aus <strong>de</strong>m Buch von KARL NI-CKEL ALGOL-Praktikum (1964) ausgewählt, weil es mit Sicherheit nicht im H<strong>in</strong>blick aufe<strong>in</strong>e Übertragung nach C geschrieben wor<strong>de</strong>n ist. Es geht um die Bestimmung <strong>de</strong>s größtengeme<strong>in</strong>samen Teilers mit <strong>de</strong>m Algorithmus von EUKLID. Daß wir die Aufgabe und <strong>de</strong>n Algorithmuskennen, erleichtert die Arbeit, daß außer e<strong>in</strong>igen Graubärten niemand mehr ALGOLkennt, 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 Druckzeit39 s. Damals hatten schnelle Kopfrechner noch e<strong>in</strong>e Chance. E<strong>in</strong>e Analyse <strong>de</strong>s Quelltextesergibt:• Das Programm besteht aus e<strong>in</strong>er Datei mit <strong>de</strong>m Hauptprogramm (war kaum an<strong>de</strong>rsmö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 und goto verwen<strong>de</strong>t.Das sieht hoffnungsvoll aus. Die Übertragung nach C:


1.13. PORTIEREN VON PROGRAMMEN 175/* 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> <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>n durch while-Schleifen ersetzt und <strong>de</strong>r ALGOL-Behelfzur Berechnung <strong>de</strong>s Divisionsrestes (entier) durch die <strong>in</strong> C vorhan<strong>de</strong>ne Modulo-Operation.Bei e<strong>in</strong>em Vergleich mit <strong>de</strong>m Programm 1.55 C-Programm ggt nach Euklid, rekursiv aufSeite 96 sieht man, wie unterschiedlich selbst e<strong>in</strong> so e<strong>in</strong>facher Algorithmus programmiertwer<strong>de</strong>n kann. Dazu kommen an<strong>de</strong>re Algorithmen zur Lösung <strong>de</strong>rselben Aufgabe, beispielsweisedas Ermitteln aller Teiler <strong>de</strong>r bei<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 quadratischer Gleichungen <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 eps


176 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>complex 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 --------------------------------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 Gleichung mit 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,


1.13. PORTIEREN VON PROGRAMMEN 177• es wird Gleitkomma-Arithmetik verwen<strong>de</strong>t, aber ke<strong>in</strong>e Komplex-Arithmetik (was dieÜbertragung nach C erleichtert),• an Funktionen treten abs(), sqrt() und cmplx() auf,• an Kontrollanweisungen wer<strong>de</strong>n if - 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 gotogibt es zwar <strong>in</strong> C, aber wir bleiben standhaft und vermei<strong>de</strong>n sie. Alles übrige sieht e<strong>in</strong>fachaus.Als Ersatz für <strong>de</strong>n komplexen Datentyp bietet sich e<strong>in</strong> Array of 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 dieOperationen selbst schaffen. Hier wer<strong>de</strong>n aber nur die komplexen Zahlen ausgegeben, washarmlos 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);done();}}else {/* 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);


178 KAPITEL 1. PROGRAMMIEREN IN C/<strong>C++</strong>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 reellen Koeffizienten und komplexenLösungen, aus FORTRAN übertragenBei <strong>de</strong>r Übertragung haben wir ke<strong>in</strong>en Gebrauch von unseren Kenntnissen über quadratischeGleichungen gemacht, son<strong>de</strong>rn ziemlich schematisch gearbeitet. MathematischeKenntnisse s<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 komplexe Koeffizienten zulassen:Schließlich wollen wir das Programm als Funktion (Subrout<strong>in</strong>e) schreiben, die von e<strong>in</strong>emübergeordneten Programm aufgerufen wird:1.14 Exkurs über AlgorithmenDer Begriff Algorithmus – benannt nach e<strong>in</strong>em usbekischen Mathematiker <strong>de</strong>s 9. Jahrhun<strong>de</strong>rts– kommt im vorliegen<strong>de</strong>n Text 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> Algorithmuse<strong>in</strong>e Vorschrift, die mit endlich 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>e Programmiersprache.Algorithmen wer<strong>de</strong>n mit Worten, Formeln o<strong>de</strong>r Grafiken dargestellt. E<strong>in</strong> Existenzbeweisist <strong>in</strong> <strong>de</strong>r Mathematik schon e<strong>in</strong> Erfolg, <strong>in</strong> <strong>de</strong>r Technik brauchen wir e<strong>in</strong>en Lösungsweg, e<strong>in</strong>enAlgorithmus.Das kl<strong>in</strong>gt alltäglich. Das Rezept zum Backen e<strong>in</strong>er Pr<strong>in</strong>zregententorte 39 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>ige Anfor<strong>de</strong>rungen an Algorithmen s<strong>in</strong>d:• Korrektheit. Das kl<strong>in</strong>gt selbstverständlich, ist aber meist schwierig zu beweisen. UndKorrektheit <strong>in</strong> e<strong>in</strong>em E<strong>in</strong>zelfall besagt gar nichts. Umgekehrt beweist bereits e<strong>in</strong> Fehlerdie Inkorrektheit.• E<strong>in</strong><strong>de</strong>utigkeit. Das stellt Anfor<strong>de</strong>rungen an die Darstellungsweise, die Sprache; <strong>de</strong>nkenSie an e<strong>in</strong>e technische 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ß das gleiche Ergebnis herauskommen.39 Dr. Oetker Backen macht Freu<strong>de</strong>, Ceres-Verlag, Bielefeld. Die Ausführung dieses Algorithmusläßt sich teilweise parallelisieren.40 H. KLIER, Alpenvere<strong>in</strong>sführer Ötztaler Alpen, Bergverlag Rudolf Rother, München. DerAlgorithmus muß sequentiell abgeschwitzt wer<strong>de</strong>n.


1.14. EXKURS ÜBER ALGORITHMEN 179• Endlichkeit. Die Beschreibung <strong>de</strong>s Algorithmus muß e<strong>in</strong>e endliche Länge haben, sonstkönnte man ihn endlichen Wesen 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 zu Lebzeiten ernten. Er darf zurAusführung nur e<strong>in</strong>e endliche Menge von Betriebsmitteln belegen.• Allgeme<strong>in</strong>heit. 3 × 4 = 12 ist ke<strong>in</strong> Algorithmus, wohl aber die Vorschrift, wie man dieMultiplikation auf die Addition zurückführt.Man kann die Anfor<strong>de</strong>rungen herabschrauben und kommt dabei zu 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>rungist die nach e<strong>in</strong>em guten, zweckmäßigen Algorithmus o<strong>de</strong>r gar die nach <strong>de</strong>m besten.Denken Sie an die vielen Sortierverfahren (ke<strong>in</strong>es ist das beste für alle Fälle).Es gibt – sogar ziemlich leicht verständliche – Aufgaben, die nicht mittels e<strong>in</strong>es Algorithmuszu lösen s<strong>in</strong>d. Falls Sie Bedarf an solchen Nüssen haben, suchen Sie unter <strong>de</strong>m StichwortEntscheidbarkeit <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- und das Hexa<strong>de</strong>zimalsystemgebräuchlich. Ferner spielt das B<strong>in</strong>är codierte 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 sich dual dargestellt.Die folgen<strong>de</strong> Tabelle enthält die Werte von 0 bis <strong>de</strong>zimal 255. Bequemlichkeitshalbers<strong>in</strong>d auch die zugeordneten ASCII-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 syn23 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 ’180


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 63 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 ‘181


182 ANHANG A. ZAHLENSYSTEME97 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 f103 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.10143 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.11


154 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.10183 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.0183


184 ANHANG A. ZAHLENSYSTEME211 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.10223 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.101


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> Zahlen und 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 Grafik27 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 + + +185


186 ANHANG B. ZEICHENSÄTZE44 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 B67 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 c


B.1. EBCDIC, ASCII, ROMAN8, IBM-PC 187100 144 À d d d101 145 Á e e e102 146 à f f f103 147 Å g g g104 150 Ç h h h105 151 Ñ i i i106 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 É145 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 ā Ü


188 ANHANG B. ZEICHENSÄTZE155 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 ñ Grafik184 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 Ø Grafik


B.2. GERMAN-ASCII 189211 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 ú ß Grafik223 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-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 amerikanischen Zeichen 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 \ Ö


190 ANHANG B. ZEICHENSÄTZE93 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-Packard verwen<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 Nummernhöher 127 enthalten, siehe vorhergehen<strong>de</strong> Tabelle.B.3 ASCII-SteuerzeichenDie Steuerzeichen <strong>de</strong>r Zeichensätze dienen <strong>de</strong>r Übermittlung von Befehlen und Informationenan das empfangen<strong>de</strong> Gerät und nicht <strong>de</strong>r Ausgabe e<strong>in</strong>es sicht- o<strong>de</strong>r druckbaren Zeichens.Die Ausgabegeräte kennen <strong>in</strong> <strong>de</strong>r Regel jedoch e<strong>in</strong>en Modus (transparent, Monitor, DisplayFunctions), <strong>in</strong> <strong>de</strong>r die Steuerzeichen nicht ausgeführt, son<strong>de</strong>rn angezeigt wer<strong>de</strong>n. Die meistenSteuerzeichen belegen ke<strong>in</strong>e eigene Taste auf <strong>de</strong>r Tastatur, son<strong>de</strong>rn wer<strong>de</strong>n als Komb<strong>in</strong>ationaus <strong>de</strong>r control-Taste und e<strong>in</strong>er Zeichentaste e<strong>in</strong>gegeben. In C/<strong>C++</strong> läßt sich je<strong>de</strong>sZeichen durch se<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>zimale Nummer<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 b3 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, RUBOUT


B.4. LATIN-1 (ISO 8859-1) 191B.4 Lat<strong>in</strong>-1 (ISO 8859-1)Die <strong>in</strong>ternationale Norm ISO 8859 beschreibt gegenwärtig zehn Zeichensätze, die je<strong>de</strong>s Zeichendurch jeweils e<strong>in</strong> Byte darstellen. 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äischeSprachen – darunter Deutsch – vorgesehen. Lat<strong>in</strong>-2 <strong>de</strong>ckt Mittel- und Osteuropa ab, soweitdas late<strong>in</strong>ische Alphabet verwen<strong>de</strong>t wird. Wer e<strong>in</strong>en polnisch-<strong>de</strong>utschen Text schreibenwill, 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>nselben Stellen.Weiteres siehe <strong>in</strong> <strong>de</strong>r ISO-Norm und im RFC 1345 Character Mnemonics and CharacterSets vom Juni 1992. Auch http://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 mit US-ASCII übere<strong>in</strong>, diezweite 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 standardisierteverbale Bezeichnung. E<strong>in</strong>ige Zeichen wie das isländische Thorn o<strong>de</strong>r das Cent-Zeichen konntenhier 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)025 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 & Ampersand


192 ANHANG B. ZEICHENSÄTZE039 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 at065 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>e


B.4. LATIN-1 (ISO 8859-1) 193096 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 h105 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)145 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)


194 ANHANG B. ZEICHENSÄTZE153 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 ¸ Cedilla185 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 diaresis


B.4. LATIN-1 (ISO 8859-1) 195208 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)223 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 eigene o<strong>de</strong>r frem<strong>de</strong> Funktionen angesehen.Ihrem Ursprung nach s<strong>in</strong>d es auch C-Funktionen. Sie s<strong>in</strong>d jedoch nicht Bestandteile<strong>in</strong>er Funktionsbibliothek, son<strong>de</strong>rn gehören zum Betriebssystem und s<strong>in</strong>d nicht durch an<strong>de</strong>reFunktionen erweiterbar.Die Systemaufrufe – als Bestandteil <strong>de</strong>s Betriebssystems – s<strong>in</strong>d für alle Programmiersprachendieselben, während die Funktionsbibliotheken zur jeweiligen Programmiersprachegehören. Folgen<strong>de</strong> Systemaufrufe s<strong>in</strong>d unter UNIX verfügbar:accessacctalarmatexitbrkchdirchmodchownchrootclosecreatduperrnoexecexitfcntlforkfsctlfsyncgetaccessgetaclgetcontextgetdirentriesgetgroupsgethostnamegetitimergetpidgettimeofdaygetuidioctlkilll<strong>in</strong>klockflseekmkdirmknodmountmsgctlniceopenpausepipepreallocprüft Zugriff auf Filestartet und stoppt Prozess Account<strong>in</strong>gsetzt Weckeruhr für ProzessFunktion für Programmen<strong>de</strong>än<strong>de</strong>rt Speicherzuweisungwechselt Arbeitsverzeichnisän<strong>de</strong>rt Zugriffsrechte e<strong>in</strong>es Filesän<strong>de</strong>rt Besitzer e<strong>in</strong>es Filesän<strong>de</strong>rt Root-Verzeichnisschließt e<strong>in</strong>en File-Deskriptoröffnet File, ordnet Deskriptor zudupliziert File-DeskriptorFehlervariable <strong>de</strong>r Systemaufrufeführt e<strong>in</strong> Programm ausbeen<strong>de</strong>t e<strong>in</strong>en ProzessFilesteuerungerzeugt e<strong>in</strong>en neuen Prozessliest Information aus File-Systemschreibt File aus Arbeitsspeicher auf Platteermittelt Zugriffsrechteermittelt Zugriffsrechteermittelt Kontext e<strong>in</strong>es Prozessesermittelt Verzeichnis-E<strong>in</strong>trägeermittelt Gruppenrechte e<strong>in</strong>es Prozessesermittelt Namen <strong>de</strong>s Systemssetzt o<strong>de</strong>r liest Intervall-Uhrliest Prozess-IDermittelt Zeitliest User-ID <strong>de</strong>s aufrufen<strong>de</strong>n ProzessesI/O-Steuerungschickt Signal an e<strong>in</strong>en Prozessl<strong>in</strong>kt e<strong>in</strong> Filesetzt Semaphore und Record-Sperrenbewegt Schreiblesezeiger <strong>in</strong> e<strong>in</strong>em Fileerzeugt Verzeichniserzeugt Filehängt File-System <strong>in</strong> File-Hierarchie e<strong>in</strong>Interprozess-Kommunikationän<strong>de</strong>rt die Priorität e<strong>in</strong>es Prozessesöffnet File zum Lesen o<strong>de</strong>r Schreibensuspendiert Prozess bis zum Empfang e<strong>in</strong>es Signalserzeugt e<strong>in</strong>e Pipereserviert Arbeitsspeicher196


197profilreadreadl<strong>in</strong>krenamermdirrtpriosemctlsetgrpsetuidsignalstatstatfssyml<strong>in</strong>ksyncszsconftimetimestruncateumaskumountunl<strong>in</strong>kustatutimewaitwriteermittelt Zeiten bei <strong>de</strong>r Ausführung e<strong>in</strong>es Programmesliest aus e<strong>in</strong>em Fileliest symbolisches L<strong>in</strong>kän<strong>de</strong>rt Filenamenlöscht Verzeichnisän<strong>de</strong>rt Echtzeit-PrioritätSemaphoresetzt Gruppen-Zugriffsrechte e<strong>in</strong>es Prozessessetzt User-ID e<strong>in</strong>es Prozesseslegt fest, was auf e<strong>in</strong> Signal h<strong>in</strong> zu tun istliest die Ino<strong>de</strong> e<strong>in</strong>es Filesliest Werte <strong>de</strong>s File-Systemserzeugt symbolischen L<strong>in</strong>kschreibt Puffer auf Platteermittelt Systemwerteermittelt die Systemzeitermittelt Zeitverbrauch e<strong>in</strong>es Prozessesschnei<strong>de</strong>t File absetzt o<strong>de</strong>r ermittelt Filezugriffsmaskeentfernt Filesystem aus File-Hierarchielöscht Fileliest Werte <strong>de</strong>s File-Systemssetzt 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 jeweiligen Lieferanten <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 Systemaufrufen mit get... gibt es e<strong>in</strong>Gegenstück set..., das <strong>in</strong> e<strong>in</strong>igen Fä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>t wer<strong>de</strong>n. Laut ANSI verwen<strong>de</strong>tC 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)– 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>heit198


D.1. SCHLÜSSELWÖRTER 199– 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, DeklarationDarü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)


200 ANHANG D. C-LEXIKOND.2 OperatorenDie Operatoren von C/<strong>C++</strong> s<strong>in</strong>d im folgen<strong>de</strong>n ihrem Vorrang nach geordnet, höchster Rang(B<strong>in</strong>dungskraft) zuoberst. Alle Operatoren e<strong>in</strong>es Abschnitts haben gleichen Rang. l bzw. rbe<strong>de</strong>utet von l<strong>in</strong>ks bzw. rechts her assoziativ. E<strong>in</strong> unärer Operator verlangt 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ärer drei.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% 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


D.3. STANDARDFUNKTIONEN 201+=, -=, *=, /= r b<strong>in</strong>är zusammengesetzte%=, >>=,


202 ANHANG D. C-LEXIKON– 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– 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– 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


D.3. STANDARDFUNKTIONEN 203– 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• 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 meisten Compiler bieten darüberh<strong>in</strong>ause<strong>in</strong>e Vielzahl weiterer Funktionen, die das Programmieren erleichtern, aber die Portabilitätverschlechtern.


204 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 Standardfunktionen zum E<strong>in</strong>- und Ausgeben vonDaten. 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>r scanf(3). Länge, Bündigkeit, Unterdrückungführen<strong>de</strong>r Nullen, 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>itionen von Konstanten undTypen, Deklarationen von Funktionen und 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 Beschreibung je<strong>de</strong>r Funktion im Referenz-Handbuch ist angegeben, welche Inclu<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))• 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 Hardware abhängig. So f<strong>in</strong><strong>de</strong>t man die<strong>in</strong>clu<strong>de</strong>-Datei dos.h nicht auf UNIX-Anlagen, son<strong>de</strong>rn nur bei Compilern unter MS-DOS fürPCs.


D.6. PRÄPROZESSOR-ANWEISUNGEN 205D.6 Präprozessor-AnweisungenDer erste Schritt beim Compilieren ist die Bearbeitung <strong>de</strong>s Quelltextes durch <strong>de</strong>n Präprozessor.Dieser entfernt <strong>de</strong>n Kommentar und führt Ersetzungen und E<strong>in</strong>fügungen gemäß <strong>de</strong>rfolgen<strong>de</strong>n Anweisungen (directives) aus:• #<strong>de</strong>f<strong>in</strong>e buchstäbliche Ersetzung e<strong>in</strong>er symbolischen Konstanten o<strong>de</strong>r e<strong>in</strong>es Makros.Ist ke<strong>in</strong> Ersatz angegeben, wird nur <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.• #<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>nPrä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>iert bzw. nicht <strong>de</strong>f<strong>in</strong>iert ist, wer<strong>de</strong>ndie nachfolgen<strong>de</strong>n Präprozessor-Anweisungen ausgeführt.• #l<strong>in</strong>e führt bei Fehlermeldungen zu e<strong>in</strong>em Sprung auf die angegebenen Zeilennummer.• #pragma veranlaßt <strong>de</strong>n Präprozessor zu e<strong>in</strong>er systemabhängigen Handlung.


EKarlsruher TestNicht je<strong>de</strong>rmann eignet sich für so schwierige D<strong>in</strong>ge wie die elektronische Datenverarbeitung.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>en Test 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)e<strong>in</strong>armiger Bandit (1)nie<strong>de</strong>r<strong>de</strong>utsch für Kam<strong>in</strong> (0)206


207Fortran 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)Character was manchen Politikern fehlt (1)Schriftzeichen (2)Wasserfall (0)


208 ANHANG E. KARLSRUHER TESTBetriebssystem Konzern (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)Ampersand Sand aus <strong>de</strong>r Amper (1)et-Zeichen, Kaufmanns-Und (2)Untiefe im Wattenmeer (0)


209Alias 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)Subrout<strong>in</strong>e Kleidungsstück e<strong>in</strong>es Priesters (0)was im Unterbewußten (0)Unterprogramm (2)


210 ANHANG E. KARLSRUHER TESTSpoiler 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)Wysiwyg englisch für Wolpert<strong>in</strong>ger (0)französisch für Elmentritschen (0)what you see is what you get (2)


211Register 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)FTP 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)


212 ANHANG E. KARLSRUHER TESTDomä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)Slip Unterbekleidung (1)Schlupfschuh (0)Internet-Protokoll (2)


213Diä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>m Computer.• 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 Karriere außerhalb <strong>de</strong>r EDV undsuchen 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 of this license document, butchang<strong>in</strong>g it is not allowed.PREAMBLEThe licenses for most software are <strong>de</strong>signed to take away your freedom to share and change it.By contrast, the GNU General Public 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 for all its users. This GeneralPublic License applies to most of the Free Software Foundation’s software and to any otherprogram whose authors commit to us<strong>in</strong>g it. (Some other Free Software Foundation softwareis covered by the GNU Library General Public License <strong>in</strong>stead.) You can apply it to yourprograms, too.When we speak of free software, we are referr<strong>in</strong>g to freedom, not price. Our General PublicLicenses are <strong>de</strong>signed to make sure that you have the freedom to distribute copies of freesoftware (and charge for this service if you wish), that you receive source co<strong>de</strong> or can get it ifyou want it, that you can change the software or use pieces of it <strong>in</strong> new free programs; andthat you know you can do these th<strong>in</strong>gs.To protect your rights, we need to make restrictions that forbid anyone to <strong>de</strong>ny you theserights or to ask you to surren<strong>de</strong>r the rights. These restrictions translate to certa<strong>in</strong> responsibilitiesfor you if you distribute copies of the software, or if you modify it.For example, if you distribute copies of such a program, whether gratis or for a fee, youmust give the recipients all the rights that you have. You must make sure that they, too,receive or can get the source co<strong>de</strong>. And you must show them these terms so they know theirrights.We protect your rights with two steps: (1) copyright the software, and (2) offer you thislicense which gives you legal permission to copy, distribute and/or modify the software.Also, for each author’s protection and ours, we want to make certa<strong>in</strong> that everyone un<strong>de</strong>rstandsthat there is no warranty for this free software. If the software is modified by someoneelse and passed on, we want its recipients to know that what they have is not the orig<strong>in</strong>al, sothat any problems <strong>in</strong>troduced by others will not reflect on the orig<strong>in</strong>al authors’ reputations.F<strong>in</strong>ally, any free program is threatened constantly by software patents. We wish to avoidthe danger that redistributors of a free program will <strong>in</strong>dividually obta<strong>in</strong> patent licenses, <strong>in</strong>effect mak<strong>in</strong>g the program proprietary. To prevent this, we have ma<strong>de</strong> it clear that any patentmust be licensed for everyone’s free use or not licensed at all.The precise terms and conditions for copy<strong>in</strong>g, distribution and modification follow.GNU GENERAL PUBLIC LICENSETERMS AND CONDITIONS FOR COPYING, DISTRIBUTION ANDMODIFICATION214


F.1. GNU GENERAL PUBLIC LICENSE 2150. This License applies to any program or other work which conta<strong>in</strong>s a notice placed bythe copyright hol<strong>de</strong>r say<strong>in</strong>g it may be distributed un<strong>de</strong>r the terms of this General PublicLicense. The “Program”, below, refers to any such program or work, and a “work basedon the Program” means either the Program or any <strong>de</strong>rivative work un<strong>de</strong>r copyrightlaw: that is to say, a work conta<strong>in</strong><strong>in</strong>g the Program or a portion of it, either verbatim orwith modifications and/or translated <strong>in</strong>to another language. (Here<strong>in</strong>after, translation is<strong>in</strong>clu<strong>de</strong>d without limitation <strong>in</strong> the term “modification”.) Each licensee is addressed as“you”.Activities other than copy<strong>in</strong>g, distribution and modification are not covered by this License;they are outsi<strong>de</strong> its scope. The act of runn<strong>in</strong>g the Program is not restricted, andthe output from the Program is covered only if its contents constitute a work based onthe Program (<strong>in</strong><strong>de</strong>pen<strong>de</strong>nt of hav<strong>in</strong>g been ma<strong>de</strong> by runn<strong>in</strong>g the Program). Whether thatis true <strong>de</strong>pends on what the Program does.1. You may copy and distribute verbatim copies of the Program’s source co<strong>de</strong> as you receiveit, <strong>in</strong> any medium, provi<strong>de</strong>d that you conspicuously and appropriately publish on eachcopy an appropriate copyright notice and disclaimer of warranty; keep <strong>in</strong>tact all thenotices that refer to this License and to the absence of any warranty; and give any otherrecipients of the Program a copy of this License along with the Program.You may charge a fee for the physical act of transferr<strong>in</strong>g a copy, and you may at youroption offer warranty protection <strong>in</strong> exchange for a fee.2. You may modify your copy or copies of the Program or any portion of it, thus form<strong>in</strong>g awork 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 meet all of these conditions:(a) You must cause the modified files to carry prom<strong>in</strong>ent notices stat<strong>in</strong>g that you changedthe files and the date of any change.(b) You must cause any work that you distribute or publish, that <strong>in</strong> whole or <strong>in</strong> partconta<strong>in</strong>s or is <strong>de</strong>rived from the Program or any part thereof, to be licensed as awhole at no charge to all third parties un<strong>de</strong>r the terms of this License.(c) If the modified program normally reads commands <strong>in</strong>teractively when run, youmust cause it, when started runn<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 an appropriate copyright noticeand a notice that there is no 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>r these conditions, and tell<strong>in</strong>gthe user how to view a copy of this License. (Exception: if the Program itself is<strong>in</strong>teractive but does not normally pr<strong>in</strong>t such an announcement, your work basedon the Program is not required 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 thatwork are not <strong>de</strong>rived from the 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 thosesections when you distribute them as separate works. But when you distribute the samesections as part of a whole which is a work based on the Program, the distribution ofthe whole must be on the terms of this License, whose permissions for other licenseesextend to the entire whole, and thus to each and every part regardless of who wrote it.Thus, it is not the <strong>in</strong>tent of this section to claim rights or contest your rights to workwritten 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 based on the Program with the Program(or with a work based on 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 of this License.3. You may copy and distribute the Program (or a work based on it, un<strong>de</strong>r Section 2) <strong>in</strong>object co<strong>de</strong> or executable form un<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:


216 ANHANG F. GNU LIZENZEN(a) Accompany it with the complete correspond<strong>in</strong>g mach<strong>in</strong>e-readable source co<strong>de</strong>,which must be distributed un<strong>de</strong>r the terms of Sections 1 and 2 above on a mediumcustomarily used for software <strong>in</strong>terchange; or,(b) Accompany it with a written offer, valid for at least three years, to give any thirdparty, for a charge no more than your cost of physically perform<strong>in</strong>g source distribution,a complete mach<strong>in</strong>e-readable copy of the correspond<strong>in</strong>g source co<strong>de</strong>, to bedistributed un<strong>de</strong>r the terms of Sections 1 and 2 above on a medium customarilyused for software <strong>in</strong>terchange; or,(c) Accompany it with the <strong>in</strong>formation you received as to the offer to distribute correspond<strong>in</strong>gsource co<strong>de</strong>. (This alternative is allowed only for noncommercial distributionand only if you received the program <strong>in</strong> object co<strong>de</strong> or executable form withsuch an offer, <strong>in</strong> accord with Subsection b above.)The source co<strong>de</strong> for a work means the preferred form of the work for mak<strong>in</strong>g modificationsto it. For an executable work, complete source co<strong>de</strong> means all the source co<strong>de</strong> for allmodules 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 usedto control compilation and <strong>in</strong>stallation of the executable. However, as a special exception,the source co<strong>de</strong> distributed need not <strong>in</strong>clu<strong>de</strong> anyth<strong>in</strong>g that is normally distributed(<strong>in</strong> either source or b<strong>in</strong>ary form) with the major components (compiler, kernel, and soon) of the operat<strong>in</strong>g system on which the executable runs, unless that component itselfaccompanies the executable.If distribution of executable or object co<strong>de</strong> is ma<strong>de</strong> by offer<strong>in</strong>g access to copy from a<strong>de</strong>signated place, then offer<strong>in</strong>g equivalent access to copy the source co<strong>de</strong> from the sameplace counts as distribution of the source co<strong>de</strong>, even though third parties are notcompelled to copy the source along with the object co<strong>de</strong>.4. You may not copy, modify, sublicense, or distribute the Program except as expressly provi<strong>de</strong>dun<strong>de</strong>r this License. Any attempt otherwise to copy, modify, sublicense or distributethe Program is void, and will automatically term<strong>in</strong>ate your rights un<strong>de</strong>r this License.However, parties who have received copies, or rights, from you un<strong>de</strong>r this License willnot have their licenses term<strong>in</strong>ated so long as such parties rema<strong>in</strong> <strong>in</strong> full compliance.5. You are not required to accept this License, s<strong>in</strong>ce you have not signed it. However,noth<strong>in</strong>g else grants you permission to modify or distribute the Program or its <strong>de</strong>rivativeworks. These actions are prohibited by law if you do not accept this License. Therefore,by modify<strong>in</strong>g or distribut<strong>in</strong>g the Program (or any work based on the Program), you<strong>in</strong>dicate your acceptance of this License to do so, and all its terms and conditions forcopy<strong>in</strong>g, distribut<strong>in</strong>g or modify<strong>in</strong>g the Program or works based on it.6. Each time you redistribute the Program (or any work based on the Program), the recipientautomatically receives a license from the orig<strong>in</strong>al licensor to copy, distribute ormodify the Program subject to these terms and conditions. You may not impose anyfurther restrictions on the recipients’ exercise of the rights granted here<strong>in</strong>. You are notresponsible for enforc<strong>in</strong>g compliance by third parties to this License.7. If, as a consequence of a court judgment or allegation of patent <strong>in</strong>fr<strong>in</strong>gement or for anyother reason (not limited to patent issues), conditions are imposed on you (whether bycourt or<strong>de</strong>r, agreement or otherwise) that contradict the conditions of this License, theydo not excuse you from the conditions of this License. If you cannot distribute so asto satisfy simultaneously your obligations un<strong>de</strong>r this License and any other pert<strong>in</strong>entobligations, then as a consequence you may not distribute the Program at all. For example,if a patent license would not permit royalty-free redistribution of the Programby all those who receive copies directly or <strong>in</strong>directly through you, then the only way youcould satisfy both it and this License would be to refra<strong>in</strong> entirely from distribution ofthe Program.If any portion of this section is held <strong>in</strong>valid or unenforceable un<strong>de</strong>r any particular circumstance,the balance of the section 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.


F.1. GNU GENERAL PUBLIC LICENSE 217It is not the purpose of this section to <strong>in</strong>duce you to <strong>in</strong>fr<strong>in</strong>ge any patents or other propertyright claims or to contest validity of any such claims; this section has the solepurpose of protect<strong>in</strong>g the <strong>in</strong>tegrity of the free software distribution system, which is implementedby public license practices. Many people have ma<strong>de</strong> generous contributionsto the wi<strong>de</strong> range of software distributed through that system <strong>in</strong> reliance on consistentapplication of that system; it is up to the author/donor to <strong>de</strong>ci<strong>de</strong> if he or she is will<strong>in</strong>g todistribute software through any other system and a licensee cannot impose that choice.This section is <strong>in</strong>ten<strong>de</strong>d to make thoroughly clear what is believed to be a consequenceof 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 eitherby patents or by copyrighted <strong>in</strong>terfaces, the orig<strong>in</strong>al copyright hol<strong>de</strong>r who places theProgram un<strong>de</strong>r this License may add an explicit geographical distribution limitationexclud<strong>in</strong>g those countries, so that distribution is permitted only <strong>in</strong> or among countriesnot thus exclu<strong>de</strong>d. In such case, this License <strong>in</strong>corporates the limitation as if written <strong>in</strong>the body of this License.9. The Free Software Foundation may publish revised and/or new versions of the GeneralPublic License from time to time. Such new versions will be similar <strong>in</strong> spirit to thepresent version, but may differ <strong>in</strong> <strong>de</strong>tail to address new problems or concerns.Each version is given a dist<strong>in</strong>guish<strong>in</strong>g version number. If the Program specifies a versionnumber of this License which applies to it and “any later version”, you have theoption of follow<strong>in</strong>g the terms and conditions either of that version or of any later versionpublished by the Free Software Foundation. If the Program does not specify a versionnumber of this License, you may choose any version ever published by the Free SoftwareFoundation.10. If you wish to <strong>in</strong>corporate parts of the Program <strong>in</strong>to other free programs whose distributionconditions are different, write to the author to ask for permission. For softwarewhich is copyrighted by the Free Software Foundation, write to the Free Software Foundation;we sometimes make exceptions 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 our free software and of promot<strong>in</strong>gthe shar<strong>in</strong>g and reuse of software generally.NO WARRANTY11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTYFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHENOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIESPROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRES-SED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OFMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK ASTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THEPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,REPAIR OR CORRECTION.12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITINGWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR RE-DISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARI-SING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOTLIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SU-STAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATEWITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEENADVISED OF THE POSSIBILITY OF SUCH DAMAGES.END OF TERMS AND CONDITIONS


218 ANHANG F. GNU LIZENZENAppendix: How to Apply These Terms to Your New ProgramsIf you <strong>de</strong>velop a new program, and you want it to be of the greatest possible use to the public,the best way to achieve this is to 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 is safest to attach them to thestart of each source file to most effectively convey the exclusion of warranty; and each fileshould have at least the “copyright” l<strong>in</strong>e and a po<strong>in</strong>ter to where the full notice is found.Copyright (C) This program is free software; you can redistribute it and/or modify it un<strong>de</strong>r theterms of the GNU General Public License as published by the Free Software Foundation;either version 2 of the License, or (at your option) any later version.This program is distributed <strong>in</strong> the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY or FIT-NESS FOR A PARTICULAR PURPOSE. See the GNU General Public License formore <strong>de</strong>tails.You should have received a copy of the GNU General Public License along withthis program; if not, write to the 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 and paper mail.If the program is <strong>in</strong>teractive, make it output a short notice like 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 WARRANTY; for <strong>de</strong>tails type ‘showw’.This is free software, and you are welcome to redistribute it 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 should show the appropriate parts ofthe General Public License. Of course, the commands you use may be called someth<strong>in</strong>g otherthan show w and show c; they could even be mouse-clicks or menu items—whatever suitsyour program.You should also get your employer (if you work as a programmer) or your school, if any, tosign a “copyright disclaimer” for the 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‘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>g your program <strong>in</strong>to proprietaryprograms. If your program is a subrout<strong>in</strong>e library, you may consi<strong>de</strong>r it more useful to permitl<strong>in</strong>k<strong>in</strong>g proprietary applications with the library. If this is what you want to do, use the GNULibrary General Public License <strong>in</strong>stead of this License.F.2 GNU Free Documentation LicenseKopiert von http://www.gnu.org/copyleft/.


F.2. GNU FREE DOCUMENTATION LICENSE 219Version 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 of this license document, butchang<strong>in</strong>g it is not allowed.PreambleThe purpose of this license is to make a manual, textbook, or other functional and usefuldocument free <strong>in</strong> the sense of freedom: to assure everyone the effective freedom to copy andredistribute it, with or without modify<strong>in</strong>g it, either commercially or noncommercially. Secondarily,this license preserves for the author and publisher a way to get credit for their work,while not be<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>rivative works of the document mustthemselves be free <strong>in</strong> the same sense. It complements the GNU General Public License, whichis a copyleft 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 manuals for free software, because freesoftware needs free documentation: a free program should come with manuals provid<strong>in</strong>g thesame freedoms that the software does. But this license is not limited to software manuals; itcan be used for any textual work, regardless of subject matter or whether it is published as apr<strong>in</strong>ted book. We recommend this license pr<strong>in</strong>cipally for works whose purpose is <strong>in</strong>structionor 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 noticeplaced by the copyright hol<strong>de</strong>r say<strong>in</strong>g it can be distributed un<strong>de</strong>r the terms of this license.Such a notice grants a world-wi<strong>de</strong>, royalty-free license, unlimited <strong>in</strong> duration, to use thatwork un<strong>de</strong>r the conditions stated here<strong>in</strong>. The Document, below, refers to any such manual orwork. Any member of the public is a licensee, and is addressed as you. You accept the licenseif you copy, modify or distribute the work <strong>in</strong> a way 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>g the Document or aportion of it, either copied verbatim, or with modifications and/or translated <strong>in</strong>to anotherlanguage.A Secondary Section is a named appendix or a front-matter section of the Documentthat <strong>de</strong>als exclusively with the relationship of the publishers or authors of the Document tothe Document’s overall subject (or to related matters) and conta<strong>in</strong>s noth<strong>in</strong>g that could falldirectly with<strong>in</strong> that overall subject. (Thus, if the Document is <strong>in</strong> part a textbook of mathematics,a Secondary Section may not expla<strong>in</strong> any mathematics.) The relationship could be amatter of historical connection with the subject or with related matters, or of legal, commercial,philosophical, ethical or political position regard<strong>in</strong>g them.The Invariant Sections are certa<strong>in</strong> Secondary Sections whose titles are <strong>de</strong>signated, asbe<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 Secondary then it is not allowedto be <strong>de</strong>signated as Invariant. The Document may conta<strong>in</strong> zero Invariant Sections. If theDocument does 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 are listed, as Front-Cover Textsor Back-Cover Texts, <strong>in</strong> the notice that says that the Document is released un<strong>de</strong>r this license.A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.A Transparent copy of the Document means a mach<strong>in</strong>e-readable copy, represented <strong>in</strong>a format whose specification is available to the general public, that is suitable for revis<strong>in</strong>gthe Document straightforwardly with generic text editors or (for images 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 issuitable for <strong>in</strong>put to text formatters or for automatic translation to a variety of formats suitablefor <strong>in</strong>put to text formatters. A copy ma<strong>de</strong> <strong>in</strong> an otherwise Transparent file format whose


220 ANHANG F. GNU LIZENZENmarkup, or absence of markup, has been arranged to thwart or discourage subsequent modificationby rea<strong>de</strong>rs is not Transparent. An image format is not Transparent if used for anysubstantial amount 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>put format, SGML or XML us<strong>in</strong>g a publicly availableDTD, and standard-conform<strong>in</strong>g simple HTML, PostScript or PDF <strong>de</strong>signed for 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> proprietary formats that can be read and edited only by proprietary word processors,SGML or XML for which the DTD and/or process<strong>in</strong>g tools are not generally available, and themach<strong>in</strong>e-generated HTML, PostScript or PDF produced by some word processors for outputpurposes only.The Title Page means, for a pr<strong>in</strong>ted book, the title page itself, plus such follow<strong>in</strong>g pagesas are nee<strong>de</strong>d to hold, legibly, the material this 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 Pagemmeans the textnear the most prom<strong>in</strong>ent appearance of the work’s title, preced<strong>in</strong>g the beg<strong>in</strong>n<strong>in</strong>g of the bodyof the text.A section Entitled XYZ means a named subunit of the Document whose title either isprecisely XYZ or conta<strong>in</strong>s XYZ <strong>in</strong> parentheses follow<strong>in</strong>g text that translates XYZ <strong>in</strong> anotherlanguage. (Here XYZ stands for a specific section name mentioned below, such as Acknowledgements,Dedications, Endorsements, or History.) To Preserve the Title of such asection when you modify the Document means that it rema<strong>in</strong>s a section Entitled XYZ accord<strong>in</strong>gto this <strong>de</strong>f<strong>in</strong>ition.The Document may <strong>in</strong>clu<strong>de</strong> Warranty Disclaimers next to the notice which states that thislicense applies to the Document. These Warranty Disclaimers are consi<strong>de</strong>red to be <strong>in</strong>clu<strong>de</strong>dby reference <strong>in</strong> this license, but only as regards disclaim<strong>in</strong>g warranties: any other implicationthat these Warranty Disclaimers may have is void and has no effect on the mean<strong>in</strong>g of thislicense.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>gthis license applies to the Document are reproduced <strong>in</strong> all copies, and that you add no otherconditions whatsoever to those of this license. You may not use technical measures to obstructor control the read<strong>in</strong>g or further copy<strong>in</strong>g of the copies you make or distribute. However, youmay accept compensation <strong>in</strong> exchange for copies. If you distribute a large enough number ofcopies you must also follow the conditions <strong>in</strong> section 3.You may also lend copies, un<strong>de</strong>r the same conditions stated above, and you may publiclydisplay copies.3. COPYING IN QUANTITYIf you publish pr<strong>in</strong>ted copies (or copies <strong>in</strong> media that commonly have pr<strong>in</strong>ted covers) ofthe Document, number<strong>in</strong>g more than 100, and the Document’s license notice requires CoverTexts, you must enclose the copies <strong>in</strong> covers that carry, clearly and legibly, all these CoverTexts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Bothcovers must also clearly and legibly i<strong>de</strong>ntify you as the publisher of these copies. The frontcover must present the full title with all words of the title equally prom<strong>in</strong>ent and visible. Youmay add other material on the covers <strong>in</strong> addition. Copy<strong>in</strong>g with changes limited to the covers,as long as they preserve the title of the Document and satisfy these conditions, can be treatedas 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 fit legibly, you should put thefirst ones listed (as many as fit reasonably) on the actual cover, and cont<strong>in</strong>ue the rest ontoadjacent pages.If you publish or distribute Opaque copies of the Document number<strong>in</strong>g more than 100,you must either <strong>in</strong>clu<strong>de</strong> a mach<strong>in</strong>e-readable Transparent copy along with each Opaque copy,or state <strong>in</strong> or with each Opaque copy a computer-network location from which the general


F.2. GNU FREE DOCUMENTATION LICENSE 221network-us<strong>in</strong>g public has access to download us<strong>in</strong>g public-standard network protocols a completeTransparent copy of the Document, free of ad<strong>de</strong>d material. If you use the latter option,you must take reasonably pru<strong>de</strong>nt steps, when you beg<strong>in</strong> distribution of Opaque copies <strong>in</strong>quantity, to ensure that this Transparent copy will rema<strong>in</strong> thus accessible at the stated locationuntil at least one year after the last time you distribute an Opaque copy (directly orthrough your agents or retailers) of that edition to the public.It is requested, but not required, that you contact the authors of the Document well beforeredistribut<strong>in</strong>g any large number of copies, to give them a chance to provi<strong>de</strong> you with anupdated version of the Document.4. MODIFICATIONSYou may copy and distribute a Modified Version of the Document un<strong>de</strong>r the conditions ofsections 2 and 3 above, provi<strong>de</strong>d that you release the Modified Version un<strong>de</strong>r precisely thislicense, with the Modified Version fill<strong>in</strong>g the role of the Document, thus licens<strong>in</strong>g distributionand modification of the Modified Version to whoever possesses a copy of it. In addition, youmust do these 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>ct from that of the Document,and from those of previous versions (which should, if there were any, be listed <strong>in</strong>the History section of the Document). You may use the same title as a previous versionif the orig<strong>in</strong>al publisher of that version gives permission.B. List on the Title Page, as authors, one or more persons or entities responsible for authorshipof the modifications <strong>in</strong> the Modified Version, together with at least five of thepr<strong>in</strong>cipal authors of the Document (all of its pr<strong>in</strong>cipal authors, if it has fewer than five),unless they release you from this requirement.C. State on the Title page the name of the publisher of the Modified Version, as the publisher.D. Preserve all the copyright notices of the Document.E. Add an appropriate copyright notice for your modifications adjacent to the other copyrightnotices.F. Inclu<strong>de</strong>, immediately after the copyright notices, a license notice giv<strong>in</strong>g the public permissionto use the Modified Version un<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 Sections and required CoverTexts given <strong>in</strong> the Document’s license notice.H. Inclu<strong>de</strong> an unaltered copy of this license.I. Preserve the section entitled History, Preserve its title, and add to it an item stat<strong>in</strong>g atleast the title, year, new authors, and publisher of the Modified Version as given on theTitle Page. If there is no section entitled History <strong>in</strong> the Document, create one stat<strong>in</strong>gthe title, year, authors, and publisher 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 Document for public access to a Transparentcopy of the Document, and likewise the network locations given <strong>in</strong> the Documentfor previous versions it was based on. These may be placed <strong>in</strong> the History section. Youmay omit a network location for a work that was published at least four years before theDocument itself, or if the orig<strong>in</strong>al publisher of the 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 section all 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> theirtitles. Section numbers or the equivalent are not consi<strong>de</strong>red part of the section titles.


222 ANHANG F. GNU LIZENZENM. Delete any section entitled Endorsements. Such a section may not be <strong>in</strong>clu<strong>de</strong>d <strong>in</strong> theModified Version.N. Do not retitle any exist<strong>in</strong>g section to be entitled Endorsements or to conflict <strong>in</strong> title withany Invariant Section.O. Preserve any Warranty Disclaimers.If the Modified Version <strong>in</strong>clu<strong>de</strong>s new front-matter sections or appendices that qualify asSecondary Sections and conta<strong>in</strong> no material copied from the Document, you may at youroption <strong>de</strong>signate some or all of these sections as <strong>in</strong>variant. To do this, add their titles to thelist of Invariant Sections <strong>in</strong> the Modified Version’s license notice. These titles must be dist<strong>in</strong>ctfrom any other section titles.You may add a section entitled Endorsements, provi<strong>de</strong>d it conta<strong>in</strong>s noth<strong>in</strong>g but endorsementsof your Modified Version by various parties – for example, statements of peer reviewor that the text has been approved by an organization as the authoritative <strong>de</strong>f<strong>in</strong>ition of astandard.You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25words as a Back-Cover Text, to the 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 may be ad<strong>de</strong>d by (or througharrangements ma<strong>de</strong> by) any one entity. If the Document already <strong>in</strong>clu<strong>de</strong>s a cover text for thesame cover, previously ad<strong>de</strong>d by you or by arrangement ma<strong>de</strong> by the same entity you areact<strong>in</strong>g on behalf of, you may not add another; but you may replace the old one, on explicitpermission from the previous publisher that ad<strong>de</strong>d the old one.The author(s) and publisher(s) of the Document do not by this license give permission touse their names for publicity for or to assert or imply endorsement of any Modified Version.5. COMBINING DOCUMENTSYou may comb<strong>in</strong>e the Document with other documents released un<strong>de</strong>r this license, un<strong>de</strong>rthe terms <strong>de</strong>f<strong>in</strong>ed <strong>in</strong> section 4 above for modified versions, provi<strong>de</strong>d that you <strong>in</strong>clu<strong>de</strong> <strong>in</strong> thecomb<strong>in</strong>ation all of the Invariant Sections of all of the orig<strong>in</strong>al documents, unmodified, andlist them all as Invariant Sections of your comb<strong>in</strong>ed work <strong>in</strong> its license notice, and that youpreserve all their Warranty Disclaimers.The comb<strong>in</strong>ed work need only conta<strong>in</strong> one copy of this license, and multiple i<strong>de</strong>nticalInvariant Sections may be replaced with a s<strong>in</strong>gle copy. If there are multiple Invariant Sectionswith the same name but different contents, make the title of each such section unique byadd<strong>in</strong>g at the end of it, <strong>in</strong> parentheses, the name of the orig<strong>in</strong>al author or publisher of thatsection if known, or else a unique number. Make the same adjustment to the section titles <strong>in</strong>the list of Invariant Sections <strong>in</strong> the license notice of the comb<strong>in</strong>ed work.In the comb<strong>in</strong>ation, you must comb<strong>in</strong>e any sections entitled History <strong>in</strong> the various orig<strong>in</strong>aldocuments, form<strong>in</strong>g one section entitled History; likewise comb<strong>in</strong>e any sections entitled Acknowledgements,and any sections entitled Dedications. You must <strong>de</strong>lete all sections entitledEndorsements.6. COLLECTIONS OF DOCUMENTSYou may make a collection consist<strong>in</strong>g of the Document and other documents released un<strong>de</strong>rthis license, and replace the <strong>in</strong>dividual copies of this license <strong>in</strong> the various documentswith a s<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 you follow the rules of thislicense for verbatim copy<strong>in</strong>g of each of the documents <strong>in</strong> all other respects.You may extract a s<strong>in</strong>gle document from such a collection, and distribute it <strong>in</strong>dividuallyun<strong>de</strong>r this license, provi<strong>de</strong>d you <strong>in</strong>sert a copy of this license <strong>in</strong>to the extracted document, andfollow this license <strong>in</strong> all other respects regard<strong>in</strong>g verbatim copy<strong>in</strong>g of that document.7. AGGREGATION WITH INDEPENDENT WORKSA compilation of the Document or its <strong>de</strong>rivatives with other separate and <strong>in</strong><strong>de</strong>pen<strong>de</strong>ntdocuments or works, <strong>in</strong> or on a volume of a storage or distribution medium, is called an


F.2. GNU FREE DOCUMENTATION LICENSE 223aggregate if the copyright result<strong>in</strong>g from the compilation is not used to limit the legal rightsof the compilation’s users beyond what the <strong>in</strong>dividual works permit. When the Documentis <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.If the Cover Text requirement of section 3 is applicable to these copies of the Document,then if the Document is less than one half of the entire aggregate, the Document’s Cover Textsmay be placed on covers that bracket the Document with<strong>in</strong> the aggregate, or the electronicequivalent of covers if the Document is <strong>in</strong> electronic form. Otherwise they must appear onpr<strong>in</strong>ted covers that bracket the whole aggregate.8. TRANSLATIONTranslation is consi<strong>de</strong>red a k<strong>in</strong>d of modification, so you may distribute translations ofthe Document un<strong>de</strong>r the terms of section 4. Replac<strong>in</strong>g Invariant Sections with translationsrequires special permission from their copyright hol<strong>de</strong>rs, but you may <strong>in</strong>clu<strong>de</strong> translations ofsome or all Invariant Sections <strong>in</strong> addition to 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, andany Warranty Disclaimers, provi<strong>de</strong>d that you also <strong>in</strong>clu<strong>de</strong> the orig<strong>in</strong>al English version of thislicense and the orig<strong>in</strong>al versions of those notices and disclaimers. In case of a disagreementbetween the translation and the orig<strong>in</strong>al version of this license or a notice or disclaimer, theorig<strong>in</strong>al version will prevail.If a section <strong>in</strong> the Document is entitled Acknowledgements, Dedications, or History, therequirement (section 4) to Preserve its title (section 1) will typically require chang<strong>in</strong>g theactual title.9. TERMINATIONYou may not copy, modify, sublicense, or distribute the Document except as expressly provi<strong>de</strong>dfor un<strong>de</strong>r this license. Any other attempt to copy, modify, sublicense or distribute theDocument is void, and will automatically term<strong>in</strong>ate your rights un<strong>de</strong>r this license. However,parties who have received copies, or rights, from you un<strong>de</strong>r this license will not have theirlicenses term<strong>in</strong>ated so long as such parties rema<strong>in</strong> <strong>in</strong> full compliance.10. FUTURE REVISIONS OF THIS LICENSEThe Free Software Foundation may publish new, revised versions of the GNU Free DocumentationLicense from time to time. Such new versions will be similar <strong>in</strong> spirit tothe 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 version number. If the Documentspecifies that a particular numbered version of this license or any later version applies to it,you have the option of follow<strong>in</strong>g the terms and conditions either of that specified version or ofany later version that has been published (not as a draft) by the Free Software Foundation. Ifthe Document does not specify a version number of this license, you may choose any versionever published (not as a draft) by the Free Software Foundation.ADDENDUM: How to use this license for your documentsTo use this license <strong>in</strong> a document you have written, <strong>in</strong>clu<strong>de</strong> a copy of the license <strong>in</strong> theDocument and put the follow<strong>in</strong>g copyright and license notices just after the title page:Copyright ©YEAR YOUR NAME. Permission is granted to copy, distribute and/ormodify this document un<strong>de</strong>r the terms of the GNU Free Documentation License,Version 1.2 or any later version published by the Free Software Foundation; withno Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy ofthe license is <strong>in</strong>clu<strong>de</strong>d <strong>in</strong> the section entitled GNU Free Documentation License.


224 ANHANG F. GNU LIZENZENIf you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace thewith...Texts. l<strong>in</strong>e with this:with the Invariant Sections be<strong>in</strong>g LIST THEIR TITLES, with the Front-CoverTexts be<strong>in</strong>g LIST, and with the Back-Cover Texts be<strong>in</strong>g LIST.If you have Invariant Sections without Cover Texts, or some other comb<strong>in</strong>ation of thethree, merge those two alternatives to suit the situation.If your document conta<strong>in</strong>s nontrivial examples of program co<strong>de</strong>, we recommend releas<strong>in</strong>gthese examples <strong>in</strong> parallel un<strong>de</strong>r your 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 aufSeiete ?? aufgeführten Werken zu entnehmen. Die meisten Errungenschaften entwickeltensich über manchmal lange Zeitspannen, so dass vor e<strong>in</strong>ige Jahreszahlen um etwa zu setzenist.-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 andas 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ührt225


226 ANHANG G. ZEITTAFELunter <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ügungszweckeund 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>.Elektronische b<strong>in</strong>äre Addiermasch<strong>in</strong>e von JOHN VINCENT ATANASOFFund 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 HOPPERdie 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 Informationsspeicherungund -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öhren,wiegt 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 und


WILLIAM 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 (726).1954 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.1960 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.227


228 ANHANG G. ZEITTAFELE<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 ICs(Chips) auf.JOSEPH CARL ROBNETT LICKLIDER hat zwei Visionen: <strong>de</strong>n <strong>in</strong>teraktivenComputer und das galaktische Netz (wenn schon, <strong>de</strong>nn schon). Er wirdDirektor <strong>in</strong> <strong>de</strong>r ARPA und geht an die Verwirklichung se<strong>in</strong>er Visionen.1963 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 Institutedie 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.1968 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 und


stellt 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.Erste, 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.Xanadu-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)229


230 ANHANG G. ZEITTAFELBeg<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 andie 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-Netz.Frankreich 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 Xenix.Im Rechenzentrum Karlsruhe löst die IBM 3090 die


Siemens 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 Knoten.Computer-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 undFamilien 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.1992 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 0.90.Weltweit 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.231


232 ANHANG G. ZEITTAFEL1997 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 und1 Mio. Internetanschlüsse (Quelle: Fachverband Informationstechnik).Debian 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 manmit 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üter,weil die Programmierer früherer Jahrzehnte mit <strong>de</strong>n Bits knauserten.Der 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 Schalttagnach 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 Pakete.Microsoft 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: RIPE).2001 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 SANGER die Wikipedia,e<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 Wikis.2002 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>ux.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,bedrohen 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>ternationaleWikimedia-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,


233die <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 WebsitesGoogle, Yahoo, Microsoft, BBC, CNN, Ebay, Fox News, Amazon und Wikipedia.Das Deutsche Forschungsnetz nimmt das X-W<strong>in</strong> <strong>in</strong> Betrieb, e<strong>in</strong>e Netz<strong>in</strong>frastrukturmit 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> .<strong>de</strong>,sie 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 lesen wollen, schon gelesen habeno<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.E. Kajan Information Technology Encyclopedia and AcronymsSpr<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/jargon/Begriffe 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, Betriebssysteme amBeispiel 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 C234


235W. 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-analytische Lö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.htmlD. 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.htmlW. 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, BOOLEscheFunktionen, Automaten, Grammatiken, Formale Sprachen3. 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 with CSpr<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.K. 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> C


236 ANHANG H. ZUM WEITERLESENR. 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.H. 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 Debian GNU/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>r KommandosH. 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-Kommandos


237M. 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<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> UNIX SystemAdm<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>istrationPrentice 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 The AWKProgramm<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.


238 ANHANG H. ZUM WEITERLESEND. 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 und makeAddison-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>OSF/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.


239H. Partl u. a. LaTeX-Kurzbeschreibungftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/latex/lkurz.ps.gzftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/latex/lkurz.tar.gz1990, 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 VGA CardsAddison-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 Manipulation Program11. 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 and ToolsAddison-Wesley, Boston, 1986, 796 S.B. Beizer Software Test<strong>in</strong>g TechniquesVan Nostrand-Re<strong>in</strong>hold, 1990, 503 S.F. 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, WerkzeugeN. Ford Programmer’s Gui<strong>de</strong>ftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/misc/pgui<strong>de</strong>.txt1989, 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.


240 ANHANG H. ZUM WEITERLESENM. Marcotty, H. Ledgard The World of Programm<strong>in</strong>g LanguagesSpr<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ängigN. Wirth Systematisches ProgrammierenTeubner, Stuttgart, 1993, 160 S.Allgeme<strong>in</strong>e E<strong>in</strong>führung <strong>in</strong>s Programmieren, PASCAL-nahe12. 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>g ApproachSpr<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.J. 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 ANSI/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.htm


241N. M. Josuttis The <strong>C++</strong> Standard Library – A Tutorial and 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>g LanguageDeutsche Ü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 by ExampleAddison-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>r STLD. 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.Verbreitetes Lehrbuch für Anfänger, enthält auch ANSI-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 ANSIR. 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.


242 ANHANG H. ZUM WEITERLESENK. 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>13. 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/zen.ps.gz1992, 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’s Gui<strong>de</strong>O’Reilly, Sebastopol, 2000, 500 S.E. Krol The Hitchhikers Gui<strong>de</strong> to the Internetftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/net/general/hitchhg.txt1987, 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.html


243A. 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, wenig TechnikC. 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


244 ANHANG H. ZUM WEITERLESEN– RFC 1244 (FYI 8): Site Security Handbookftp://ftp.nic.<strong>de</strong>/pub/rfc/rfc1244.txt1991, 101 S., ASCIISicherheits-Ratgeber für Internet-Benutzer– Department of Defense Trusted Computer SystemsEvaluation Criteria (Orange Book)ftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/net/secur/orange-book.gz1985, 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/fcvol1.ps.gzftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/net/secur/fcvol2.ps.gz1992, 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 Security Inci<strong>de</strong>ntsA Primer from Prevention through Recoveryftp://ftp.ciw.uni-karlsruhe.<strong>de</strong>/pub/docs/net/secur/primer.ps.gz1990, 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/secdoc.ps.gz1990, 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 Hacker ContestSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 2003, 300 S.16. Computerrecht– Newsgruppen:comp.society.privacycomp.privacycomp.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> Kommentar


245G. v. Gravenreuth Computerrecht von A – Z (Beck Rechtsberater)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 Deutschland– Die Geschichte <strong>de</strong>r masch<strong>in</strong>ellen Datenverarbeitung Band 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 nordamerikanischer SichtO. 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, 345 S.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>dsSpr<strong>in</strong>ger, Berl<strong>in</strong> + Hei<strong>de</strong>lberg, 1995, 295 S.Biografien berühmter Computerpioniere


246 ANHANG H. ZUM WEITERLESEND. 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>s1993, 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 Digital AgePetersen, 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 verantwortlich se<strong>in</strong>?<strong>in</strong>: Hans Lenk, Macht und Machbarkeit <strong>de</strong>r TechnikReclam-Band 8989, Ph. Reclam, Stuttgart, 1994, 152 S.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>ungenK. Ste<strong>in</strong>buch Die <strong>de</strong>s<strong>in</strong>formierte GesellschaftBusse + Seewald, Herford, 1989, 269 S. (vergriffen)J. 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>/


247– 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; viel C und <strong>C++</strong>Und noch e<strong>in</strong>ige Verlage:• Addison-Wesley, Bonn,http://www.addison-wesley.<strong>de</strong>/• 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/


248 ANHANG H. ZUM WEITERLESENUnd ü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, 12


249


PersonenverzeichnisAiken, H. 225Andreessen, M. 231Atanasoff, J. V. 225Babbage, C. 225Backus, J. 47Bar<strong>de</strong>en, J. 225Berners-Lee, T. 225Berry, C. 225Boole, G. 225Bratta<strong>in</strong>, W. H. 225Brickl<strong>in</strong>, D. 225Cailliau, R. 225Cerf, V. G. 229Codd, E. F. 229Crocker, S. 225Diffie, W. 229Eckert, J. P. 225Engelbart, D. C. 225Fibonacci 225Frankston, B. 225Gibson, W. 225Heilig, M. 225Hellmann, M. E. 229Hewlett, W. 225Hollerith, H. 225Hopper, G. 225Hopper, G. M. 7Jacquard, J. M. 225Jobs, S. P. 229Kahn, R. E. 229Kemeny, J. 8Kernighan, B. 9, 15Kernighan, B. W. 236Kilby, J. St. C. 225Knuth, D. E. 225, 235Kurtz, T. 8Lamport, L. 238Leibniz, G. W. 225Lickli<strong>de</strong>r, J. C. R. 225L<strong>in</strong>k, E. 225Mauchly, J. W. 225Metcalfe, R. 225Mill, H. 225M<strong>in</strong>sky, M. L. 225Morse, S. F. B. 225Murdock, I. 231Napier, J. 225Nassi, I. 16Naur, P. 47Nelson, T. 225Neumann, J. von 225Nickel, K. 227, 228Oikar<strong>in</strong>en, J. 230Packard, D. 225Pascal, B. 225Pisa, L. von 225Plauger, P. J. 15Postel, J. B. 225Poulsen, W. 225Reis, J. P. 225Rem<strong>in</strong>gton, E. 225Ritchie, D. 9Sanger, L. M. 232Schickard, W. 225Shannon, C. E. 225, 232Shnei<strong>de</strong>rman, B. 16Shockley, W. B. 225Shugart, A. 229Stallman, R. M. 225Ste<strong>in</strong>buch, K. 225, 232, 246Stroustrup, B. 9, 225, 242Sutherland, I. E. 225Tanenbaum, A. S. 236, 243Thompson, K. 9Tichy, W. F. 28Torvalds, L. B. 225Tur<strong>in</strong>g, A. 225Volkerd<strong>in</strong>g, P. 231Wales, J. D. 232Weiss<strong>in</strong>ger, J. 225Wirth, N. 8, 240Wozniak, S. G. 229Zemanek, H. 246Zuse, K. 225, 246250


Sachverzeichnis/lib/libc.a 103/usr/<strong>in</strong>clu<strong>de</strong>/limits.h 50/usr/lib/libcurses.a 106#<strong>de</strong>f<strong>in</strong>e 129, 205#if<strong>de</strong>f 132#ifn<strong>de</strong>f 132#<strong>in</strong>clu<strong>de</strong> 130, 205#un<strong>de</strong>f 130$? 78$Hea<strong>de</strong>r$ (RCS) 29$Id$ (RCS) 29$Log$ (RCS) 29& (C) 66&& (C) 6664-Bit-Masch<strong>in</strong>e 51a.out 19, 44Abstrakter Datentyp 109access 38action (HTML) 167Adaptor 117adb 23adm<strong>in</strong> 33Adresskonstante 58Adressübergabe 82ALGOL 8, 174Algorithmus 178Alias-Anweisung (FORTRAN) 36Allgeme<strong>in</strong>heit 178ANSI-C 9AnweisungAlias-A. (FORTRAN) 36C-A. 73, 137Compiler-A. 36, 87<strong>de</strong>f<strong>in</strong>e-A. 129<strong>in</strong>clu<strong>de</strong>-A. 130Kontrollanweisung 73leere A. (C) 73Präprozessor-A. 129ar 25ar(1) 107Archiv (Datei) 25, 102argc 90argc 37Argumentvektor 90Argumentzähler 90argv 90argv 37ArrayA. of characters 54A. von Funktionspo<strong>in</strong>tern 82, 153Array 53In<strong>de</strong>x 53l<strong>in</strong>earisieren 54mehrdimensionales A. 54Name 54Subarray 119ASCIIGerman-ASCII 189Steuerzeichen 190Zeichensatz 180Assembler 3, 6, 7, 11, 97Assoziativität 72AusdruckAusdruck (C) 64ausführbar 12Ausgabe 69, 122Ausgang (Schleife) 75Auswahl (C) 74auto (C) 62Backus-Naur-Form 47BASIC 8BCD-System 180Beautifier 20Bed<strong>in</strong>gte Bewertung 67Bed<strong>in</strong>gte Kompilation 132Bed<strong>in</strong>gung (C) 74Bezug 85Bibliothek 25, 102b<strong>in</strong>är-kompatibel 12B<strong>in</strong>ary 12B<strong>in</strong>dung, dynamische 12B<strong>in</strong>dung, statische 12Block 137Botschaft (<strong>C++</strong>) 109Bottom-up-Entwurf 16break (C) 74, 77Bubblesort 28Buil<strong>de</strong>r 21CC 9<strong>C++</strong> 5, 9Obfuscated C. 171Objective C 10<strong>C++</strong> 5, 9C-XSC 10, 118C9X 9calloc(3) 158case (C) 74cast-Operator 71cb 13, 20, 45251


252 SACHVERZEICHNIScc 11, 19CC 11ccom 11c<strong>de</strong>cl 50cflow 27, 45Chaos Computer Club 225char (C) 52chatr 41chmod 45ci (RCS) 29close 38, 69co (RCS) 29COBOL 7Codierung (Programm) 10, 13Common Gateway Interface 167compact (Speichermo<strong>de</strong>ll) 108Compiler 3, 11, 19Compiler-Treiber 11Compilerbau 5compress(1) 136Computer Ai<strong>de</strong>d Software Eng<strong>in</strong>eer<strong>in</strong>g 33Concurrent Versions System 33Configuration Management 33configure (make) 22const (C) 50Constructor 110Conta<strong>in</strong>er 117cont<strong>in</strong>ue (C) 75, 77Contra vermes 24core 44creat 45Cross-Compiler 11ctime 36curses(3) 106, 141curses.h 106, 141cxref 28, 45DateiDatei 137Deskriptor 69Inclu<strong>de</strong>-D. 130, 204Kennung 12Mo<strong>de</strong> 41mtime 21Po<strong>in</strong>ter 70Strukturtyp 55System 173Datenaustausch 16Datenstruktur 16, 49Debuggerabsoluter D. 23symbolischer D. 23<strong>de</strong>fault (C) 74Def<strong>in</strong>ition 49Deklaration 49<strong>de</strong>krementieren 65, 69<strong>de</strong>lta 33<strong>de</strong>referenzieren 57, 68DIN 66230 135Disassembler 12do-while-Schleife (C) 75Dokumentation 134Dotprecision 120double (C) 52Doxygen 136Dualsystem 180dynamische B<strong>in</strong>dung 12dynamische Speicherverwaltung 158Editoremacs(1) 19nedit(1) 19vi(1) 19E<strong>in</strong><strong>de</strong>utigkeit 178E<strong>in</strong>gabe 69, 122E<strong>in</strong>gang (Schleife) 75Endlichkeit 178Entscheidbarkeit 179enum (C) 56envp 37etch 232Euro 232exit(2) 77Exponent 52Exten<strong>de</strong>d Scientific Comput<strong>in</strong>g 118extern (C) 62, 63, 173f77 19f90 19fclose 70fcntl.h 38FehlerDenkfehler 23Fehlerfreiheit 12, 140Fehlermeldung 23Grammatik-F. 23Laufzeit-F. 23logischer F. 23Mo<strong>de</strong>ll-F. 23semantischer F. 23Syntax-F. 23Zaunpfahl-F. 77Flag (Variable) 162float (C) 52Flussdiagramm 16fopen 70for-Schleife (C) 75fork 41FORM-Element 167Formatstr<strong>in</strong>g 94FORTRAN 7, 48Fortsetzungszeile (C) 46fpr<strong>in</strong>tf 45fputs 70


SACHVERZEICHNIS 253free(3) 158Freiburger Co<strong>de</strong> 7FunktionStr<strong>in</strong>gfunktion 104Funktion (C)Array von Funktionspo<strong>in</strong>tern 82Bibliothek 25, 102Def<strong>in</strong>ition 81E<strong>in</strong>sprungadresse 58Funktion 81, 137grafische F. 106Input/Output-F. 104mathematische F. 105Po<strong>in</strong>ter auf F. 82Prototyp 81Speicherklasse 62Standardfunktion 34, 103, 201virtuelle F. 111Xlib-F. 162gcc 20gdb 23Geltungsbereich 63get 33get (HTML) 167gets(3) 104getut 45Gleichung 64gmtime 35gnats 33GNU-Projekt 22GNU Free Documentation License 218GNU General Public License 214goto (C) 77gprof 24Grafik 153gzip(1) 136HASKELL 5Hexa<strong>de</strong>zimalsystem 180HP SoftBench 33huge (Speichermo<strong>de</strong>ll) 108IEEE Std 1063-1987 135if (C) 74if - else (C) 74Inclu<strong>de</strong>-Datei 130<strong>in</strong>fo(1) 137Initialisierung 49, 173<strong>in</strong>krementieren 65, 69Ino<strong>de</strong>Informationen aus <strong>de</strong>r I. 38INRIA 230<strong>in</strong>t (C) 51Interface (Sprachen) 37Internet 105Interpreter 11ISO/IEC 14882 9ISO/IEC 9899 9Iteration 94Iterator 117JAVA 5, 10K&R-C 9KarlsruheBeg<strong>in</strong>n <strong>de</strong>r Informatik <strong>in</strong> K. 225Informatikstudium <strong>in</strong> K. 225Rechenzentrum <strong>de</strong>r Universität K.225ZUSE Z 22 225Karlsruher Test 206Klammer (C) 72Klasse (<strong>C++</strong>) 109Klasse, abstrakte 111Komma-Operator 71, 75, 76Kommandozeile 90KommentarC 46, 47, 129, 135, 138<strong>C++</strong> 48, 109make 21KonstanteKonstante 46Literal 50symbolische K. 49, 129Kontrollanweisung 73Kreuzreferenz 28l-Wert 64Label (C) 77Langzahl-Arithmetik 121large (Speichermo<strong>de</strong>ll) 108ld 19LebensdauerOperand 49, 63, 64libQt 124l<strong>in</strong>ken (Programme) 19, 102L<strong>in</strong>ker 4, 11l<strong>in</strong>t 20, 43LISP 5Literal 46long (C) 51long double (C) 52ls 45lseek 38magic 38magic.h 38Magic Number 38ma<strong>in</strong>() 137ma<strong>in</strong>() 37, 90, 91make 21, 45make(1) 156Makefile 21Makro


254 SACHVERZEICHNISC 82, 129make 21malloc(3) 158man(1) 136man-Seite 136MANPATH 136Mantisse 52Masch<strong>in</strong>enco<strong>de</strong> 11Masch<strong>in</strong>ensprache 4Masch<strong>in</strong>enwort 51, 55math.h 105medium (Speichermo<strong>de</strong>ll) 108Member Access Specifier 110Meta Object Compiler 124method (HTML) 167Metho<strong>de</strong> (<strong>C++</strong>) 109M<strong>in</strong>us, unäres 172mknod 41moc 124Modul 19MODULA 8Modulus 65, 144monitor 25Motif 107NAG-Bibliothek 107NameName (C) 46, 48, 173Operan<strong>de</strong>n-N. 49Programm-N. 137Nassi-Shnei<strong>de</strong>rman-Diagramm 16Nebenwirkung 78Negation 172Newton-Verfahren 123nm 45nroff(1) 136NULL 58, 148Nullpo<strong>in</strong>ter 58, 145, 148, 173Obfuscated C 171Objective C 10Objekt (<strong>C++</strong>) 109Objekt (Variable) 49Objektco<strong>de</strong> 4, 11, 12Oktalsystem 180open 38, 69open(2) 104Operand 49Operationarithmetische O. 65Bit-O. 68, 173Grund-O. 16logische O. 66Modulo-O. 51Po<strong>in</strong>ter-O. 68Relations-O. 67zulässige O. 50Operator (Zeichen) 46, 64, 200Optimierung 140Parameteraktueller P. 82formaler P. 82Übergabe 82PASCAL 8Patch 12pc 19Pflichtenheft 15Platzhalter 82Po<strong>in</strong>terdangl<strong>in</strong>g P. 147Darstellung 173far P. 108huge P. 108near P. 108Nullpo<strong>in</strong>ter 58, 148, 173P.-Arithmetik 58P. auf Funktion 82, 153P. auf void 53, 148Po<strong>in</strong>ter 49, 56, 68, 147portieren 173POSIX 34post (HTML) 167Präprozessor 3, 11, 46Präprozessor (C) 129, 205Primzahl 127, 150pr<strong>in</strong>tf 70, 72pr<strong>in</strong>tf(3) 104, 204Private Member 110Problem Management 33prof 25Profiler 24ProgrammAufgabenstellung 13, 14benutzerfreundliches P. 13Bottom-up-Entwurf 16Codierung 10, 13, 15Dokumentation 134Effizienz 13Entwurf 13fehlerfreies P. 12Grund-Operation 16Hauptprogramm 137P. än<strong>de</strong>rn 12Patch 12Pflege 13Programm 137programmiererfreundliches P. 13Prototyp 16robustes P. 12Struktur 15, 16Test 13Top-down-Entwurf 15Version 12


SACHVERZEICHNIS 255ProgrammierspracheALGOL 8algorithmische P. 5Assembler 6, 7BASIC 8C 9<strong>C++</strong> 5, 9COBOL 7<strong>de</strong>klarative P. 5FORTRAN 7Freiburger Co<strong>de</strong> 7funktionale P. 5HASKELL 5imperative P. 5JAVA 5LISP 5logische P. 5masch<strong>in</strong>enorientierte P. 6Masch<strong>in</strong>ensprache 6Mischen von P. 82MODULA 8objektorientierte P. 5Paradigma 5PASCAL 8prädikative P. 5problemorientierte P. 6PROLOG 5prozedurale P. 5SCHEME 5SMALLTALK 5Sprachenfamilie 5SQL 5Programmierstil 13Programmiertechnik 13Programmierumgebung 33Programmquelle 2PROLOG 5Pro nescia 24Public Member 110Quasar-Toolkit 124Quellco<strong>de</strong> 11Qu<strong>in</strong>e 172r-Wert 64rand(3C) 144random(3M) 144ranlib 25read 38, 69read(2) 104realloc(3) 158Referenzebene 61referenzieren 57, 68register (C) 62Rekursion 96relozierbar 12reserviertes Wort 48return (C) 78Revision Control System 28Richtl<strong>in</strong>ien (C) 13Rienne-Vaplus, Höhle von R. 23rlog (RCS) 29robust 12Rückgabewert 78, 82, 138Rundungsfehler 52sarge 232scanf 70scanf(3) 104, 204SCHEME 5Schleife (C) 75Schleife, abweisen<strong>de</strong> 75Schleife, nichtabweisen<strong>de</strong> 75Schleifenzähler 77Schlüsselwort 34, 46, 48Schlüsselwort 198sdb 23Seed 145Sequenz 74Shared Library 19shift (C) 68short (C) 51Signal (Qt) 124S<strong>in</strong>gle UNIX Specification 137size 45sizeof-Operator 71Skalarprodukt 120Slapper 232Slot 124small (Speichermo<strong>de</strong>ll) 108SMALLTALK 5, 10, 48Software Configuration Management 33Software Eng<strong>in</strong>eer<strong>in</strong>g 13Source Co<strong>de</strong> Control System 33Speicherdynamische Verwaltung 158Register 62Segmentierung 108Speichermo<strong>de</strong>ll 19, 108Speicherbedarf 50Speicherklasse (C)auto 62, 64extern 62register 62static 62, 64Speicherplatz (C) 49spl<strong>in</strong>t 20Sprung (C) 77srand(3C) 144srandom(3M) 144Standard-C-Bibliothek 103Standard-Mathematik-Bibliothek 105Standardbibliothek 103, 108Standard Template Library 117


256 SACHVERZEICHNISstat 38static (C) 62, 145statische B<strong>in</strong>dung 12stdio.h 104, 130, 144stdlib.h 144str<strong>in</strong>g 38Str<strong>in</strong>g 54, 58, 157Str<strong>in</strong>g-Deskriptor 36str<strong>in</strong>g.h 104Str<strong>in</strong>gfunktion 104str<strong>in</strong>gs 28, 45strip 45strncmp 38struct (C) 54Structured Query Language 5StrukturDatenstruktur 16, 49Programmstruktur 15, 16Strukturverweis (C) 68Subarray 119switch (C) 74Syntax-Diagramm 46Syntax-Prüfer 20sys/stat.h 38Systemaufruf 34, 104, 196Target (make) 21Template 117term<strong>in</strong>fo(4) 141Tex<strong>in</strong>fo 137Textfile 46time 24, 35, 45time(2) 144time.h 144times 25t<strong>in</strong>y (Speichermo<strong>de</strong>ll) 108Token 46Top-down-Entwurf 15TreiberCompilertreiber 19Trennzeichen (C) 46Typabstrakter Datentyp 109alphanumerischer T. 52Array 53Attribut 50Aufzählungstyp 56Bitfeld 55, 173boolescher T. 53cdotprecision 120char 52character 173cidotprecision 120cimatrix 119c<strong>in</strong>terval 118civector 119cmatrix 119complex 118const 50cvector 119dotprecision 120double 52e<strong>in</strong>facher Typ 50erklären (c<strong>de</strong>cl) 50externer T. 63float 52ganze Zahl 51Gleitkommazahl 52idotprecision 120imatrix 119<strong>in</strong>t 51<strong>in</strong>terval 118ivector 119long 51long double 52Po<strong>in</strong>ter 56real 118rmatrix 119rvector 119short 51Struktur 54T. e<strong>in</strong>es Operan<strong>de</strong>n 49, 50Typumwandlung 64, 71, 140Union 56unsigned 51void 53volatile 50zusammengesetzter T. 53type<strong>de</strong>f (C) 61types.h 38Überladung 65Übersichtlichkeit 12, 130, 140Uhr 35Umgehung 12union (C) 56unsigned (C) 51Unterprogramm 34utime 45utmp 45varargs 92Variableglobale V. 62lokale V. 62, 63register-V. 62Vere<strong>in</strong>barung 49Vererbung (Klassen) 111Vergleich 67Version 12Versionskontrolle 28Verzweigung (C) 74void (C) 53volatile (C) 50


SACHVERZEICHNIS 257Vorrang (C) 72Waterfall approach 13Wert 49Wertebereich 50Wertübergabe 82while-Schleife (C) 75who 45Widget 107, 124W<strong>in</strong>dows (Microsoft) 124woody 232Wort, reserviertes 48Wortsymbol 48write 69write(2) 104xdb 23, 44Xlib 107xstr 28Xt 107X W<strong>in</strong>dow System 124Zahlganze Z. 51Gleitkommazahl 52komplexe Z. 10, 177Primzahl 127, 150Pseudo-Zufallszahl 147Zufallszahl 144Zahlensystem 180ZeichensatzASCII 185EBCDIC 185IBM-PC 185Lat<strong>in</strong>-1 191ROMAN8 185Zeilenkommentar (<strong>C++</strong>) 48Ziel (make) 21Zirkel<strong>de</strong>f<strong>in</strong>ition 96Zirkelschluss 96Zufallszahl 144ZUSE Z22 7ZUSE Z 22 225Zuweisung 64, 73Zweierkomplement 172

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

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!