Gerd Küveler | Dietrich Schwoch Informatik für Ingenieure und Naturwissenschaftler 1
Aus dem Programm
Elektrotechnik...
98 downloads
1847 Views
2MB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
Gerd Küveler | Dietrich Schwoch Informatik für Ingenieure und Naturwissenschaftler 1
Aus dem Programm
Elektrotechnik
Elemente der angewandten Elektronik von E. Böhmer, D. Ehrhardt und W. Oberschelp Elemente der Elektronik Repetitorium und Prüfungstrainer von E. Böhmer Digitaltechnik von K. Fricke Bussysteme in der Automatisierungs- und Prozesstechnik herausgegeben von G. Schnell und B. Wiedemann Digitale Schnittstellen und Bussysteme von F. Wittgruber Automatisieren mit SPS – Theorie und Praxis von G. Wellenreuther und D. Zastrow Automatisieren mit SPS – Übersichten und Übungsaufgaben von G. Wellenreuther und D. Zastrow Steuerungstechnik mit SPS von G. Wellenreuther und D. Zastrow Lösungsbuch Steuerungstechnik mit SPS von G. Wellenreuther und D. Zastrow Mikroprozessortechnik von K. Wüst Elektronik von D. Zastrow Elektrotechnik von D. Zastrow Aufgabensammlung Elektrotechnik 1 und 2 von M. Vömel und D. Zastrow Bussysteme in der Fahrzeugtechnik von W. Zimmerman und R. Schmidtgall
www.viewegteubner.de
Gerd Küveler | Dietrich Schwoch
Informatik für Ingenieure und Naturwissenschaftler 1 Grundlagen, Programmieren mit C/C++, Großes C/C++-Praktikum 6. Auflage STUDIUM
Bibliografische Information der Deutschen Nationalbibliothek Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über abrufbar.
1. Auflage 1996 2., vollständig überarbeitete Auflage 1999 3., vollständig überarbeitete und erweiterte Auflage 2001 4., durchgesehene und erweiterte Auflage 2003 5., vollständig überarbeitete und aktualisierte Auflage 2006 6. Auflage 2009 Alle Rechte vorbehalten © Vieweg +Teubner | GWV Fachverlage GmbH, Wiesbaden 2009 Lektorat: Reinhard Dapper | Andrea Broßler Vieweg+Teubner ist Teil der Fachverlagsgruppe Springer Science+Business Media. www.viewegteubner.de Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Jede Verwertung außerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung des Verlags unzulässig und strafbar. Das gilt insbesondere für Vervielfältigungen, Übersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronischen Systemen. Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. in diesem Werk berechtigt auch ohne besondere Kennzeichnung nicht zu der Annahme, dass solche Namen im Sinne der Warenzeichen- und Markenschutz-Gesetzgebung als frei zu betrachten wären und daher von jedermann benutzt werden dürften. Umschlaggestaltung: KünkelLopka Medienentwicklung, Heidelberg Druck und buchbinderische Verarbeitung: Krips b.v., Meppel Gedruckt auf säurefreiem und chlorfrei gebleichtem Papier. Printed in the Netherlands ISBN 978-3-8348-0460-0
Vorwort Informatik für Ingenieure und Naturwissenschaftler erscheint in zweibändiger Form. Das eröffnet zum einen die Möglichkeit zu größerer Ausführlichkeit, zum anderen ist der Leser nicht gezwungen, viele Seiten zu erwerben, die ihn persönlich nicht interessieren. Der erste Band führt in die Hochsprachen-Programmierung ein. Nicht zufällig wurde als Sprache C/C++ gewählt, weil sie sich im Laufe der letzten Jahre zu bedeutendsten Universalsprache mit breitestem Anwendungsspektrum entwickelt hat. Der zweite Band beschäftigt sich schwerpunktmäßig mit PC-Technik und Computernetzen. Die hier vorliegende erste Band entspricht inhaltlich einer zweisemestrigen Einführung in die Informatik für Ingenieurstudenten oder Studenten der Naturwissenschaften. Der Stundenumfang wird dabei mit insgesamt 4 Semesterwochenstunden Vorlesung und ebenso vielen Übungen angenommen. Der Text erlaubt jedoch durchaus auch ein Selbststudium. Teil I bietet einen kurzen Überblick über die technische Informatik. Nach dieser Einstimmung geht es dann mit Teil II richtig los: Ab hier setzen wir den Zugang zu einem PC mit C++-Compiler voraus. Die Einführung ist zwar systematisch aber dennoch sehr praxisnah angelegt, d. h. der Leser erhält die Gelegenheit, das Gelernte komplett nachzuvollziehen. Aus diesem Grund ergänzen zahlreiche Übungsaufgaben die einzelnen Kapitel. Vor allem aber der Teil III mit seinen Praktikumsaufgaben macht aus jedem Leser einen brauchbaren C-Programmierer, zumindest wenn er sich durch die nicht immer ganz einfachen Aufgaben „kämpft“. Um gelegentlichen Frust zu vermeiden, haben wir für sämtliche Praktikumsaufgaben die Komplettlösungen angegeben. Diese Aufgaben sollten Sie lernbegleitend zu Teil II lösen. Die Sprache C/C++ ist nicht nur Selbstzweck, sondern eröffnet einen fundierten Zugang zu anderen Spezialsprachen im technisch-wissenschaftlichen Bereich, wie etwa LabVIEW. Java, nicht nur für Web-Anwendungen interessant, basiert auf C++. Aber selbst zu komplexen Anwendungsprogrammen bzw. Tools wie Excel, MATLAB und Simulink oder Mathematica findet man als geübter Programmierer leichteren Zugang. Die Quelltexte der im Buch abgedruckten Programme, die Lösungen zu den Übungsaufgaben sowie eventuelle aktuelle Ergänzungen und Fehlerkorrekturen finden Sie im Internet unter http://r5.mnd.fh-wiesbaden.de/infobuch Sie haben dort auch die Möglichkeit, uns eine E-Mail zu schicken. Über Hinweise auf Fehler, Anregungen und Kritiken würden wir uns freuen. Unser Dank gilt allen, die einen Beitrag zu diesem Buches geleistet haben. Viele Anregungen und Hinweise auf Fehler in den vorherigen Auflagen stammen von Studenten und Kollegen, denen wir hiermit ebenfalls danken. Glashütten, im Februar 2009
Gerd Küveler
Dieburg, im Februar 2009
Dietrich Schwoch
Inhaltsverzeichnis
I Grundlagen.............................................................................................................................1 1 Grundprinzipien der Datenverarbeitung ..................................................................................2 1.1 Historische Entwicklung der Datenverarbeitung ..............................................................2 1.1.1 Von A wie Abakus bis Z wie Zuse ........................................................................2 1.1.2 Die Rechnergenerationen .......................................................................................3 1.1.3 Computer und Science Fiction ................................................................................5 1.2 Funktion und Aufbau eines Rechners...............................................................................6 1.3 Aufgaben ........................................................................................................................10 2 Das Betriebssystem................................................................................................................11 2.1 Single- und Multitasking ................................................................................................11 2.2 Dateien und Dateisysteme ..............................................................................................15 3 Algorithmen und Struktogramme ..........................................................................................18 3.1 Algorithmen....................................................................................................................18 3.2 Struktogramme ...............................................................................................................18 3.3 Aufgaben ........................................................................................................................25 4 Programmiersprachen............................................................................................................26 4.1 Maschinen- und Hochsprachen.......................................................................................26 4.2 Die Hochsprachen-Programmentwicklung.....................................................................29 II Programmieren in C/C++ ..................................................................................................31 5 Über C und C++ ....................................................................................................................32 6 Grundlagen ............................................................................................................................33 6.1 Einführende Beispiele.....................................................................................................33 6.2 Anweisungen, Wertzuweisungen und Datentypen .........................................................35 6.3 Der Aufbau eines C++-Programms ................................................................................37 6.3.1 Die Bausteine der Sprache ...................................................................................37 6.3.2 Der Blockaufbau eines Programms......................................................................39 6.3.3 Separationszeichen...............................................................................................41 6.3.4 Kommentare.........................................................................................................41 6.3.5 Die Freiheit der äußeren Form .............................................................................42
1.1 Historische Entwicklung der Datenverarbeitung
VII
6.4 Fehler.............................................................................................................................. 43 6.4.1 Syntaxfehler ......................................................................................................... 43 6.4.2 Laufzeitfehler....................................................................................................... 43 6.4.3 Logische Fehler.................................................................................................... 44 6.5 Die Entwicklung von C/C++-Programmen .................................................................... 45 6.6 Aufgaben ........................................................................................................................ 46 7 Vordefinierte Standard-Datentypen....................................................................................... 47 7.1 Der Umgang mit Zahlen ................................................................................................. 47 7.1.1 Ein wesentlicher Unterschied: int oder float ........................................................ 47 7.1.2 Ganzzahlige Datentypen ...................................................................................... 49 7.1.3 Reelle Datentypen................................................................................................ 54 7.1.4 Standardfunktionen mit Zahlen............................................................................ 57 7.2 Verarbeitung von Einzelzeichen: Der Datentyp char ..................................................... 59 7.2.1 Der Umgang mit der ASCII-Tabelle.................................................................... 60 7.2.2 Standardfunktionen mit char ................................................................................ 63 7.3 Logische Ausdrücke ....................................................................................................... 64 7.4 Operatoren und Ausdrücke............................................................................................. 67 7.5 Benutzerdefinierte Konstanten ....................................................................................... 73 7.6 Aufgaben ........................................................................................................................ 74 8 Interaktive Ein-/Ausgabe....................................................................................................... 76 8.1 Standard Ein-/Ausgabe mit C++..................................................................................... 76 8.2 Formatierte Bildschirm-Ausgabe ................................................................................... 82 8.3 Standard-Eingabe ........................................................................................................... 84 8.4 Standard Ein-/Ausgabe mit C ......................................................................................... 87 8.5 Aufgaben ........................................................................................................................ 91 9 Programm-Ablaufstrukturen.................................................................................................. 93 9.1 Die Selektion .................................................................................................................. 93 9.1.1 Die einseitige Verzweigung: if ............................................................................. 93 9.1.2 Die Alternative: if ... else ..................................................................................... 95 9.1.3 Die Mehrfach-Fallunterscheidung: switch ... ....................................................... 96 9.2 Die Iteration.................................................................................................................... 99 9.2.1 Die Zählschleife: for ... ...................................................................................... 100 9.2.2 Bedingungsschleifen .......................................................................................... 103 9.3 Die Schachtelung von Kontrollstrukturen .................................................................... 112 9.4 Aufgaben ...................................................................................................................... 115
VIII
Inhaltsverzeichnis
10 Modularisierung von Programmen: Functions ..................................................................121 10.1 Vereinbarungen von Functions .................................................................................123 10.2 Der Aufbau von Funktionen .....................................................................................126 10.3 Die Parameterübergabe .............................................................................................128 10.4 Die return-Anweisung...............................................................................................133 10.5 Der Geltungsbereich von Vereinbarungen................................................................135 10.6 Rekursionen ..............................................................................................................138 10.7 Aufgaben...................................................................................................................141 11 Höhere Datenstrukturen.....................................................................................................143 11.1 Felder ........................................................................................................................143 11.1.1 Eindimensionale Felder................................................................................143 11.1.2 Mehrdimensionale Felder.............................................................................152 11.1.3 Zeichenketten: Strings..................................................................................153 11.1.4 Initialisierung von Feldern ...........................................................................158 11.2 Pointer.......................................................................................................................160 11.2.1 Pointer und Felder ........................................................................................162 11.2.2 Dynamische Speicherverwaltung .................................................................164 11.3 Datenverbunde: Strukturen .......................................................................................167 11.3.1 Übergabe von Strukturen an Funktionen......................................................171 11.3.2 Struktur-Pointer............................................................................................172 11.3.3 Der typedef-Operator ...................................................................................174 11.4 Aufgaben...................................................................................................................175 12 Arbeiten mit Dateien .........................................................................................................177 12.1 ASCII-Dateien: Der Dateityp Text ...........................................................................179 12.2 Binärdateien ..............................................................................................................183 12.3 Aufgaben...................................................................................................................187 13 Einführung in die OOP mit C++........................................................................................189 13.1 Klassen......................................................................................................................189 13.2 Der ObjektOrientierte Ansatz....................................................................................193 13.3 Konstruktoren und Destruktoren...............................................................................194 13.4 Dateiorganisation ......................................................................................................201 13.5 Friend Funktionen und -Klassen ...............................................................................204 13.6 Überladen von Funktionen........................................................................................206 13.7 Überladen von Operatoren ........................................................................................209 13.8 Der this-Zeiger ..........................................................................................................222 13.9 Übergabe von Objekten an Funktionen.....................................................................224
1.1 Historische Entwicklung der Datenverarbeitung
IX
13.10 Dynamischer Speicher und Klassen........................................................................ 228 13.11 Vererbung................................................................................................................ 232 13.12 Schrittweise Entwicklung eines einfachen OOP-Projektes..................................... 237 13.12.1 Definition einer Klasse „TIME"............................................................... 237 13.12.2 Definition der Methoden außerhalb der Klassendefinition....................... 238 13.12.3 Konstruktoren und die Überladung des +-Operators................................ 240 13.12.4 Zusätzliche Überladung für Ein- und Ausgaben....................................... 241 13.13 Abschlussbemerkungen........................................................................................... 245 13.14 Aufgaben................................................................................................................. 245 III C/C++ Praktikum ........................................................................................................... 247 14 Einführungs-Praktikum ..................................................................................................... 248 14.1 Erstes Praktikum ....................................................................................................... 248 14.2 Zweites Praktikum .................................................................................................... 249 14.3 Drittes Praktikum...................................................................................................... 250 14.4 Viertes Praktikum ..................................................................................................... 252 14.5 Fünftes Praktikum..................................................................................................... 253 14.6 Sechstes Praktikum ................................................................................................... 254 14.7 Siebentes Praktikum ................................................................................................. 255 14.8 Achtes Praktikum...................................................................................................... 256 14.9 Praktischer Programmiertest..................................................................................... 259 15 Fortgeschrittenen-Praktikum ............................................................................................. 261 15.1 Erstes Praktikum ....................................................................................................... 261 15.2 Zweites Praktikum .................................................................................................... 262 15.3 Drittes Praktikum...................................................................................................... 264 15.4 Viertes Praktikum ..................................................................................................... 266 15.5 Fünftes Praktikum..................................................................................................... 267 15.6 Sechstes Praktikum ................................................................................................... 267 15.7 Siebentes Praktikum ................................................................................................. 269 15.8 Achtes Praktikum...................................................................................................... 271 15.9 Neuntes Praktikum.................................................................................................... 272 16 Lösungen zum Einführungs-Praktikum............................................................................. 275 16.1 Lösungen zum ersten Praktikum............................................................................... 275 16.2 Lösungen zum zweiten Praktikum............................................................................ 276 16.3 Lösungen zum dritten Praktikum.............................................................................. 279 16.4 Lösungen zum vierten Praktikum ............................................................................. 282
X
Inhaltsverzeichnis 16.5 Lösungen zum fünften Praktikum.............................................................................284 16.6 Lösungen zum sechsten Praktikum...........................................................................287 16.7 Lösungen zum siebenten Praktikum .........................................................................288 16.8 Lösungen zum achten Praktikum ..............................................................................291 16.9 Lösung zum praktischen Programmiertest................................................................296
17 Lösungen zum Fortgeschrittenen-Praktikum.....................................................................298 17.1 Lösung zum ersten Praktikum...................................................................................298 17.2 Lösung zum zweiten Praktikum................................................................................300 17.3 Lösung zum dritten Praktikum..................................................................................303 17.4 Lösung zum vierten Praktikum .................................................................................305 17.5 Lösung zum fünften Praktikum.................................................................................307 17.6 Lösung zum sechsten Praktikum...............................................................................311 17.7 Lösung zum siebten Praktikum.................................................................................316 17.8 Lösung zum achten Praktikum..................................................................................319 17.9 Lösung zum neunten Praktikum................................................................................325 Anhang A: ASCII-Tabelle.......................................................................................................330 Anhang B: Häufige Fehler.......................................................................................................331 Sachwortverzeichnis................................................................................................................333
I Grundlagen In diesem Teil geht es darum, einen Überblick über wichtige Grundlagen der technischen Informatik zu vermitteln, die wir später ausführlich behandeln. Dabei fangen wir zwar im wahrsten Sinne des Wortes bei (Adam und) EVA an, stellen uns aber dennoch einen Leser vor, für den Computer selbstverständliche Gegenstände seiner Umgebung darstellen wie Autos und Fernsehgeräte. So werden Sie wissen, dass ein PC mindestens über eine Zentraleinheit, ein Bildschirmgerät und eine Tastatur verfügt. Wahrscheinlich haben Sie Computerspiele gespielt, mit Office-Software wie Word, Excel oder Power Point gearbeitet, CDs gebrannt und wissen, was eine Datei ist. Auch der Umgang mit Windows dürfte Ihnen vertraut sein. Wenn nicht, wird es höchste Zeit, Computererfahrungen zu sammeln. Doch selbst wenn Sie ein geübter Computeranwender sind, sollten Sie diese kleine Einführung lesen (es sind ja nur 30 Seiten), denn sie wird auch Ihnen einiges Neue zu bieten haben.
1 Grundprinzipien der Datenverarbeitung Datenverarbeitung (DV) wird nicht erst seit Einführung des Computers betrieben. Das menschliche Gehirn kann offensichtlich auch ohne technische Hilfsmittel Daten verarbeiten. Beispiel Kopfrechenaufgabe: addiere 3 zu 2 Untergliederung in 3 Schritte 1. Aufnehmen der Daten mit unseren Sinnen 2. Verarbeiten der Daten im Gehirn 3. Mitteilen des Ergebnisses durch Wort oder Schrift
Hieraus leitet sich das Hauptprinzip der DV ab: E i
V e
A u
n
r
s
g
a
g
a
r
a
b
b
b
e
e
e
i t u n g Dieses „EVA“-Prinzip liegt allen klassischen technischen DV-Anlagen zugrunde.
1.1 Historische Entwicklung der Datenverarbeitung Der moderne Allzweckrechner entwickelte sich erst nach Ende des Zweiten Weltkrieges. Trotzdem hat er eine lange Vorgeschichte. Bei den elektronischen Rechnern haben technologische Entwicklungssprünge zu den verschiedenen Computergenerationen geführt.
1.1.1 Von A wie Abakus bis Z wie Zuse Die technische Geschichte der Rechenmaschinen weist folgende Meilensteine auf: ca. 1000 v. Chr.
Abakus (= Rechenbrett, Rechentafel) x Speicherfunktion x Rechenfunktion: Addition und Subtraktion x noch heute meistbenutzte „Rechenmaschine“ der Welt (?)
1.1 Historische Entwicklung der Datenverarbeitung 1623
1642 1672 1833
1886
1941
3
Schickard’sche Rechenmaschine x Zahnradgetriebe: 10 Räder mit je 10 Zähnen x Stellenwertübertrag wie beim Kilometerzähler x Addition und Subtraktion Pascalsche Rechenmaschine x Prinzip wie bei Schickard, jedoch mit verbesserter Mechanik Rechenmaschine von Leibniz x zusätzlich verschiebbare Staffelwalze zum schnellen Addieren und Multiplizieren Differenzenmaschine nach Charles Babbage x Babbage entwarf das Konzept eines programmierbaren Universalrechners mit Zahlenspeicher, Rechenwerk, Leitwerk sowie Ein- und Ausgabeeinheiten. Programmierung mit Lochkarten nach dem Vorbild der automatischen Webstühle nach Jacquard (um 1800). Babbages „Analytical Engine“ konnte nicht gebaut werden, da bis zu 25 Zahnräder ineinander greifen mussten, was damals mechanisch noch nicht lösbar war. 1991 wurde sie jedoch erfolgreich nachgebaut. x sehr wichtig für die Theorie des Computers! Papplochkarte nach Hermann Hollerith x Einsatz zur Auswertung der 11. amerikanischen Volkszählung x Format einer 1-Dollar-Note x Hollerith gründete 1896 die Tabulating Machine Company. Fusionen führten 1924 zur IBM. Z3 nach Konrad Zuse x erster programmierbarer Computer der Welt x Schaltelemente waren Relais. x 1944 das amerikanische Gegenstück Mark I nach Howard Aikens
1.1.2 Die Rechnergenerationen Die im zweiten Weltkrieg entwickelten Rechner werden heute der Vorgeneration zugerechnet (bis 1946). In Deutschland „Z3“ (Konrad Zuse, 1941) Anzahl der Additionen pro Sekunde: Anzahl der Multiplikationen pro Sekunde:
20 15
In Amerika „Mark1“ (Howard Aikens, 1944) Anzahl der Additionen pro Sekunde: Anzahl der Multiplikationen pro Sekunde:
3 0.16
Für die Entwicklung an der Z4 gründete Konrad Zuse noch während des Krieges die erste Computerfirma der Welt. Das Kernteam bestand aus einem Konstrukteur, frisch aus der Nervenheilanstalt, einem blinden Programmierer und einem vorbestraften Buchhalter.
4
1 Grundprinzipien der Datenverarbeitung
Übersicht über die Rechnergenerationen
Generation
Hardwarebeispiele
Technologien
Speicherkapazität/ Verarbeitungsgeschwindigkeit
Software: Sprache/ Betriebssystem
1. 1946–1958
ENIAC Z22 (Zuse) UNIVAC IBM 650 SIEMENS 704 IBM 1400 AEG TR CDC 6600 SIEMENS-2002
Elektronenröhren
0.02 MIPS/
Maschinensprache/ _________
IBM /370 DEC PDP-11 SIEMENS-7000 Cray 1 PC Cray XMP Sperry 1100 IBM 309x DEC VAX Workstations Hochleistungs-PC
ICs
5 MIPS/
Halbleiterspeicher Mikroprozessoren Optische Speicher
1–2 MB
Mehr-KernCPU ComputerNetze
1 000 MIPS GB
Nanocomputer Quantencomputer
supraleitende Keramiken, Nanotechnik
> 10 000 MIPS viele TB
2. 1959–1964
3. 1965–1980
4. 1981–heute
Gegenwart
5. Entwicklung der Zukunft Abkürzungen
1–2 KB Trommelspeicher Transistoren
0.1 MIPS/
Kernspeicher
32 KB
50 MIPS/
Assembler, FORTRAN/ Stapelverarb./ Mehrprogrammbetrieb div. Hochsprachen: C, Pascal, .../ Multiuserdialog Sprachen der 4. Generation
8–32 MB CodeParallelisierung Netzsoftware, Objektorientierte Sprachen: C++, LabVIEW/UNIX/ Linux Windows XP ?
MIPS = Megainstructions per Second (Millionen Befehle pro Sekunde) KB
= Kilobyte (210 Byte = 1.024 Byte, o siehe Band 2, Teil I)
MB
= Megabyte (220 Byte = 1.048.576 Byte)
GB
= Gigabyte (230 Byte = 1.073.741.824 Byte)
TB
= Terabyte (240 Byte = 1.099.511.627.776 Byte)
PB
= Petabyte (250 Byte = 1.125.899.906.842.624 Byte)
EB
= Exabyte (260 Byte = 1.152.921.504.606.846.976 Byte)
1.1 Historische Entwicklung der Datenverarbeitung
5
1.1.3 Computer und Science Fiction Der erste Großrechner der Welt hieß ENIAC (1946). Dieses Monstrum mit 18 000 Röhren wog nicht weniger als 30 Tonnen. Er konkurrierte noch mit Relaisrechnern wie der Z5, die zwar langsamer, aber zuverlässiger waren. Die Autoren von Zukunftsromanen glaubten damals mit Recht, dass es bald immer bessere Computer geben würde. In einem wichtigen Punkt allerdings irrten sie: Je leistungsfähiger ein Rechner, umso größer muss er wohl sein, so dachten sie. Clifford D. Simak veröffentlichte 1949 die Geschichte „An der Grenze“. Die Hauptrolle spielte ein Computer, der so groß ist wie die ganze Erde. Noch 1966 hieß ein anderer Science Fiction Computer „Colossus“, auch ein Riese, wie schon sein Name verrät (verfilmt als „Colossus: The Forbin Projekt“, USA 1969). Die Wirklichkeit kam ganz anders: mit rasantem Tempo wurden die Computer immer besser und schneller. Dabei nahm ihre Größe nicht zu, sondern ab. Der Grund: immer kleinere und schnellere Bauteile wurden erfunden. Die Erfindung des Transistors und später des Chips (IC) revolutionierte die Elektronik. Kein Science Fiction Autor hat diese Entwicklung, die durch die Raumfahrt, vor allem das Mondlande-Projekt, forciert wurde, vorausgeahnt. Mehr Glück hatten sie mit den Robotern. Science Fiction Autoren haben sogar interessante Beiträge zur Robotergeschichte geleistet. Im Jahre 1922 erschien in Prag das Theaterstück „WUR“. Karel ýapek, der Autor, ist der Urheber der Bezeichnung „Roboter“, denn WUR bedeutet „Werstands Universal Robots“ und handelt von einer Fabrik, die massenweise Roboter herstellt. Den Titel „Miss Robot“ verdient bis heute das elegante Metallgeschöpf aus dem Fritz LangFilm „Metropolis“ (D 1927) nach dem Drehbuch Thea von Harbous. Der Traum von künstlicheren Helfern ist jedoch viel älter. An eine alte Sage aus dem jüdischen Prag knüpft der Roman „Der Golem“ von Gustav Meyrink (1915) an. Hundert Jahre zuvor erschien in den „Nachtstücken“ von E.T.A. Hoffmann (1815) die Geschichte „Der Sandmann“. Dort tritt ein menschenähnlicher Automat, die Puppe Olimpia, auf. Sie spielt auch in der Jacques-Offenbach-Oper „Hoffmanns Erzählungen“ eine Hauptrolle. Um 1900 hielten die Maschinenmenschen auch Einzug in die triviale Unterhaltungsliteratur. Ein Beispiel ist der Roman von John Merriman „Die künstlichen Menschen“ aus der fünfbändigen Reihe „Thomas Alva Edison der große Erfinder“ (1908). Einen sehr interessanten Beitrag zur Roboterforschung leistete der amerikanische Schriftsteller Isaac Asimov, der 1940 in seiner Zukunftserzählung „Ich, der Robot“ seine drei Robotergesetze aufstellte: 1.
Ein Roboter darf einen Menschen nicht verletzen oder durch Untätigkeit zulassen, dass ein Mensch zu Schaden kommt.
2.
Ein Roboter muss den Befehlen gehorchen, die er von Menschen erhalten hat, mit Ausnahme solcher Befehle, die zu dem ersten Gesetz in Widerspruch stehen.
3.
Ein Roboter muss seine eigene Existenz schützen, solange dieses nicht zu dem ersten oder zweiten Gesetz im Widerspruch steht.
Vor allem das 1. Gesetz ist in der Praxis schwer umzusetzen, da es keine absolut sicheren technischen Systeme gibt. Menschen sind bereits Opfer von Unfällen mit Industrierobotern geworden. Außerdem haben die Schriftsteller sich wieder geirrt: die echten Roboter sehen nicht menschenähnlich aus. Solche Roboter wurden bisher nur für Ausstellungen oder als
6
1 Grundprinzipien der Datenverarbeitung
Spielzeuge gebaut. Roboter, wie sie heute viel tausendfach in der Industrie eingesetzt werden, gleichen eher riesenhaften Armen. Gebaut werden sie für spezielle Aufgaben, z. B. schweißen sie Karosserieteile in Autofabriken zusammen. Herz und Hirn eines realen Roboters ist ein kleiner Mikrocomputer mit einem Steuerungsprogramm. Spezielle „Sensoren“ erlauben es dem Roboter, zu „fühlen“ oder gar zu „sehen“, je nach seiner Aufgabe. Das Programm wertet alles aus. Es erteilt dann die notwendigen Befehle an die „Aktoren“. Solche Aktoren bewegen z. B. eine „Eisenhand“ mit einem Lackiergerät für Autos. Fazit
Nur selten gelingt es, Entwicklungen einigermaßen zutreffend vorherzusehen. Weder Wissenschaftler, noch Schriftsteller oder Politiker sind auf diesem Gebiet sonderlich erfolgreich. Forschung lässt sich nur in begrenztem Maße sinnvoll planen: was heute sonnenklar erscheint, kann morgen Schnee von gestern sein.
Die Vorstellung von beseelten Computern und menschenähnlichen Robotern hat bis heute nichts von ihrer Faszination eingebüßt. Und so entstehen immer noch Bücher und vor allem äußerst erfolgreiche Filme zu diesen Themen. Herausragend sind „2001 – Odyssee im Weltall“ (E 1968, menschlich fühlender Computer) und „Bladerunner“ (USA 1982, dürfen wir denkende und fühlende Androiden als Sklaven halten?). Glauben wir Filmen wie „Welt am Draht“ (D 1973) oder „The Matrix“ (USA 1999), so sind wir selbst nur Teil einer Computersimulation einer höheren Intelligenz.
1.2 Funktion und Aufbau eines Rechners Ab Mitte der 40er Jahre entwickelte John von Neumann ein theoretisches Rechnermodell. Seine Vorschläge (Entwicklung und Ausnutzung neuerer mathematischer Maschinen, 1954) lauteten: x
Rechner sollen nicht mehr von „außen“ mit Lochstreifen gesteuert werden, sondern die Programmbefehle sind wie Daten in den Zentralspeicher zu laden (Geschwindigkeitsvorteile),
x
Einführung bedingter Befehle (wenn A > 0 dann ...), damit höhere Flexibilität
Von Neumann stellte folgendes, bis heute gültiges Modell eines einfachen Rechners auf, das ebenfalls das EVA-Prinzip widerspiegelt. In aktualisierter Form lässt es sich so schematisieren: (s. folgende Seite) Dieses Modell gilt für alle sequentiell arbeitenden Computer. Das sind Rechner, die ein Programm der Reihe nach, Schritt für Schritt, abarbeiten. Dazu gehören, mit Modifikationen, auch PC. Am Beispiel eines PC kann man sich veranschaulichen, welche Komponenten den Funktionsblöcken des von-Neumann-Modells entsprechen (o siehe Übungsaufgaben 1.3). So genannte Parallelrechner, die mehrere Prozessoren besitzen, entsprechen nicht mehr dem vonNeumann-Prinzip. Mit dem Pentium entwickelt sich auch der PC immer mehr in Richtung Parallelarchitektur. Auf diese speziellen Rechner soll hier jedoch nicht näher eingegangen werden. Wir wollen nun die Zentraleinheit eines „einfachen“ Rechners gewissermaßen unter der Lupe betrachten.
1.2 Funktion und Aufbau eines Rechners
7
Von-Neumannsches-Rechnermodell
Ein Prozessor – heute meist als Mikroprozessor realisiert – besitzt neben Leit- und Rechenwerk noch einige Register, sozusagen als „Privatspeicher“. Gemäß dem von-Neumann-Modell werden sowohl das Programm als auch die zu verarbeitenden Daten in den Zentralspeicher geladen. Der Prozessor hat über ein System von Leitungen, den Bus, Zugriff auf diesen Speicher. Weil der Computer ein digital arbeitender Automat ist, sind alle Programmbefehle (Maschinenbefehle) binär codiert, d. h. sie bestehen aus Folgen von Nullen und Einsen. Im 2. Band werden wir näher darauf eingehen. Das Programm wird sequentiell, Maschinenbefehl für Maschinenbefehl, vom Leitwerk interpretiert und ausgeführt. Bei arithmetischen und logischen Operationen zieht es das Rechenwerk zu Hilfe. Dieses wiederum ist beispielsweise in der Lage, zwei Daten zu addieren. Im Allgemeinen müssen diese zuvor vom Zentralspeicher über den Datenbus in die Datenregister transportiert werden. Das Ergebnis kann später auf dem gleichen Weg zurück in den Speicher gebracht werden.
8
1 Grundprinzipien der Datenverarbeitung
Einfaches Modell der Zentraleinheit
Den Zentralspeicher kann man sich als ein „überhohes“ Schubladenelement vorstellen, dessen einzelne Schubladen Daten oder Programmbefehle enthalten können. Jede „Schublade“ (jeder Speicherplatz) wird über seine numerische Adresse angesprochen. Das geschieht per Adressbus. Ein Speicherplatz kann 1 Byte (8 Bit) aufnehmen. Längere „Worte“ belegen mehrere Speicherplätze, typischerweise 16, 32 oder 64 Bit, entsprechend 2, 4 oder 8 Byte. Das Byte (damals noch 6 Bit lang und „Bite“ geschrieben) wurde 1956 von der Firma IBM als Standard für die kleinste adressierbare Speichereinheit eingeführt. Das Programm wird mit Hilfe des Programmschrittzählers verwaltet. Dieses spezielle Steuerregister enthält stets die Speicheradresse, unter welcher der Maschinenbefehl zu finden ist, der als nächster vom Leitwerk ausgeführt werden muss. Zur Speicherung des augenblicklichen Prozessorzustands dient das Zustands- oder Flagregister (Flag = Flagge). Die einzelnen Flags zeigen an, ob beispielsweise das Ergebnis der letzen arithmetischen Operation Null ergab (Zero Flag), oder ob ein arithmetischer Übertrag notwendig ist, weil das „zu große“ Ergebnis nicht vollständig in ein Datenregister passt (Carry Flag). Einige Prozessoren besitzen weitere Steuerregister. Ein PC, wie er am Arbeitsplatz oder zu Hause steht, ist heute typischerweise so konfiguriert:
1.2 Funktion und Aufbau eines Rechners
9
x
Motherboard mit Intel- oder AMD-Prozessor, 1–4 GB RAM-Speicher
x
PCI-Bus
x
100 bis 1000 GB-Festplatte; CDRW/DVD-Laufwerk, nur noch selten Diskettenlaufwerk
x
Tastatur; Maus; evtl. Scanner
x
Tintenstrahl- oder Laserdrucker
x
19"–22" LCD-Flachbildschirm (TFT Monitor)
x
Soundkarte mit Lautsprechern
x
Internet-Zugang über Netzwerk-Karte (100 MBit) + DSL-Modem (digital, Breitband), nur noch selten Modem (analog) oder ISDN-Karte (digital)
x
ggf. Netzwerkkarte für Intranet-Zugang
x
diverse Schnittstellen (USB, Firewire; eher selten noch V.24, PS/2, Parallel)
Alle externen Einheiten sind über Schnittstellen mit der Zentraleinheit verbunden. Der Drucker ist meist über die USB- oder, bei älteren Rechnern, die parallele (Centronics-) Schnittstelle angebunden, die Maus über die PS/2- oder USB-Schnittstelle. Für Bildschirm, Tastatur und externe Speicher existieren spezielle Schnittstellen. Wer heute einen Computer erwirbt, wird sich in der Regel nicht mit der bloßen Hardware zufrieden geben. Wenn der Computer ein „IBM-kompatibler“ PC ist, ist das Betriebssystem, meist eine der Windows-Varianten, häufig vorinstalliert. Erst ein solches Betriebssystem macht für den Normalkunden einen Allzweckrechner zu einem brauchbaren Hilfsmittel. Das Betriebssystem gestaltet den Umgang mit der Computerhardware komfortabel. Ohne Betriebssystem wäre das Einlesen einer Tastatureingabe eine schwierige Aufgabe für einen Spezialisten. Das Betriebssystem „vermittelt“ zwischen der Hardware und der Anwendungssoftware (Spiele, Textverarbeitung, Datenbankprogramme, selbst geschriebene Programme). Wir können somit für ein Computersystem folgendes einfache Dreischichtenmodell aufstellen: ANWENDUNGSSOFTWARE Access Word Excel Power Point selbst geschriebene Programme ... BETRIEBSSYSTEM + DOS UNIX Linux OS/2 Windows 98 Windows NT Windows 2000 Windows XP Windows Vista Windows 7
SYSTEMSOFTWARE Compiler Diverse Tools (Werkzeuge) …
10
1 Grundprinzipien der Datenverarbeitung
... HARDWARE Prozessor RAM-Speicherbausteine ROM-Speicherbaustein Controller-Bausteine Festplatte USB-Stick Bildschirm Tastatur Netzwerkkarte Maus ... Auf Betriebssysteme werden wir in Kap. 2 näher eingehen.
1.3 Aufgaben 1. Ordnen Sie die Bauteile eines modernen PC den Komponenten des von-Neumann’schenRechnermodells zu. PC Bauteil
von-Neumann-Modellkomponente
Bildschirm Tastatur Mutterplatine USB-Memory-Stick Mikroprozessor RAM-Bausteine Maus Festplatte Scanner Modem Soundkarte Joystick ROM-Speicherbaustein Drucker Netzwerkkarte CD-ROM-Laufwerk 2. Welcher seiner historischen Vorgänger beeinflusste John von Neumann offensichtlich beim Entwurf seines Rechnermodells? 3. Beschreiben Sie, welche Schritte bei der Abarbeitung eines Subtraktionsbefehls notwendig sind.
2 Das Betriebssystem In Kap. 1.2 stellten wir ein einfaches Dreischichtenmodell eines EDV-Systems vor: Zwischen Hardware und Anwendersoftware ordneten wir das Betriebssystem ein. Unter einem Betriebssystem versteht man nach DIN „diejenigen Programme eines digitalen Rechensystems, die zusammen mit den Eigenschaften der Rechenanlage die Basis der möglichen Betriebsarten des digitalen Rechensystems bilden und insbesondere die Abwicklung von Programmen steuern und überwachen“. Infolgedessen umfasst das Betriebssystem nur die Basissoftware, die es einem Benutzer der Anlage erst ermöglicht, seine eigene (Anwendungs-)Software mehr oder weniger komfortabel ablaufen zu lassen. Der durchschnittliche Benutzer eines modernen Rechners sieht sich immer seltener mit der Hardware konfrontiert, umso mehr dagegen mit dem Betriebssystem (BS). Das BS entlastet den Benutzer von Routineproblemen. Typische Aufgaben sind: x Verwalten des Zentralspeichers x Starten und Beenden von Programmen x Verwalten des peripheren Speichers (Festplatten und Disketten) x Durchführung von Ein- und Ausgabeoperationen x Bereitstellung von Dienstprogrammen (Kommandos)
2.1 Single- und Multitasking BS lassen sich grob in Singletasking- und Multitasking-Systeme unterteilen. Während erstere ein Programm komplett abarbeiten, bevor das nächste gestartet wird, unterstützen letztere die „gleichzeitige“ Ausführung mehrerer Programme. Beim kooperativen Multitasking unterbricht sich eine Anwendung selbst, um einer anderen vorübergehend den Vortritt zu lassen. Beim echten (preemtive) Multitasking ist die Verteilung der Rechenzeit auf die einzelnen Programme (genauer: Tasks oder Prozesse) Aufgabe einer Komponente des Betriebssystems, des Schedulers. Dieser teilt jedem Prozess eine Zeitscheibe zu. Ist diese abgelaufen, wird der Prozess unterbrochen, wobei alle Prozesszustände gesichert werden, und der nächste kommt an die Reihe. In der Regel sind die Zeitscheiben gleich groß, bei einigen BS lassen sich Prioritäten vergeben, die über breitere oder schmalere Zeitscheiben realisiert werden können. Wichtige Betriebssysteme:
Singletasking
Kooperatives Multitasking
Preemtive Multitasking
MS-DOS
Windows 3.1
Windows 98
div. C-Monitore
Windows 3.11
Windows NT Windows XP Windows Vista Mac OS X Leopard UNIX Linux
12
2 Das Betriebssystem
Betrachten wir zunächst das vergleichsweise einfach gestaltete Singletasking-BS MS-DOS (Microsoft Disk Operating System). Es ist zugeschnitten auf die INTEL-Prozessorlinie 80(X)86, denn es ist in der Assemblersprache dieser Prozessoren programmiert. Das wiederum hat auch Vorteile: DOS ist sehr kompakt und schnell. Wegen der starken Verbreitung der „IBM-kompatiblen“ PC wurde DOS zu einem Industriestandard (nicht genormter Standard), der jedoch mittlerweile von Windows abgelöst wurde. Da DOS für jedermann zugänglich dokumentiert, modellhaft aufgebaut und daher verhältnismäßig leicht durchschaubar ist, eignet es sich als Lehrbeispiel für ein einfaches Betriebssystem. Der Aufbau von DOS folgt einem Schichtenmodell, das sich stark abstrahiert so darstellen lässt: Anwendungen Benutzeroberfläche DOS BIOS Hardware Die oberste Schicht, die Benutzeroberfläche, ermöglicht den Zugriff auf die Dienstprogramme. Darunter versteht man Kommandos wie „copy“ (Kopiere Datei) und „del“ (Lösche Datei). Außerdem ermöglicht sie den Start eigener Anwendungen. Die übrigen genannten Aufgaben des Betriebssystems fallen den Schichten DOS und BIOS zu. Als Schnittstelle zu den Anwendungsprogrammen existieren so genannte Systemaufrufe (system calls). Unter DOS werden diese durch Softwareinterrupts realisiert. Mehr dazu erfahren Sie im Band 2. Das DOS erschließt die Rechnerhardware auf logischer Ebene, z. B. den Plattenspeicher über Dateinamen. DOS selbst bedient sich seinerseits des BIOS (Basic Input Output System), ein in jedem PC enthaltene Software, die den Hardwarezugriff auf die physikalischer Ebene ermöglicht, z. B. den Plattenspeicherzugriff über Spuren und Sektoren. Das BIOS ist somit hardwareabhängig, was dem Benutzer allerdings verborgen bleibt, solange er sich der Systemaufrufe bedient. Die klassische DOS-Benutzerschnittstelle ist Kommando-orientiert (Zeilen-orientiert): Der Benutzer tippt über die Tastatur ein Kommando ein, das anschließend abgearbeitet wird. Danach gibt der Kommando-Interpreter erneut die Eingabeaufforderung (Prompt) aus, um die Bereitschaft zur Entgegennahme des nächsten Kommandos zu signalisieren. Ebenfalls klassischerweise Kommando-orientiert ist UNIX (Universal Exchange). UNIX ist das Ergebnis des Versuchs, Betriebssysteme hardwareunabhängig (UNIX ist in C geschrieben, C wurde eigens für UNIX entwickelt) zu gestalten, d. h. ein und dasselbe Betriebsystem ist auf verschiedenen Rechnersystemen mit unterschiedlichen Prozessoren lauffähig. UNIX stellt allerdings kein „einfaches“ Betriebssystem wie DOS dar, denn es erlaubt neben Mehrprogramm- auch Mehrbenutzer-Betrieb (Multitasking/Multiuser). Wichtige Leistungen sind: x
Systemaufrufe, um Hardwarefunktionen leichter zugänglich zu machen
x
Ein hierarchisches (baumartiges) Dateiensystem (o siehe Kap. 2.2)
x
Dienstprogramme (Befehle), die man in einer Kommandozeile aufrufen (starten) kann
x
Möglichkeit der Kommandoverkettung
2.1 Single- und Multitasking
13
x
Ein-/Ausgabe-Umlenkung
x
Prozedursprache(n) zur Erstellung eigener Superkommandos.
DOS hat sich in seiner Struktur weitgehend am älteren UNIX orientiert. Die Kommandos unterscheiden sich jedoch: Beispiele für Kommandos unter DOS und UNIX
DOS
UNIX
Bedeutung
dir
ls –l
Inhaltsangabe des aktuellen Verzeichnisses
copy dat1 dat2
cp dat1 dat2
Kopiere Quelldatei dat1 auf Zieldatei dat2
type a.txt
cat a.txt
Ausgabe der Datei a.txt auf den Bildschirm
Besonders bei UNIX spielen selbst geschriebene „Super-Kommandos“, die sogenannte ShellProzeduren, eine bedeutende Rolle. Zu diesem Zweck stellt das BS eine Interpreter-Sprache zur Verfügung. Dabei werden die Programme (auch Shell-Skripte genannt) nicht in die Maschinensprache übersetzt sondern Befehl für Befehl vom BS interpretiert und ausgeführt. In eine solche Prozedur können BS-Kommandos und eigene Programme integriert werden. Dadurch lassen sich komplizierte Abläufe, wie periodische Datensicherungen nach gewünschten Kriterien, automatisieren. Shell-Prozeduren können sehr komplex und entsprechend umfangreich sein. Nachstehend eine Mini-Prozedur als Beispiel: Beispiel # Diese UNIX Shell-Prozedur laeuft so lange, bis ein existierender Dateiname # ueber die Tastatur eingegeben wird until test -f "$datei_name" do echo "Eingabe: \c" read datei_name done echo "Datei $datei_name existiert"
Von UNIX gibt es zahlreiche Varianten. Das populäre Linux ist kostenlos erhältlich und verhält sich wie UNIX. Linux ist besonders bei Hochschulen und fortgeschrittene Privatnutzer äußerst beliebt. Auf nähere Details geht unser Band 2 ein. Inzwischen haben sich Windowsoberflächen zum Standard entwickelt, zumindest in der PCWelt. Während Windows 3.11 noch einen Aufsatz auf DOS darstellt, sind Windows 98, XP und Vista eigenständige Betriebssysteme. Für UNIX und Linux existieren verschiedene Oberflächen wie X-Windows mit KDE als Alternative zu den Standardsshells (Shell = Schale (Benutzeroberfläche)). Bei den Windows-Oberflächen kommuniziert man über Fenster mit dem
14
2 Das Betriebssystem
BS und den Anwendungsprogrammen. Neben der herkömmlichen alphanumerischen Eingabe per Tastatur wird auch die grafische Eingabe, meist per Maus, unterstützt. Fenster können geöffnet, vergrößert, verkleinert (bis auf Icon-Größe), verschoben und wieder geschlossen werden. Zusammengehörende Gruppen von Funktionen werden anwendungsbezogen über Menüs (starr, pulldown oder popup) ausgewählt. Vor- und Nachteile von Windows-Oberflächen Vorteile – einheitliche Benutzerschnittstelle für alle Programme – standardisierte Zwischenablage (clipboard) für den Datenaustausch zwischen verschiedenen Programmen Nachteile – starke Inanspruchnahme von Prozessorleistung, Haupt- und Plattenspeicher – keine Shellprozeduren zur Automatisierung wiederkehrender komplizierter Abläufe Windows 98, 2000, NT, XP und Vista sind 32-Bit-Betriebssysteme, welche die Leistungsfähigkeit der Intel-Rechner erheblich besser nutzen als beispielsweise DOS. Leider beanspruchen sie aber auch sehr viel Leistung für sich selbst. Windows 98 ist in erster Linie für den Privatnutzer konzipiert. So gibt es keine Benutzerverwaltung mit der Möglichkeit des Dateienschutzes vor anderen Benutzern. Es ist teilweise noch in 16-Bit-Technik realisiert und daher langsamer als NT oder XP. Speicherschutzverletzungen alter Windows 3.x-Anwendungen können zu Abstürzen führen. Windows 98 bietet auch noch, wie unter DOS, die Möglichkeit, direkt auf Hardware-Komponenten zuzugreifen. So kann man beispielsweise den System-Timer umprogrammieren oder den Tastatur-Interrupt abschalten. So etwas ist in der Regel „tödlich“, kann jedoch besonders bei hardwarenahen technischen Anwendungen gewünscht und hilfreich sein. Windows NT ist (war) das leistungsfähigere Profi-System: x
volle 32-Bit-Architektur, damit schneller als Windows 98
x
Mehrbenutzerverwaltung durch Administrator, der die Benutzerrechte verwaltet
x
unterstützt Multiprocessing (Systeme mit mehreren Prozessoren)
x
getrennte Speicherbereiche für BS und Anwendungsprogramme; Speicherschutzverletzungen werden abgefangen
x
bessere Schichtentrennung als bei Windows 98, daher im Prinzip Prozessorunabhängig
x
kein direkter Zugriff von Anwendungsprogrammen auf die Hardware möglich
x
in Workstation- und Server-Version erhältlich, damit zur Verwaltung großer Netzwerke gut geeignet.
Windows 2000 und XP führten die beiden Windows-Linien mehr und mehr zusammen. Windows XP verschickt ungefragt Daten über das Internet an Microsoft. Möchten Sie das verhindern, sollten Sie ein entsprechendes „Antispionage-Programm“ installieren und aktivieren.
2.2 Dateien und Dateisysteme
15
Für sehr flexible Anwendungen, wie sie v. a. für die Forschung typisch sind, bleiben häufig zeilenorientierte Shells, mit der Möglichkeit, Prozeduren zu schreiben, deutlich überlegen. In diesem Bereich ist UNIX bzw. Linux erste Wahl. Am unteren Ende der Leistungsskala für BS sind sog. Monitore angesiedelt. Das sind Minibetriebssysteme, meist für den Einsatz in Mikrocontrollern (C). Ihr Umfang beträgt etwa 1 bis 8 KByte. Sie sind komplett auf einem EPROM untergebracht. Sie ermöglichen in erster Linie das Herunterladen von Programmen aus dem Software-Entwicklungs-Rechner in den Controller (Downloading). Außerdem bieten sie einfache Testfunktionen: Anschauen und Verändern von Speicherstellen und Registern, Setzen von Breakpoints und Singlestep-Betrieb. Monitore kommunizieren über die serielle oder USB-Schnittstelle meist mit einem PC, auf dem eine Terminalemulation läuft. Nach Abschluss der Entwicklungsarbeiten und Abspeicherung der Software auf einem EPROM verschwinden die C häufig in einem Gerät (Waschmaschine, Auto, Aufzug). Man spricht dann von Embedded Systems. Einen Sonderfall bei den Multitasking-Systemen im technischen Bereich bilden die Echtzeitsysteme. Manchmal erfordern bestimmte Tatbestände eine Reaktion des Rechners innerhalb einer bestimmten (kurzen) Zeit. Beispiele: – ein Messgerät möchte die aktuellen Daten übermitteln – ein Reaktor-Überwachungsgerät löst Alarm aus Ein gewöhnlicher Zeitscheiben-Scheduler kann darauf nicht angemessen reagieren, wenn das entsprechende Programm, welches das Messgerät oder den Alarm bedienen soll, gerade nicht an der Reihe ist. Dagegen reagiert ein Echtzeitsystem innerhalb einer garantierten Zeitspanne. Beim Echtzeit-BS OS-9 beispielsweise funktioniert das so: Das Gerät, das Aufmerksamkeit verlangt, löst einen Impuls (Interrupt-Request) aus. Das BS beendet die aktuelle Zeitscheibe ordnungsgemäß, speichert deren Status ab und weckt die Service-Routine auf, die sich bisher im Zustand „schlafend“ befand. Die dafür benötigte Zeitspanne ist die Reaktionszeit des Echtzeit-BS. In der Regel wird die Service-Routine nun ohne Unterbrechung komplett abgearbeitet, bis sie sich selbst wieder „schlafen legt“. Nun geht der normale Nicht-Echtzeit-Betrieb weiter bis zum nächsten Interrupt. Aufgrund des hohen Verwaltungsaufwands sind Echtzeitsysteme nicht unbedingt sehr schnell, sie garantieren lediglich eine maximale Reaktionszeit. Liefert etwa „im richtigen Leben“ der Paketdienst A jedes Paket ohne Ausnahme spätestens innerhalb von sieben Tagen beim Empfänger ab, so ist das eine Echtzeitgarantie. Der Paketdienst B liefert praktisch immer innerhalb von drei Tagen aber ohne feste Zusage. B ist also kein „Echtzeit-Paketdienst“, in Wirklichkeit aber fast immer schneller als A. Man sollte bei technischen Anwendungen immer sehr genau prüfen, ob man tatsächlich ein Echtzeit-BS benötigt. Häufig reicht ein schneller Rechner unter einem „normalen“ BS aus. Falls man gar kein Multitasking benötigt, kann ein Singletasking-BS wie DOS gute Dienste leisten, denn bei solchen Systemen kommt das Echtzeitproblem erst gar nicht auf.
2.2 Dateien und Dateisysteme Eine Datei besteht in der Regel aus mehreren Datensätzen, bei Personendaten z. B. Angaben über Namen und Anschriften dieser Personen. Oft vergleicht man eine Datei mit einem Karteikasten, einen Datensatz mit einer Karteikarte.
16
2 Das Betriebssystem
Unter einer Datei versteht man eine Menge logisch zusammengehörender Daten. In seinen ersten Versionen besaß beispielsweise DOS ein ungegliedertes Dateisystem, d. h. alle Dateien ordneten sich gleichwertig auf einer Ebene an. Man spricht von einem „flat-filesystem“. Das war durchaus sinnvoll, weil als Datenträger lediglich Disketten dienten, die darüber hinaus nur Kapazitäten im Kilobyte-Bereich aufwiesen, so dass eine Diskette nur eine sehr begrenzte Zahl von Dateien aufnehmen konnte. Wollte der Benutzer Ordnung in seine Dateiensammlung bringen, so konnte er dies über eine Vielzahl von Disketten erreichen: Die eine enthielt beispielsweise nur C-Programme, die andere ausschließlich Liebesbriefe. Mit den ersten Festplatten, die bereits 10 Megabyte speichern konnten, erschien ein flat-filesystem als zu unübersichtlich. Ab Version 2.0 übernahm DOS von UNIX das hierarchische Dateisystem, dessen Struktur mit einem Baum vergleichbar ist. Zu diesem Zweck wurden Dateiverzeichnisse (directories, bei Windows auch „Ordner“ genannt) eingeführt, die die Funktion der Äste im Dateienbaum einnehmen. Die Dateien stellen die Blätter dar. Einen Stamm gibt es nicht, wohl aber eine Wurzel (root). Diese ist ebenfalls ein Verzeichnis, dass sich aber auf doppelte Weise auszeichnet: Es ist einzigartig (ein Baum hat viele Äste aber nur eine Wurzel) und es repräsentiert gleichzeitig die unterste Hierarchieebene. Die Verzeichnisse stellen nun die Verbindung zwischen einer Datei und ihrem Namen her. Jede Datei steht in genau einem Verzeichnis und ist nur über dieses eindeutig ansprechbar. Inzwischen verwenden alle modernen BS solche hierarchischen Dateisysteme. In aller Regel wird der Dateibaum auf dem Kopf stehend, d. h. mit der Wurzel nach oben, dargestellt. Das folgende Beispiel zeigt das Gerüst (nur Wurzel und Äste, keine Blätter) eines möglichen Dateibaums:
Hierarchisches Dateisystem (Beispiel)
In dieser Darstellung ist die Hierarchie gut zu erkennen. Die Verzeichnisse „WINDOWS“, „C“, „TEXTE“ und „PASCAL“ hängen direkt an der Wurzel (root). Die „Äste“ „QUELLEN“ und „EXE“ hängen an dem „Ast“ „C“, usw. Für die Verzeichnisnamen gelten die gleichen Regeln wie für die Namen der „normalen“ Dateien unter dem jeweiligen BS. Lediglich die Wurzel wird immer durch den Backslash „\“ (oder Slash „/“ bei UNIX und Linux) symbolisiert. Es können mehrere Dateien und sogar Verzeichnisse mit dem gleichen Namen vorkommen. Eindeutig werden sie erst mit ihrem Pfadnamen. Man unterscheidet
2.2 Dateien und Dateisysteme
17
Absolute Pfadnamen
Relative Pfadnamen
erstrecken sich von der Wurzel bis zu der gewünschten Datei.
erstrecken sich relativ zum Arbeitsverzeichnis bis zu der gewünschten Datei.
Wir betrachten nun einen anderen Dateibaum, der sogar mit ein wenig Laub versehen ist. Die Blätter (Dateien) sind durch runde Klammern symbolisiert, die Äste (Verzeichnisse) nach wie vor durch spitze Klammern. Bei modernen Betriebssystemen wie Windows können Dateinamen beliebig lang sein, bei DOS sind sie auf 8 Zeichen begrenzt.
Dateibaum < > = directory (Verzeichnis) ( ) = normale Datei
Anhand von Beispielen wollen wir uns den Begriff des absoluten und relativen Pfadnamens klarmachen. Der absolute Pfadname der Datei „edv.dat“ (Groß- oder Kleinschreibung ist unerheblich) lautet: \fhw\rh\et\edv.dat (DOS oder Windows), bzw. /fhw/rh/et/edv.dat (UNIX) Regel: Absolute Pfadnamen beginnen immer mit „\“ (DOS, Windows) oder „/“ (UNIX, Linux), dem Symbol für das Wurzelverzeichnis. Solche absoluten Pfadnamen können sehr lang und umständlich werden, deshalb kann man ein Verzeichnis seiner Wahl zum Arbeitsverzeichnis (working directory) bestimmen. Nehmen wir an, „rh“ sei Arbeitsverzeichnis, dann lautet der relative Pfadname von „edv.dat“: et\edv.dat oder bei UNIX et/edv.dat Regel: Relative Pfadnamen beginnen nie mit „\“ (oder „/“ bei UNIX, Linux).
3 Algorithmen und Struktogramme Neben der technischen Seite weist die EDV eine logisch-mathematische auf. Bei ihr geht es um die Lösung konkreter Probleme mit Rechnern.
3.1 Algorithmen Möchte man ein Problem mit Hilfe eines Rechners lösen, ist zu prüfen, ob sich die Aufgabe in Algorithmen (Rechenregeln) formulieren lässt. Ein Algorithmus besteht aus elementaren Einzelschritten, diese müssen x
in einer bestimmten Reihenfolge ausgeführt werden,
x
zahlenmäßig begrenzt und in endlicher Zeit abgearbeitet sein.
Der Algorithmus selbst muss allgemeingültig und maschinell lösbar sein. Ist dies der Fall, kann man die Automatisierung des Problems in Angriff nehmen. Beispiel In einen Rechner soll eine unbestimmte Anzahl von ganzen Zahlen eingegeben werden. Die Aufgabe besteht darin, jeweils die Anzahl der positiven und der negativen Zahlen zu ermitteln und auszugeben. Die Verarbeitung soll enden, wenn eine „0“ eingegeben wird. Wir formulieren den Algorithmus zunächst umgangssprachlich: 1. Setze den Zähler der positiven Zahlen auf Null. 2. Setze den Zähler der negativen Zahlen auf Null. 3. Lies eine ganze Zahl ein. 4. Falls die Zahl kleiner als Null ist, erhöhe den Zähler der negativen Zahlen. 5. Falls die Zahl größer als Null ist, erhöhe den Zähler der positiven Zahlen. 6. Falls die Zahl nicht „0“ ist, gehe zurück nach 3. 7. Gib die Anzahl der positiven Zahlen aus. 8. Gib die Anzahl der negativen Zahlen aus. Diese Lösung erfüllt unsere Forderungen an einen Algorithmus (s. o.). Der Algorithmus besteht aus Befehlsfolgen (1., 2. und 7., 8.), Auswahlen (4. und 5.) sowie einer Schleife (3. bis 6.). Das sind die drei Grundstrukturen, aus denen sich jeder Algorithmus zusammensetzen kann. Weitere existieren nicht.
3.2 Struktogramme Eine umgangssprachliche Formulierung, wie im obigen Beispiel, kann bei derart überschaubaren Problemen durchaus sinnvoll sein, bei komplexeren Algorithmen ist sie zu unübersichtlich. Deshalb bedient man sich in der Informatik häufig einer formalisierten Darstellungsform, die man „Struktogramm“ nennt. Ein Struktogramm besteht aus einzelnen Strukturblöcken, die sich bausteinartig zu dem kompletten Struktogramm zusammensetzen.
3.2 Struktogramme
19
Es gelten folgende „Grundgesetze“: 1. Jeder Strukturblock ist rechteckig. 2. Jeder Block hat nur einen Eingang (oben) und einen Ausgang (unten). 3. Blöcke stehen entweder untereinander oder sie sind vollständig ineinander enthalten (aus 1. und 3. o das gesamte Struktogramm ist ebenfalls rechteckig). 4. Strukturblöcke sind knapp, aber verständlich zu kommentieren. eintretende Kante
STRUKTURBLOCK
austretende Kante Strukturblock
Nachstehende Regeln sind nicht zwingend, sie sollten jedoch ebenfalls befolgt werden: 5. Kein Struktogramm sollte länger sein als eine Seite. Daraus folgt: 6. Teilprobleme sollten als separate Modulblöcke ausgegliedert werden. Wir unterscheiden folgende Grundtypen von Strukturblöcken, mit denen sich jeder Algorithmus formulieren lässt: 1. Sequenzblock
=
Folge (Sequenz) von unbedingten Anweisungen (mindestens eine Anweisung)
2. Selektionsblock
=
alternative Ausführung von Anweisungen (Auswahl)
3. Iterationsblock
=
wiederholte Ausführung von Anweisungen (Schleife)
4. Modulblock
=
black box für separat erläutertes Teilproblem (Modul)
Ein Modulblock besteht wiederum aus Sequenzen, Selektionen und Iterationen. Die Selektion gibt es in zwei Varianten, von denen die Alternative die elementare ist. Ein eigener Strukturblock existiert jedoch auch für die Fallfolge oder Mehrfachauswahl. Diese ließe sich aber auch durch ineinander geschachtelte Alternativblöcke ersetzen. Sequenz (Folge) Beschreibung der Programmschritte In diesem Block steht eine Folge der Programmschritte, die ohne „wenn und aber“ in dieser Reihenfolge auszuführen sind.
20
3 Algorithmen und Struktogramme
Beispiel Setze den Zähler der positiven Zahlen auf Null. Setze den Zähler der negativen Zahlen auf Null. Selektion (Verzweigungen) a) Alternative Bedingung 1. Alternative
2. Alternative
Es handelt sich um eine klare „entweder-oder“-Entscheidung. Ist die Bedingung wahr, wird der linke Block durchlaufen, ist sie unwahr, der rechte. Das folgende Beispiel prüft, ob „Zahl“ kleiner als Null ist. Ist diese Bedingung im aktuellen Fall wahr, wird „Zähler“ um eins erhöht. Beispiel Zahl < Nu ll ja
nein
Zähler = Zähler+1
Wie dieses Beispiel zeigt, kann einer der beiden Alternativblöcke durchaus leer sein. Das bedeutet, dass in diesem Fall nichts geschieht. b) Fallfolge (Mehrfachauswahl) Mehrfachauswahl mit Fehlerfall
Fall 1
Fall 2
Fall 3
…
Sonstfall
3.2 Struktogramme
21
Fallfolgen eröffnen mehrere Alternativen. Sie eignen sich besonders gut zur Darstellung von Auswahlmenüs. Stets sollte man einen Sonstfall vorsehen, der immer dann greift, wenn keiner der gewünschten Fälle zutrifft. Der Sonstfall, manchmal auch als Fehlerfall bezeichnet, fängt alle „unerlaubten“ Fälle, z. B. eine falsche Eingabe, ab. Als Beispiel sollen mögliche Operationen auf eine Datenbank dienen. Datenbanken bestehen aus einer Vielzahl von Sätzen, die bestimmte Eigenschaften von Personen oder Dingen beschreiben. Ein Satz aus einer Studentendatenbank enthält mit Sicherheit Elemente wie Matrikelnummer, Name und Adresse eines Studenten. Der Benutzer der Datenbank möchte Sätze lesen, ändern, hinzufügen und löschen. Das sind die möglichen Operationen. Beispiel (Datenbankoperation) Benutzereing abe
' C'
' R'
S a tz le s e n
' D'
S atz än der n
Satz löschen
' A'
Satz anfügen
Son stfa ll Ausg abe: ‚unerlau bte Eingabe‘
Fallfolgen sind, wie schon gesagt, erweiterte Alternativen. Jede Fallfolge lässt sich, wenn auch etwas umständlicher, mit ineinander geschachtelten Selektionen darstellen. Iterationsblock (Schleife)
Bei den Iterationen unterscheiden wir wiederum zwei Typen: x x
Schleife mit Kopfprüfung (abweisende Schleife) Schleife mit Fußprüfung (nicht-abweisende Schleife)
a) Schleife mit Kopfprüfung Be ding ung Sch leifenkern oder Sch leifenkörper
Diese Schleife wird ausgeführt, solange die Bedingung wahr ist. Ist diese zu keinem Zeitpunkt wahr, wird die Schleife niemals durchlaufen. In unserem Beispiel wird ein Zähler solange erhöht, wie er kleiner als ein vorgegebener Endwert ist. Der Schleifenkörper besteht aus zwei Schritten: Summe um Zähler erhöhen und Zähler um eins erhöhen. Der Schleifenkörper ist in diesem Beispiel eine Sequenz.
22
3 Algorithmen und Struktogramme
Beispiel
Solange Zähler < Endwert Summe = Summe + Zähler Zähler = Zähler + 1
b) Schleife mit Fußprüfung Sc hleifenkern oder S chle ifenkörper B edingung
Auch diese Schleife wird ausgeführt, solange die Bedingung wahr ist. Da die Bedingung jedoch erst am Schluss eines Schleifendurchlaufs geprüft wird, kommt es in jedem Fall zu mindestens einem Durchlauf. Beispiel Ein gabe
s olan ge Eingabe falsch
Schleifen mit Fußprüfung benutzt man gerne, um Eingabefehler zu verhindern. Der Benutzer wird solange zur erneuten Eingabe gezwungen, bis er eine gültige Eingabe macht. Modulblock
Man kann sich leicht vorstellen, dass Struktogramme, die länger sind als eine Seite, schnell unübersichtlich werden. Wir leiten daraus die folgende Forderung ab: Jedes Struktogramm sollte auf eine Seite passen. Das scheint schwieriger als gesagt, wenn man an einen komplexen, umfangreichen Algorithmus denkt. Den Ausweg bieten Modulblöcke. Teilalgorithmen werden einfach als „Blackbox“ ausgegliedert und dann im Detail auf einer gesonderten Seite erläutert.
Modulname Modulfunktion
3.2 Struktogramme
23
Im Beispiel wird ein Sortiervorgang als „Blackbox“ ausgegliedert. An anderer Stelle ist hierfür ein eigenes Struktogramm zu erstellen. Beispiel
So rt Date n in abst eigender Reih enf olge sortieren
Ein Struktogramm setzt sich nun aus mehreren Strukturblöcken zusammen. Das GesamtStruktogramm bleibt dabei stets rechteckig, d. h. verändert seine Breite während des Programms nicht. Die beiden senkrechten Begrenzungen bilden „die Schienen“ für die Strukturblöcke. Wir erinnern uns, dass die Strukturblöcke entweder aufeinander folgen oder vollständig geschachtelt sind. Zunächst ein kleines Beispiel: Beispiel Eingabe N Summe Lauf
= 0 = 0
solange Lauf 0 ja
zneg
nein
= z neg + 1 zpos
= zpos + 1
solange x ungleich 0 Ausgabe zpos Ausgabe zneg Die Auswahl (Zahl x größer oder kleiner als Null) wurde hier gegenüber der umgangssprachlichen Formulierung (o siehe Kap. 3.1) durch Schachtelung optimiertt. Struktogramme sind unabhängig von einer bestimmten Programmiersprache, in der das Problem evtl. gelöst werden soll. Struktogramme dienen als Planungsinstrument (allgemeine Formulierung eines Algorithmus) und als sprachunabhängiges Dokumentationsmittel.
3.3 Aufgaben
25
3.3 Aufgaben 1. Analysieren Sie das Struktogramm von der vorherigen Seite. a) Wie viele Elementarblöcke enthält es? b) Benennen Sie die einzelnen Blöcke nach ihrer Art. 2. Formulieren Sie ein Struktogramm zur Berechnung der Fakultät einer positiven ganzen Zahl und führen Sie einen „Schreibtischtest“ mit verschiedenen Eingabewerten durch. Fakultät N = N * (N-1) * ... * 1; Definition: Fakultät 0 = 1. 3. Welche Aufgabe löst der folgende, als Struktogramm formulierte Algorithmus? Hinweis: Führen Sie einen „Schreibtischtest“ durch, indem Sie das Struktogramm mit unterschiedlichen Wertepaaren von x und y „durchlaufen“. Notieren Sie die schrittweisen Wertänderungen von x und y. Eingabe: x Eingabe: y x < 1 oder y < 1 ja
nein solange x ungleich y
Ausgabe: „falsche Eingabe“
x>y ja
nein x=x–y
Ausgabe: x
y=y–x
4 Programmiersprachen Sprachen lassen sich allgemein nach folgendem Schema klassifizieren:
Sprachen
n atürliche Spr ache n
formale Sprachen
... U m ga ngs sp r a c h e n
Fa chspra chen
Programmiersprachen
math. Formelsprache
...
Die Programmiersprachen zählen demnach zu den formalen, „künstlichen“ Sprachen. Auch wenn Sie es uns im Moment noch nicht glauben: Programmiersprachen sind erheblich leichter und schneller zu erlernen als Fremdsprachen!
4.1 Maschinen- und Hochsprachen Die Rechner der ersten Generation mussten mühsam in ihrer Maschinensprache programmiert werden, die aus einem reinen Binärcode (Folge von „0“ und „1“) besteht. Die Assemblersprache brachte die erste Erleichterung für den Programmierer. Maschinenbefehle konnten nun in halbwegs lesbarer Form programmiert werden, statt beispielsweise Maschinenbefehl:
Assemblerbefehl:
Bedeutung:
0000000111011000
ADD AX,BX
Addiere Register BX zu Reg. AX
Eine Assemblersprache verwendet also gedächtnisstützende Kürzel (mnemonics) statt Binärziffernfolgen. Das Beispiel bezieht sich auf einen PC-Prozessor (Intel 80(x)86, AMD). Da jeder Rechner – auch heute noch – ausschließlich seine eigene Maschinensprache versteht, muss ein Assemblerprogramm zunächst, vor seiner Ausführung, in die Maschinensprache übersetzt werden. Dies besorgt ein (käufliches) Programm, das verwirrenderweise ebenfalls „Assembler“ heißt. Aus einem Assemblerbefehl wird ein Maschinenbefehl.
4.1 Maschinen- und Hochsprachen
27 Assembler
Asse mbler program m
Maschinenprog ram m 1:1 Übersetzung
Maschinensprache und Assemblersprache gehören zu den maschinenorientierten Programmiersprachen, denn sie sind auf einen bestimmten Prozessortyp abgestimmt. Wie die folgende Übersicht zeigt, gibt es daneben die heute wesentlich häufiger eingesetzten problemorientierten Programmiersprachen: Programmiers prachen
problemorientierte Sprachen
masc hinenori entierte Spra chen
M a s c h i ne nsp rach en
Asse mblerspra che n
Universalsprachen
Spezialsprachen
FORTRAN PASCAL C . .
Lisp SQL Prolog . .
Problemorientierte Sprachen sind unabhängig von einem bestimmten Rechnertyp. Es besteht auch keine 1:1 Zuordnung zwischen einem Befehl in einer „höheren“ Sprache und einem Maschinenbefehl. Der Begriff „höher“ bezieht sich auf das Abstraktionsniveau, die Sprache „schwebt“ hoch über der Hardware. Man kann durchaus erfolgreich FORTRAN- oder C/C++Programme schreiben, ohne viel über den Aufbau und die Arbeitsweise von Rechnern zu wissen. Selbstverständlich müssen auch problemorientierte Programme vor ihrer Ausführung in die jeweilige Maschinensprache ihres Zielrechners übersetzt werden. Dies übernimmt ebenfalls ein käufliches Softwareprodukt, der Compiler. Aus einem Hochsprachenbefehl entstehen N Maschinenbefehle, wobei N meistens größer als 1 ist. Q ue l l p rog ra mm : Pr o g r am m i n ei n e r p ro b le m o ri e nti e r t en Pr o g r am m i e rsp ra c h e
Compiler Maschinenpr og ra mm 1:N Übersetzung
Der Vorgang des Übersetzens heißt „compilieren“.
28
4 Programmiersprachen
Die wichtigsten problemorientierten Sprachen im Ingenieurbereich sind heute FORTRAN, PASCAL, Basic und C. FORTRAN ist die älteste Hochsprache überhaupt (seit 1954) und für Probleme der numerischen Mathematik nach wie vor unschlagbar. PASCAL (seit 1968) ist eine hervorragend strukturierte Sprache. Sie eignet sich wegen ihrer Modellhaftigkeit v.a. für die Ausbildung. Auf PC war sie mit ihrem „Dialekt“ TURBO PASCAL weit verbreitet und sehr attraktiv, weil sie die Möglichkeiten des PC recht einfach erschließt. Basic eignet sich gut für kleine Programmiervorhaben. C ist eine echte Universalsprache. Bei hardwarenahen Problemen macht sie sogar der Assemblersprache Konkurrenz, in der Systemprogrammierung ist C die Nummer eins, und auch normale Anwenderprobleme lassen sich sehr gut lösen. C hat die höchste Verfügbarkeit (kein Computer ohne C-Compiler), C-Programme sind sehr leicht von einer Hardware auf eine andere übertragbar (portabel). Die drei genannten Sprachen gehören der 3. Sprachgeneration an, inzwischen gibt es auch Sprachen der 4. und 5. Generation mit noch höherem Abstraktionsniveau. Diese Sprachen sind oftmals objektorientiert (strenge Modularität, Einheit von Daten und Programmen). Anders als bei FORTRAN-, PASCAL oder C-Programmen lassen sich aus der Befehlsreihenfolge nicht immer Rückschlüsse auf die Verarbeitungsreihenfolge im Rechner ziehen. Der Algorithmus (das „wie“) tritt gegenüber dem Problem (das „was“) immer mehr in den Hintergrund. Man spricht deshalb auch von nicht-prozeduralen Sprachen. Die Sprachen der 4. Generation sind allerdings oftmals weniger universell, es sind Spezialsprachen für Spezialprobleme (z. B. PROLOG für Probleme der künstlichen Intelligenz und SQL als Abfragesprache für Datenbanksysteme). So finden nach wie vor alle Sprachgenerationen ihre Anwendungen, abhängig vom Problem. C++ als Erweiterung von C kann zumindest teilweise als Sprache der 5. Generation (objektorientiert) betrachtet werden. Eine für den Ingenieurbereich sehr interessante Spezialsprache zur Lösung von Problemen im Bereich Messen, Steuern und Regeln ist LabVIEW von der Firma National Instruments. Die Sprache ist voll grafisch. Aus Toolboxen werden Module geholt, auf dem Bildschirm platziert und mit „Drähten“ von einer „Drahtrolle“ verbunden. Dadurch ergibt sich der Daten- und Programmfluss. Gleichzeitig entsteht automatisch die Benutzeroberfläche. Das folgende einfache Beispiel zeigt den LabVIEW-„Quelltext“ einer Addition zweier Eingabeelemente für ganze Zahlen und die Ausgabe des Ergebnisses in einem Ausgabeelement.
Einfaches LabVIEW-Quellprogramm (Addition zweier Eingabewerte mit Ausgabe)
Das folgende Beispiel beweist die Möglichkeit, mit LabVIEW auch individuell gestaltete Oberflächen zu erzeugen. Leider können wir hier die Farbe als zusätzliches Gestaltungselement nicht demonstrieren.
4.2 Die Hochsprachen-Programmentwicklung
29
Oberfläche eines LabVIEW-Programms (Anlagensteuerung mit Messdatenerfassung) im „Metal“-Design
4.2 Die Hochsprachen-Programmentwicklung Auch bei der Softwareentwicklung spielt das EVA-Prinzip eine wichtige Rolle. Mit Befehlen wie READ oder WRITE werden Daten eingelesen und ausgegeben. Eingabemedium ist meist die Tastatur, während Bildschirm und Drucker zu den bevorzugten Ausgabemedien zählen. Zwischendurch wird gerechnet oder allgemein verarbeitet. Das EVA-Prinzip gibt jedoch keine feste Reihenfolge vor. Vor allem bei großen Programmen wechseln sich E-, V- und A-Schritte in bunter Vielfalt ab. Eine typische Softwareentwicklung erfolgt in Stufen: Stufe
Tätigkeit
Werkzeug oder Methode
0 1 2 3 4
Programmplanung (Algorithmus erstellen) Quellprogramm eingeben Programm übersetzen Evtl. Fehler beseitigen Programm mit externen Modulen zusammen binden und lauffähig machen Programm starten
Struktogramm Editor Compiler Schreibtischtest, Debugger Linker
5
Kommandointerpreter
30
4 Programmiersprachen
Unter einem Quellprogramm verstehen wir den Programmtext in lesbarer Form (s. folgendes Kapitel). Der Editor ist ein Programm, das die Tastatureingabe von Texten auf komfortable Weise ermöglicht. Das Quellprogramm muss streng den Regeln der gewählten Programmiersprache, den Syntaxregeln, entsprechen. Diese zu erlernen, macht den Schwerpunkt eines Programmierkurses aus. Teil II ist eine solche Einführung in die Sprache C / C++. Mit Hilfe des Linkers in Stufe 4 werden evtl. mehrere vorhandene übersetzte Programmodule oder Bibliotheksroutinen zu einem lauffähigen Gesamtprogramm zusammengebunden. Jeder Compiler enthält Bibliotheken für häufig auftretende Standardfunktionen. Generell sind problemorientierte Sprachen alle nach einem ähnlichen Muster aufgebaut. Typischerweise lässt sich ein Programm in drei Teile untergliedern: 1. Überschrift 2. Vereinbarungsteil 3. Anweisungsteil Die Überschrift besteht nur aus einer Zeile, die je nach Sprache unterschiedlich aussieht. Es folgt der Vereinbarungsteil; dort werden die im Programm benötigten Variablen und Konstanten vereinbart (deklariert), d. h. es wird Platz im Zentralspeicher des Rechners reserviert. Speicherplätze werden, wie bereits weiter oben erläutert, über ihre numerische Adresse angesprochen. Hochsprachen arbeiten jedoch mit symbolischen Adressen, deren Namen im Rahmen gewisser Regeln vom Programmierer frei wählbar sind. Dies erleichtert die Arbeit sehr, weil sich der Programmierer über die exakte Länge und Verfügbarkeit von Speicherplätzen keine Gedanken machen muss. Variablen und Konstanten können im Programm Werte zugewiesen werden, Konstanten nur einmal zu Beginn des Programms, Variablen beliebig oft. Der Anweisungsteil entspricht dem in die jeweilige Programmiersprache umgesetzten Struktogramm. Der Anweisungsteil besteht aus den einzelnen Befehlen, die den strengen Syntaxregeln der jeweiligen Sprache unterliegen. Syntaxfehler entdeckt der Compiler, den man nach Eingabe des Quelltextes aufruft. Ist das Quellprogramm syntaktisch fehlerfrei, übersetzt es der Compiler in die Maschinensprache des verwendeten Rechners. Dennoch ist es möglich, dass unser Programm fehlerhaft ist. Es produziert u. U. falsche Ergebnisse. Der Grund: es enthält logische Fehler (Semantikfehler). Die Fehlersuche nennt man debugging (= Entwanzung). Sie erfolgt entweder durch aufmerksames Studium des Quelltextes (evtl. „Schreibtischtest“) oder mit Hilfe eines Debuggers, einer speziellen Software zur Fehlersuche. Entsprechend der Erkenntnisse wird nun der Quelltext verbessert. „Läuft“ das Programm zufriedenstellend, ist der Entwicklungskreislauf abgeschlossen. Programme startet man im Fall von grafischen Oberflächen (GUI) durch Doppelklick auf das Symbol der ausführbaren Datei (unter Windows EXE-Modul), bei einfachen ZeilenBenutzeroberflächen durch Eingabe des Programmnamens. Diese Eingabe wird vom Kommandointerpreter des Betriebssystems ausgewertet. Moderne Compiler bieten meist eine integrierte Arbeitsumgebung, aus der heraus man auch Programme starten kann. Im folgenden Teil II, dem Kernstück dieses Lehrbuchs, werden wir uns intensiv mit der Programmentwicklung befassen. Als Sprache wählen wir, aufgrund ihrer zurzeit überragenden Bedeutung, C/C++.
II Programmieren in C/C++ Dieses Kapitel soll in die Grundlagen der Programmierung einführen. Aufgrund ihrer zunehmenden praktischen Bedeutung wählen wir dazu die Sprache C bzw. C++. Als Entwicklungsumgebung stellen wir uns einen PC unter Windows vor. Allerdings ist C hervorragend portabel, d. h. Programme lassen sich ohne großen Änderungsaufwand auf andere Betriebssysteme oder andere Rechner, z. B. UNIX- oder Linux-Workstations, übertragen, sofern man sich an den Standard hält und auf compilerspezifische Funktionen verzichtet Es ist nicht beabsichtigt, die Möglichkeiten von C/C++ erschöpfend darzustellen. Vielmehr möchten wir am Beispiel von C/C++ die sich in verschiedenen Sprachen oft ähnelnden Konzepte einer Höheren Programmiersprache vorzustellen. C++ stellt eine Spracherweiterung von C dar. Während C v. a. system- und hardwarenahe Probleme unterstützt, strebt C++ eine bessere Unterstützung der Anwendungsprogrammierung an, v. a. durch Objektorientierung. Die Ideen der objektorientierten Programmierung können hier nur in ihren Grundzügen dargestellt werden. Ignoriert man weitgehend die objektorientierten Elemente, so ist C++ eine prozedurale Sprache, die den C-Standard nutzbringend erweitert. Das Programm läuft später im Rechner so ab, wie es programmiert wurde. Die Reihenfolge der Befehle bestimmt exakt die Reihenfolge der Abarbeitung. Diese prozessorientierte (strukturierte) Vorgehensweise bestimmt nach wie vor die Lösung der meisten technischen Softwareprobleme. Die so entwickelten Programme sind konkurrenzlos schnell. Soweit sich die Aussagen der folgenden Kapitel nicht nur auf C++ sondern auch auf C beziehen, sprechen wir von C/C++. Für technische Anwendungen, also Aufgaben aus dem Bereich der Automatisierung und Messdatenerfassung, ist C/C++ Standard, auch wenn immer häufiger graphische Entwicklungstools, z. B. LabVIEW, eingesetzt werden. Der sichere Umgang mit solchen Tools setzt jedoch ebenfalls fundierte „klassische“ Programmierkenntnisse voraus, denn auch in solchen Tools findet man die Grundstrukturen der klassischen Programmierung wieder. Sequenzen, Verzweigungen und Schleifen bleiben die Grundlagen jeglicher Programmierung. Und auch die Lösungsidee, die Entwicklung eines Algorithmus, nimmt einem leider kein Tool ab. Natürlich ist das Erlernen einer Programmiersprache für den Anfänger keine ganz leichte Aufgabe. In der Praxis stellt jedoch die Entwicklung einer Lösungsidee für das jeweilige Problem die weitaus größere Schwierigkeit dar. Das Einmaleins der Programmierung lernt man am Besten anhand einer prozeduralen Sprache, zumal sie zusätzlich ein „sicheres Gefühl“ für die Arbeitsweise eines Rechners vermittelt. Und wenn sie darüber hinaus auch noch die Objektorientierung unterstützt und eine so große praktische Bedeutung wie C++ aufweist, dann umso besser. Die zahlreichen Beispiele dieses Teils sollten mit jedem C/C++-Compiler auf jedem Rechner, sofern er über die entsprechende Peripherie (Tastatur, Bildschirm, Festplatte) verfügt, unter jedem Betriebssystem funktionieren. Für alle gängigen Computer und Betriebssysteme gibt es Compiler, die man kostenlos aus dem Internet herunterladen kann. Die auf PC unter Windows am häufigsten eingesetzten kommerziellen Compiler sind der Borland C++-Builder und der Microsoft Visual C++-Compiler. Mehr zum Thema Compiler finden Sie zu Beginn von Teil III.
5 Über C und C++ Die Entwicklung der Programmiersprache C ist eng mit der des Betriebssystems UNIX verknüpft. Nachdem die erste UNIX-Version noch in Assembler erstellt worden war (1969), entwickelte Ken Thomson 1970 die Sprache B zur Implementierung eines UNIX-Systems für eine PDP-7-Maschine. Aus der mit zu vielen Schwächen behafteten Sprache B entwickelte Dennis Ritchie 1972 C. Seit 1973 ist das Betriebssystem UNIX fast vollständig in C geschrieben. Zunächst gab es keinen offiziellen Sprachstandard. Stattdessen erreichte die Sprachdarstellung in einem Lehrbuch – deutsch: Kernighan, Ritchie; Programmieren in C. Hanser Verlag 1983 – den Status eines Quasi-Standards (Kernighan-Ritchie-Standard). Kleinere Erweiterungen und Verbesserungen führten zum ANSII-Standard. Die Sprache C++ wurde Anfangs der 80er Jahre von Bjarne Stroustrup an den Bell Laboratories entwickelt. Es handelt sich dabei um einen Zusatz für C. C ist in C++ vollständig enthalten. (Fast) alles was in C funktioniert, funktioniert auch in C++ C ist eine Sprache der 3. Generation (strukturierte Sprache) und ist die wichtigste Höhere Programmiersprache im Ingenieurbereich. Die wesentlichen Merkmale der Sprache sind: x
breites Anwendungsspektrum
x
knappe Befehle (short is beautiful)
x
sehr klares Sprachkonzept.
Was oben als Vorteil erscheint, erweist sich als Nachteil bezüglich der Erlernbarkeit als „Erstsprache“. Die „knappen Befehle“ könnte man etwas böswillig auch als kryptisch bezeichnen und das „klare Sprachkonzept“ verlangt vom Programmierer Grundkenntnisse über Aufbau und Arbeitsweise von Computern, deutlich mehr als Pascal und FORTRAN. Allerdings steigen diese Grundkenntnisse bei der jungen Generation von Jahrgang zu Jahrgang. Fast jeder (Interessierte) kann mit einem PC umgehen. Viele haben bereits gelernt, kleinere Probleme in Basic oder Pascal zu lösen. Und so kann man es heute wagen, ernsthaft mit C zu starten. Die Mühe lohnt sich! Es klingt paradox aber es ist wahr: Obwohl C++ der 5. Sprachgeneration (objektorientiert) angehört und mächtiger als C ist, gelingt der Einstieg mit C++ leichter als mit C „pur“. Der Grund: C++ bietet einige Erleichterungen, v. a. bei der Datenein- und Ausgabe, auch lassen sich die gefürchteten Pointer in der Anfangsphase umgehen. Im letzten Kapitel dieses Teils erhalten Sie eine kurze Einführung in die Objektorientierte Programmierung (OOP).
6 Grundlagen Eine Programmiersprache ist im Wesentlichen durch zwei Themenbereiche gekennzeichnet: x Datenstrukturen x Programm-Ablaufstrukturen Mit „Datenstrukturen“ werden die verschiedenen Organisationsmöglichkeiten von Daten beschrieben. Der Programmierer muss sich sehr gut überlegen, welche Datenstrukturen am ehesten seinem Problem angepasst sind. So kann es in dem einen Fall günstig sein, skalare Einzelwerte zu verarbeiten, während in einem anderen Fall die Zusammenfassung von Daten zu Feldern (z. B. Vektoren, Matrizen), Verbunden (z. B. Adressen von Studenten) oder ganzen Dateien (z. B. ein eine komplette Serie von Messwerten) erheblich sinnvoller ist. „Ablaufstrukturen“ kennzeichnen die Möglichkeiten, vom linearen Ablauf des Programms abzuweichen und Schleifen oder Verzweigungen durchzuführen. Der Programmierer muss anhand der von der Sprache unterstützten Ablaufstrukturen entscheiden, welche zur Lösung der jeweiligen Aufgabe optimal geeignet ist. Bei größeren Programmen sollte dies mit Hilfe von Struktogrammen geschehen, wie im Teil I vorgestellt.
6.1 Einführende Beispiele Das klassische Programm, mit dem jeder C/C++-Lehrgang beginnt, sieht etwa so aus: // BSP_6_1_1 (Dies ist eine Kommentarzeile) #include #include // fuer getchar() using namespace std; int main(void) { cout radius; // Tastatureingabe while(radius != 0) // while-Schleife von { bis } { // Kugelberechnung Volumen = 4.0 / 3.0 * M_PI * radius * radius * radius; Oberflaeche = 4.0 * M_PI * radius * radius; cout "; cin >> c ; i = toupper(c); ... o später keine zusätzlichen Abfragen für „j“ und „n“ nötig.
64
7 Vordefinierte Standard-Datentypen
Beispiel 2 ... char c; int i; ... cout > c; i = isdigit(c); if(i != 0) cout i >> k; l1 = i == k; cout "; cin >> a;
Bildschirm: Gib Zahl ein > n Eingabe-Cursorposition Anmerkung:
Häufig schreibt man die beiden C++-Anweisungen in eine Zeile, um damit die „Prompt-Eingabe“ zu verdeutlichen.
Statt endl kann man alternativ die Escape-Sequenz '\n' benutzen. endl ist vorzuziehen, da es automatisch, je nach Bedarf des Betriebssystems, ein '\n' oder ein "\n\r" generiert. Die Sprache C (ohne ++) kennt jedoch kein endl! Der Manipulator flush leert den Puffer ohne Zeilenvorschub. C++ Manipulatoren zur Ausgabepufferleerung
endl Leeren des Puffers plus Zeilenvorschub flush Leeren des Puffers ohne Zeilenvorschub Beispiele cout ist der überladene Rechtsshiftoperator (Operatorüberladung, o s. Kap. 13). Überladene C++ Operatoren zur Standard-Ein/Ausgabe
79
Eingabeoperator (Eingabe-Transferoperator)
Neben cin und cout unterstützt die IOStream-Bibliothek von C++ noch weitere StandardStreams, d. h. Streams die normalerweise mit Tastatur und Bildschirm verbunden sind. Standard Streams Stream
Anwendung
standardmäßig verbunden mit
cin
Standard-Eingabe
Tastatur
cout
Standard-Ausgabe
Bildschirm
clog
Standard-Protokoll
Bildschirm
cerr
Standard-Fehlerausgabe
Bildschirm
clog stellt eine Alternative zu cout dar. clog ist immer ungepuffert. clog eignet sich damit besonders für Testausgaben bei der Programmentwicklung. Beispiel clog
0
1
2
3
.... n-1
n
vz
0
1
2
.... n-2
n-1
n-1
.....
.1
0
m Index von text[] m Umspeicherung von text[], falls „–“ m Index von ziffer[]
strlen(text) liefert die Länge.
In der Ausgaberoutine wird das Ziffernfeld nach einem eventuell auftretenden „–“ in umgekehrter Reihenfolge geschrieben. Testen Sie zunächst die Klasse mit einem Default-Konstruktor, indem Sie lediglich große Zahlen ein- und ausgeben. Bei der Addition werden addiert: das aktuelle Objekt (*this) und ein Objekt, das als Parameter übergeben wird. Das Ergebnis ist wieder ein Objekt der Klasse BigInt. Es wird in der Methode erzeugt und mit return zurückgegeben. Beachten Sie die Überträge bei der Addition der einzelnen Stellen. Behandlung von Überträgen: Nach der Zifferaddition können in den Feldelementen Werte > 10 oder, bei negativen Zahlen, < 0 vorkommen. Daher wird nach jeder Addition eine Methode normiere()aufgerufen, die das Ergebnisfeld der Ziffern so korrigiert, dass nur Ziffern 0 ziffernweise: 00
normiere(): 1
00 000
2 3
01 04
00 06
27 36 54 12 16 24 ---------------12 43 60 54 06 09 05 04
0 * +
1 4
00 m Index k 09
m Werte für Index(k+i)
Die Umsetzung resultiert in einer Doppelschleife: for(i=0; i> y; if(x < 1 || y < 1) // falls x oder y < 1 sind { cout > liter; if(km > 0) { verbrauch = (liter / km) * 100; // Berechnung des // Verbrauchs pro 100 km cout 0 && r2 > 0) // r1 > 0 und r2 > 0 { r_ges = 1 / r1 + 1 / r2; r_ges = 1 / r_ges; cout sl3; if(sl1 > 0 && sl2 > 0 && sl3 > 0) // alle Seiten > 0 { inhalt = sl1 * sl2 * sl3; // Berechnungen oberflaeche = sl1 * sl2 * 2 + sl1 * sl3 * 2 + sl2 * sl3 * 2; cout