Top Banner

of 488

Programmkonstruktion

Feb 10, 2018

Download

Documents

Hrvoje Ljubic
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
  • 7/22/2019 Programmkonstruktion

    1/487

    PK13W

    Skriptum zu

    PROGRAMMKONSTRUKTION

    185.A02 Grundlagen der Programmkonstruktion183.592 Programmierpraxis

    im Wintersemester 2013/2014

    Franz Puntigam Fakultt fr InformatikMichael Reiter Technische Universitt Wien

  • 7/22/2019 Programmkonstruktion

    2/487

    2

  • 7/22/2019 Programmkonstruktion

    3/487

    Inhaltsverzeichnis

    1 Maschinen und Programme 111.1 Ein Java-Programm. . . . . . . . . . . . . . . . . . . . . . 12

    1.1.1 Simulierte Objekte . . . . . . . . . . . . . . . . . . 121.1.2 Programmablauf . . . . . . . . . . . . . . . . . . . 16

    1.2 Binre Digitale Systeme . . . . . . . . . . . . . . . . . . . 201.2.1 Entstehung der Digitaltechnik . . . . . . . . . . . . 201.2.2 Binre Systeme . . . . . . . . . . . . . . . . . . . . 221.2.3 Rechnen mit Binrzahlen. . . . . . . . . . . . . . . 241.2.4 Logische Schaltungen . . . . . . . . . . . . . . . . . 29

    1.3 Maschinen und Architekturen . . . . . . . . . . . . . . . . 311.3.1 Architektur blicher Computer . . . . . . . . . . . 311.3.2 Abstrakte Maschinen und Modelle. . . . . . . . . . 341.3.3 Objekte als Maschinen . . . . . . . . . . . . . . . . 37

    1.3.4 Softwarearchitekturen . . . . . . . . . . . . . . . . 381.4 Formale Sprachen, bersetzer und Interpreter . . . . . . . 401.4.1 Syntax, Semantik und Pragmatik . . . . . . . . . . 401.4.2 Bestandteile eines Programms . . . . . . . . . . . . 431.4.3 Compiler und Interpreter. . . . . . . . . . . . . . . 451.4.4 bersetzung und Ausfhrung . . . . . . . . . . . . 48

    1.5 Denkweisen . . . . . . . . . . . . . . . . . . . . . . . . . . 501.5.1 Sprachen, Gedanken und Modelle . . . . . . . . . . 511.5.2 Der Lambda-Kalkl. . . . . . . . . . . . . . . . . . 56

    1.5.3 Eigenschaften des Lambda-Kalkls . . . . . . . . . 601.5.4 Zusicherungen und Korrektheit . . . . . . . . . . . 63

    1.6 Softwareentwicklung . . . . . . . . . . . . . . . . . . . . . 661.6.1 Softwarelebenszyklus . . . . . . . . . . . . . . . . . 661.6.2 Ablauf und Werkzeuge der Programmierung . . . . 681.6.3 Softwarequalitt. . . . . . . . . . . . . . . . . . . . 701.6.4 Festlegung von Softwareeigenschaften . . . . . . . . 73

    1.7 Programmieren lernen . . . . . . . . . . . . . . . . . . . . 751.7.1 Kontrollfragen. . . . . . . . . . . . . . . . . . . . . 77

    3

  • 7/22/2019 Programmkonstruktion

    4/487

    Inhaltsverzeichnis

    2 Grundlegende Sprachkonzepte 812.1 Die Basis . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

    2.1.1 Vom Algorithmus zum Programm . . . . . . . . . . 81

    2.1.2 Variablen und Zuweisungen . . . . . . . . . . . . . 862.1.3 Datentypen . . . . . . . . . . . . . . . . . . . . . . 912.2 Ausdrcke und Operatoren. . . . . . . . . . . . . . . . . . 95

    2.2.1 Allgemeines . . . . . . . . . . . . . . . . . . . . . . 952.2.2 Operatoren in Java . . . . . . . . . . . . . . . . . . 1002.2.3 Typumwandlungen und Literale . . . . . . . . . . . 109

    2.3 Blcke und bedingte Anweisungen. . . . . . . . . . . . . . 1152.3.1 Blcke . . . . . . . . . . . . . . . . . . . . . . . . . 1152.3.2 Selektion mit if-else . . . . . . . . . . . . . . . . 118

    2.3.3 Mehrfach-Selektion mit derswitch-Anweisung . . 1202.4 Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . 1222.4.1 Methodendefintion anhand eines Beispiels . . . . . 1232.4.2 Beispiel einer Aufrufsequenz . . . . . . . . . . . . . 1272.4.3 Rekursive Methoden . . . . . . . . . . . . . . . . . 1302.4.4 Zusicherungen. . . . . . . . . . . . . . . . . . . . . 133

    2.5 Schleifen und Arrays . . . . . . . . . . . . . . . . . . . . . 1352.5.1 while- und do-while-Schleifen . . . . . . . . . . 1372.5.2 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . 138

    2.5.3 for-Schleifen . . . . . . . . . . . . . . . . . . . . . 1422.5.4 Beispiel: Pascalsches Dreieck. . . . . . . . . . . . . 144

    2.6 Zustnde. . . . . . . . . . . . . . . . . . . . . . . . . . . . 1492.6.1 Seiteneffekte. . . . . . . . . . . . . . . . . . . . . . 1492.6.2 Funktionen und Prozeduren in Pascal . . . . . . . . 1502.6.3 Methoden mit Seiteneffekten in Java . . . . . . . . 1542.6.4 Funktionaler und prozeduraler Programmierstil . . 157

    2.7 Kommunikation mit der Auenwelt . . . . . . . . . . . . . 1582.7.1 Die Methodemain . . . . . . . . . . . . . . . . . . 158

    2.7.2 Einlesen und Ausgeben . . . . . . . . . . . . . . . . 1602.7.3 Transformatorische und reaktive Systeme. . . . . . 163

    2.8 Java-Grundlagen lernen . . . . . . . . . . . . . . . . . . . 1652.8.1 Kontrollfragen. . . . . . . . . . . . . . . . . . . . . 166

    3 Objektorientierte Konzepte 1713.1 Das Objekt . . . . . . . . . . . . . . . . . . . . . . . . . . 171

    3.1.1 Abstrakte Sichtweisen . . . . . . . . . . . . . . . . 1713.1.2 Faktorisierung: Prozeduren und Objekte . . . . . . 175

    4

  • 7/22/2019 Programmkonstruktion

    5/487

    Inhaltsverzeichnis

    3.1.3 Datenabstraktion . . . . . . . . . . . . . . . . . . . 1773.2 Die Klasse und ihre Instanzen . . . . . . . . . . . . . . . . 181

    3.2.1 Variablen und Methoden . . . . . . . . . . . . . . . 181

    3.2.2 Sichtbarkeit . . . . . . . . . . . . . . . . . . . . . . 1853.2.3 Identitt und Gleichheit . . . . . . . . . . . . . . . 1893.2.4 Kontext und Initialisierung. . . . . . . . . . . . . . 1933.2.5 Konstanten . . . . . . . . . . . . . . . . . . . . . . 197

    3.3 Interfaces und dynamisches Binden . . . . . . . . . . . . . 1993.3.1 Interfaces zur Schnittstellenbeschreibung . . . . . . 1993.3.2 Dynamisches Binden . . . . . . . . . . . . . . . . . 2053.3.3 Spezialisierung und Ersetzbarkeit . . . . . . . . . . 210

    3.4 Vererbung . . . . . . . . . . . . . . . . . . . . . . . . . . . 213

    3.4.1 Ableitung von Klassen . . . . . . . . . . . . . . . . 2133.4.2 Klassen versus Interfaces . . . . . . . . . . . . . . . 2183.4.3 Von Object abwrts. . . . . . . . . . . . . . . . . . 222

    3.5 Quellcode als Kommunikationsmedium . . . . . . . . . . . 2263.5.1 Namen, Kommentare und Zusicherungen . . . . . . 2273.5.2 Faktorisierung, Zusammenhalt und Kopplung . . . 2323.5.3 Ersetzbarkeit und Verhalten . . . . . . . . . . . . . 235

    3.6 Objektorientiert programmieren lernen . . . . . . . . . . . 2373.6.1 Kontrollfragen. . . . . . . . . . . . . . . . . . . . . 239

    4 Daten, Algorithmen und Strategien 2434.1 Begriffsbestimmungen . . . . . . . . . . . . . . . . . . . . 243

    4.1.1 Algorithmus . . . . . . . . . . . . . . . . . . . . . . 2434.1.2 Datenstruktur. . . . . . . . . . . . . . . . . . . . . 2454.1.3 Lsungsstrategie . . . . . . . . . . . . . . . . . . . 248

    4.2 Rekursive Datenstrukturen und Methoden . . . . . . . . . 2504.2.1 Verkettete Liste . . . . . . . . . . . . . . . . . . . . 2504.2.2 Rekursion versus Iteration . . . . . . . . . . . . . . 254

    4.2.3 Binrer Baum . . . . . . . . . . . . . . . . . . . . . 2584.3 Algorithmische Kosten . . . . . . . . . . . . . . . . . . . . 264

    4.3.1 Abschtzung algorithmischer Kosten . . . . . . . . 2654.3.2 Kosten im Zusammenhang . . . . . . . . . . . . . . 2684.3.3 Zufall und Wahrscheinlichkeit . . . . . . . . . . . . 271

    4.4 Teile und Herrsche . . . . . . . . . . . . . . . . . . . . . . 2744.4.1 Das Prinzip . . . . . . . . . . . . . . . . . . . . . . 2744.4.2 Pragmatische Sichtweise . . . . . . . . . . . . . . . 2774.4.3 Strukturelle hnlichkeiten . . . . . . . . . . . . . . 279

    5

  • 7/22/2019 Programmkonstruktion

    6/487

    Inhaltsverzeichnis

    4.5 Abstraktion und Generizitt . . . . . . . . . . . . . . . . . 2824.5.1 Generische Datenstrukturen . . . . . . . . . . . . . 2824.5.2 Gebundene Generizitt . . . . . . . . . . . . . . . . 286

    4.5.3 Abstraktionen ber Datenstrukturen . . . . . . . . 2894.5.4 Iteratoren . . . . . . . . . . . . . . . . . . . . . . . 2924.6 Typische Lsungsstrategien . . . . . . . . . . . . . . . . . 298

    4.6.1 Vorgefertigte Teile . . . . . . . . . . . . . . . . . . 2984.6.2 Top-Down versus Bottom-Up . . . . . . . . . . . . 3014.6.3 Schrittweise Verfeinerung. . . . . . . . . . . . . . . 304

    4.7 Strukturen programmieren lernen . . . . . . . . . . . . . . 3064.7.1 Kontrollfragen. . . . . . . . . . . . . . . . . . . . . 307

    5 Qualittssicherung 3115.1 Spezifikationen . . . . . . . . . . . . . . . . . . . . . . . . 3115.1.1 Anforderungsspezifikation und Anwendungsflle . . 3125.1.2 Design-by-Contract . . . . . . . . . . . . . . . . . . 3145.1.3 Abstraktion und Intuition . . . . . . . . . . . . . . 317

    5.2 Statisches Programmverstndnis. . . . . . . . . . . . . . . 3215.2.1 Typen und Zusicherungen . . . . . . . . . . . . . . 3215.2.2 Schleifeninvarianten. . . . . . . . . . . . . . . . . . 3245.2.3 Termination . . . . . . . . . . . . . . . . . . . . . . 327

    5.2.4 Beweise und deren Grenzen . . . . . . . . . . . . . 3305.3 Testen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3335.3.1 Auswirkungen auf Softwarequalitt . . . . . . . . . 3335.3.2 Testmethoden . . . . . . . . . . . . . . . . . . . . . 3365.3.3 Laufzeitmessungen . . . . . . . . . . . . . . . . . . 339

    5.4 Nachvollziehen des Programmablaufs . . . . . . . . . . . . 3425.4.1 Stack-Traces und Debug-Output. . . . . . . . . . . 3435.4.2 Debugger . . . . . . . . . . . . . . . . . . . . . . . 3465.4.3 Eingrenzung von Fehlern . . . . . . . . . . . . . . . 348

    5.5 Ausnahmebehandlung . . . . . . . . . . . . . . . . . . . . 3515.5.1 Abfangen von Ausnahmen . . . . . . . . . . . . . . 3525.5.2 Umgang mit Ausnahmefllen . . . . . . . . . . . . 3555.5.3 Aufrumen . . . . . . . . . . . . . . . . . . . . . . 360

    5.6 Validierung . . . . . . . . . . . . . . . . . . . . . . . . . . 3635.6.1 Validierung von Daten . . . . . . . . . . . . . . . . 3635.6.2 Validierung von Programmen . . . . . . . . . . . . 365

    5.7 Qualitt sichern lernen . . . . . . . . . . . . . . . . . . . . 3685.7.1 Kontrollfragen. . . . . . . . . . . . . . . . . . . . . 369

    6

  • 7/22/2019 Programmkonstruktion

    7/487

    Inhaltsverzeichnis

    6 Vorsicht: Fallen! 3736.1 Beschrnkte Ressourcen . . . . . . . . . . . . . . . . . . . 373

    6.1.1 Speicherverwaltung . . . . . . . . . . . . . . . . . . 373

    6.1.2 Dateien und Co . . . . . . . . . . . . . . . . . . . . 3776.1.3 Antwortzeiten . . . . . . . . . . . . . . . . . . . . . 3836.2 Grenzwerte . . . . . . . . . . . . . . . . . . . . . . . . . . 387

    6.2.1 Umgang mit ganzen Zahlen . . . . . . . . . . . . . 3876.2.2 Rundungsfehler . . . . . . . . . . . . . . . . . . . . 3916.2.3 Null . . . . . . . . . . . . . . . . . . . . . . . . . . 3966.2.4 Off-by-One-Fehler und Pufferberlufe . . . . . . . 400

    6.3 Nebenlufigkeit . . . . . . . . . . . . . . . . . . . . . . . . 4036.3.1 Parallelitt und Nebenlufigkeit . . . . . . . . . . . 404

    6.3.2 Race-Conditions und Synchronisation . . . . . . . . 4086.3.3 Gegenseitige Behinderung . . . . . . . . . . . . . . 4126.4 Einfachheit und Flexibilitt . . . . . . . . . . . . . . . . . 415

    6.4.1 Strukturierte Programmierung. . . . . . . . . . . . 4156.4.2 Typische Fallen objektorientierter Sprachen . . . . 4196.4.3 Spezielle Fallen in Java . . . . . . . . . . . . . . . . 422

    6.5 Vertrauen und Kontrolle . . . . . . . . . . . . . . . . . . . 4266.5.1 Defensive und offensive Programmierung . . . . . . 4266.5.2 Programmierstil und Vertrauen . . . . . . . . . . . 429

    6.5.3 Einheitliche Regeln . . . . . . . . . . . . . . . . . . 4326.6 Mythen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433

    6.6.1 Paradigmen und Mythen . . . . . . . . . . . . . . . 4356.6.2 Mythen in Java . . . . . . . . . . . . . . . . . . . . 440

    6.7 Fallen umgehen lernen . . . . . . . . . . . . . . . . . . . . 4446.7.1 Kontrollfragen. . . . . . . . . . . . . . . . . . . . . 444

    7 Information und rohe Daten 4497.1 Informationsbegriff nach Shannon . . . . . . . . . . . . . . 449

    7.1.1 Informationsgehalt als statistische Eigenschaft . . . 4507.1.2 Entropie . . . . . . . . . . . . . . . . . . . . . . . . 4527.1.3 Codierung . . . . . . . . . . . . . . . . . . . . . . . 4547.1.4 Betrachtungsebenen der Information . . . . . . . . 456

    7.2 Redundanz und Information . . . . . . . . . . . . . . . . . 4587.2.1 Datenkompression . . . . . . . . . . . . . . . . . . 4597.2.2 Verschlsselung und Information . . . . . . . . . . 4617.2.3 Information in Programmen . . . . . . . . . . . . . 463

    7.3 Interne Darstellung primitiver Werte . . . . . . . . . . . . 466

    7

  • 7/22/2019 Programmkonstruktion

    8/487

    Inhaltsverzeichnis

    7.3.1 Zahlen . . . . . . . . . . . . . . . . . . . . . . . . . 4677.3.2 Zeichen . . . . . . . . . . . . . . . . . . . . . . . . 4697.3.3 Abstrakte Werte . . . . . . . . . . . . . . . . . . . 473

    7.4 Interna der JVM . . . . . . . . . . . . . . . . . . . . . . . 4757.4.1 Speicher der JVM. . . . . . . . . . . . . . . . . . . 4757.4.2 Interne Darstellung von Objekten und Klassen . . . 4777.4.3 Dynamisches Binden mittels Methodentabelle . . . 478

    7.5 Information in Objekten . . . . . . . . . . . . . . . . . . . 4807.5.1 Datenabstraktion . . . . . . . . . . . . . . . . . . . 4807.5.2 Untertypbeziehungen . . . . . . . . . . . . . . . . . 481

    7.6 Externe Darstellung. . . . . . . . . . . . . . . . . . . . . . 4827.6.1 Serialisierung . . . . . . . . . . . . . . . . . . . . . 483

    7.6.2 Lesbare externe Darstellung . . . . . . . . . . . . . 4857.7 Information und Daten verstehen lernen . . . . . . . . . . 4867.7.1 Kontrollfragen. . . . . . . . . . . . . . . . . . . . . 487

    8

  • 7/22/2019 Programmkonstruktion

    9/487

    Vorwort

    Das Modul Programmkonstruktionbildet die Basis der Programmieraus-bildung in den Bachelorstudien der Informatik und Wirtschaftsinformatikan der TU Wien. Dieses Modul umfasst zwei Lehrveranstaltungen:Grund-lagen der Programmkonstruktion (PK) undProgrammierpraxis (PP).

    PK gibt einen berblick ber die Programmierung im weitesten Sinn.Man erhlt einen ersten Einblick in zahlreiche Themen, von denen vielespter im Studium genauer behandelt werden. Die Themen werden zuein-ander in Beziehung gesetzt. Auf dieser Grundlage fllt das sptere tiefeEintauchen leichter. Auerdem soll einer zu engen Sichtweise der Program-mierung schon von Beginn des Studiums an entgegengewirkt werden.

    In PP werden praktische Programmierfhigkeiten entwickelt. Studie-rende sollen die Fhigkeit erwerben, Programmieraufgaben selbstndiganhand mehr oder weniger genauer Spezifikationen so zu lsen, dass be-stimmte Qualittskriterien eingehalten werden.

    Es wird dringend empfohlen, die beiden Lehrveranstaltungen ganz zuBeginn des Studiums zusammen zu absolvieren. In PK werden unter an-derem Konzepte eingefhrt, die zeitlich abgestimmt in PP praktisch an-zuwenden sind. Auch nicht unmittelbar vorausgesetztes Wissen aus PKkann die Qualitt der Lsungen praktischer Programmieraufgaben in PP

    verbessern. Umgekehrt helfen zuvor in PP erworbene Fhigkeiten beimVerstndnis komplexer Zusammenhnge in PK.Das vorliegende Skriptum deckt das Stoffgebiet von PK ab, ist also als

    Skriptum fr PK zu verstehen. Aber auch in PP wird von der Kenntnisgroer Teile dieses Skriptums ausgegangen. Das Skriptum ist daher frStudierende beider Lehrveranstaltungen vorgesehen.

    Das Skriptum ist zyklisch aufgebaut. Wichtige Themen werden frh an-gesprochen und spter tiefergehend erlutert, machmal sogar mehrfach.Diese Struktur soll Anfnger(inne)n entgegenkommen, macht das Skrip-

    tum aber kaum dafr geeignet, bestimmte Themen rasch nachzuschlagen.Den in PK gebrachten Stoff kann man sich, bei entsprechendem Bem-

    hen auch ohne Programmier-Vorkenntnisse, in der vorgesehenen Zeit voneinem Semester aneignen. Die Entwicklung praktischer Fhigkeiten kanndagegen, je nach Veranlagung und Vorkenntnissen, deutlich lnger dauern.Daher darf man fr PP bis zu zwei Semestern brauchen. Trotz flexiblerPlanungsmglichkeiten wird dazu geraten, gleich zu Studienbeginn in PPeinzusteigen und einen Schwerpunkt darauf zu legen. Sonst geht es sichauch mit zwei Semestern mglicherweise nicht aus.

    9

  • 7/22/2019 Programmkonstruktion

    10/487

    Viele Studienanfnger(innen) bringen schon Programmier-Wissen mit.Dennoch wird empfohlen, sich intensiv mit PK und PP auseinanderzuset-zen. Am Anfang mgen die Themen als sehr einfach erscheinen, aber im

    Laufe der Zeit steigt die Komplexitt rasch an. Man bersieht leicht denZeitpunkt, ab dem das Vorwissen alleine nicht mehr ausreicht.Das Modul Programmkonstruktion ist Teil der Studieneingangs- und

    Orientierungsphase (STEOP). Eine positive Absolvierung ist Vorausset-zung fr die Teilnahme an Lehrveranstaltungen ab dem dritten Semester.Man kann dies als Hrde sehen, die bersprungen werden muss, bevor manZugang zu den komplexeren Themengebieten bekommt. Neben der Hrdesollte man jedoch auch die Chancen sehen: Die Programmierausbildunghat einen hohen Stellenwert. Von Studierenden werden gute Program-

    mierkenntnisse erwartet, es wird ihnen aber auch viel Untersttzung beimLernen geboten. Das Ziel ist ein hohes Niveau an Wissen und Knnen.Die besten Leistungen lassen sich nur mit viel Einsatz und Enthusias-

    mus erzielen. Knftige Informatiker(innen) bringen in der Regel viel Be-geisterung fr das Programmieren mit. Es ist ein gutes Gefhl, wenn maneigene Gedanken und Ideen in Software real werden lassen kann. Manch-mal knnen uns Fehler in einem Programm oder Schwierigkeiten beimVerstehen komplexer Zusammenhnge jedoch auch fast zur Verzweiflungtreiben. Das gehrt genauso dazu wie die Freude darber, wenn am Ende

    dennoch alles funktioniert. Programmieren ist keineswegs eine so emoti-onslose Angelegenheit, wie man gelegentlich suggeriert bekommt. Nur werselbst Programme schreibt, kann die Begeisterung dafr verstehen. Wieso oft steht am Anfang ein manchmal schwieriger Lernprozess mit vielenkleinen Erfolgen, aber auch so manchem Rckschlag. Wer genug Durch-haltevermgen aufbringt um den Lernprozess zu meistern und sich von derBegeisterung anstecken lsst, wird beim Programmieren sicher viel Freudeerleben. Das ist die eigentliche Triebfeder, die zu einem hohen Niveau anWissen und Knnen fhrt.

    Lassen Sie sich von der Begeisterung fr das Programmieren anstecken!

    Viel Freude und Erfolg beim Programmierenlernen!

    Franz PuntigamMichael Reiter

    10

  • 7/22/2019 Programmkonstruktion

    11/487

    1 Maschinen und Programme

    UnterProgrammierenversteht man heute meist die Ttigkeit des Erstel-lens von Computerprogrammen. Genau darum geht es bei Grundlagender Programmkonstruktion (PK)und Programmierpraxis (PP): Wir wol-len lernen, wie man Computerprogramme schreibt, also einer Maschine dientigen Anweisungen gibt, damit sie das macht, was wir von ihr wollen.

    Auf den ersten Blick ist Programmieren tatschlich so einfach: Es reicht,die wenigen grundlegenden Anweisungen einer Maschine zu kennen undauf geeignete Weise aneinanderzureihen. Kleine Programme werden wirbald verstehen und entwickeln knnen. Hier ist das erste Java-Programm:

    Listing 1.1: Java-Programm zur Ausgabe von Hello World!

    1 public class Hello {2 public static void main(String[] args) {3 System.out.println("Hello World!");4 }

    5 }

    Dieses Programm (ohne die zur besseren Lesbarkeit vorangestellten Zei-lennummern) brauchen wir nur mehr in der Datei Hello.javazu spei-chern, mit dem Befehl javac Hello.java zu bersetzen und mitdem Befehl java Hello auszufhren. Schon haben wir eine Maschinezum Leben erweckt und dazu gebracht, mit der Welt in Kontakt zu treten.

    Zahlreiche Schwierigkeiten zeigen sich erst auf den zweiten Blick: Eintypisches Programm reiht viele Tausend oder Millionen Anweisungen an-

    einander, und jeder noch so kleine Fehler kann schwerwiegende Folgennach sich ziehen. Es ist nicht leicht, den berblick ber ein riesiges Netz-werk an Anweisungen zu bewahren oder herauszufinden, welchen Zweckeine einzelne Anweisung darin hat. Zudem ndern sich die Wnsche andas Programm im Laufe der Zeit ebenso wie die Maschinen, auf denen dasProgramm laufen soll. Auch die Personen, die das Programm erstellen undweiterentwickeln, bleiben nicht immer dieselben. Nur mit viel Wissen, ge-schultem abstraktem Denkvermgen und durchdachten Vorgehensweisenist es mglich, die groe Komplexitt zu meistern.

    11

  • 7/22/2019 Programmkonstruktion

    12/487

    1 Maschinen und Programme

    Wir wollen in PK und PP daher auch

    Zusammenhnge zwischen Maschinen, Programmen und den in die

    Entwicklung und Anwendung von Programmen involvierten Perso-nen sowie ihrem Umfeld betrachten (PK),

    grundlegende Konzepte und Aussagen der Informatik im Bereich derProgrammierung einfhren und deren Auswirkungen auf konkreteProgrammiersprachen und Programmierstile veranschaulichen (PK),

    Techniken, Werkzeuge und Vorgehensweisen kennenlernen, die unsbei der Erstellung hochwertiger Programme untersttzen (PK+PP),

    durch Lsen von Programmieraufgaben das handwerkliche Geschickund abstrakte Denkvermgen weiterentwickeln (hauptschlich PP).

    1.1 Ein Java-Programm

    Zur Einstimmung betrachten wir ein kleines Programm in Java und typi-sche Merkmale davon. Es ist noch nicht ntig, alle Details zu verstehen.Vorerst wollen wir nur ein Gespr fr das Aussehen von Programmen so-wie die Terminologie und die Konzepte der Programmierung bekommen.

    Erst spter werden wir lernen, solche Programme selbst zu entwickeln.

    1.1.1 Simulierte Objekte

    Java ist eine objektorientierte Programmiersprache, das heit, Software-Objekte oder kurz Objekte stehen im Mittelpunkt der Programmierung.Ein Software-Objektsimuliertein Objekt aus der realen Welt. Alle Ar-ten von Objekten knnen simuliert werden, gegenstndliche Objekte wieBume, Autos und Huser, aber auch abstrakte Objekte wie Zahlen und

    Mengen, also alles, was tatschlich oder in unserer Vorstellung existiert.Objekte werden in Java nicht direkt, sondern durchKlassendargestellt.

    Eine Klasse beschreibt gleichartige Objekte. Beispielsweise beschreibt eineKlasse Baumdie Bume einer Allee, und jeder einzelne Alleebaum gehrtzur KlasseBaum. Statt ein Objekt gehrt zur Klasse sagt man auch einObjekt ist Instanz der Klasse, also ein bestimmter Alleebaum ist eineInstanz von Baum. In Java ist jedes Objekt Instanz irgendeiner Klasse.

    Listing1.2zeigt den Programmcode der Klasse UnbekannteZahl. Je-de Instanz davon stellt eine auerhalb dieses Objekts unbekannte Zahl dar,

    12

  • 7/22/2019 Programmkonstruktion

    13/487

    1.1 Ein Java-Programm

    Listing 1.2: Kapsel, die eine Zahl und Vergleichsmethoden enthlt

    1 import java.util.Random;2

    3 public class UnbekannteZahl {4 // die Zahl ist nur innerhalb der Klasse bekannt5 private int zahl;67 // Initialisierung mit Zufallszahl zwischen 0 und (grenze - 1)8 // Voraussetzung: grenze > 09 public UnbekannteZahl(int grenze) {

    10 zahl = (new Random()).nextInt() % grenze;11 if (zahl < 0) {12 zahl = zahl + grenze;13 }

    14 }1516 // Ergebnis von "gleich(n)" ist true wenn zahl gleich n ist17 public boolean gleich(int vergleichszahl) {18 return (zahl == vergleichszahl);19 }2021 // Ergebnis von "kleiner(n)" ist true wenn zahl kleiner n ist22 public boolean kleiner(int vergleichszahl) {23 return (zahl < vergleichszahl);24 }

    25 }

    die aber innerhalb des Objekts sehr wohl bekannt ist. Man unterscheidetdie Innen- von der Auenansicht. Vor einem Betrachter von auen sindviele Details versteckt. Im Programmcode findet man die Wrterpublicundprivate. Alles wasprivateist, kann man nur innerhalb der Klas-se sehen, whrend alles was public ist, berall im Programm sichtbar ist.Im Rumpfder berall sichtbaren Klasse, das ist alles was innerhalb der

    geschwungenen Klammern nachclass UnbekannteZahl steht (Zeilen424), werden folgende Programmteile deklariert bzw. definiert:

    in Zeile 5 eine nur in der Klasse sichtbare Variablenamens zahl,

    in den Zeilen 9 bis 14 ein berall sichtbarerKonstruktormit demsel-ben Namen wie die Klasse, also UnbekannteZahl,

    in den Zeilen 17 bis 19 und 22 bis 24 zwei berall sichtbareMethodennamens gleichund kleiner.

    13

  • 7/22/2019 Programmkonstruktion

    14/487

    1 Maschinen und Programme

    Jeder Deklaration und Definition in dieser Klasse ist ein Kommentarvor-angestellt, das ist beliebiger Text zwischen // und dem Ende einer Zeile.Kommentare helfen Menschen dabei, das Programm zu verstehen, werden

    aber vom Computer in der Regel nicht beachtet.Die Deklaration in Zeile 5 legt die Sichtbarkeitprivate, denTypintund denNamenzahl einer Variablen fest. Eine Variable steht fr einen imLaufe der Zeit nderbaren (= variablen) Wert. Man sagt auch, sie enthltoder hateinen Wert. Beispielsweise hat die Variable zu einem Zeitpunktden Wert 87 und zu einem anderen Zeitpunkt den Wert 3. Der Wert selbstist in der Deklaration nicht festgelegt; genau deswegen spricht man nurvon einerDeklarationund keiner Definition. Der Typ legt die Art der Wer-te fest, welche die Variable haben kann. Die Variable zahlhat den Typ

    int eine Abkrzung fr das englischsprachige WortInteger, also ganzeZahl auf Deutsch. Ein anderer mglicher Typ wre boolean, der denBooleschen bzw. logischen Werten true(wahr) und false(falsch) ent-spricht. Aber auch der Name einer Klasse wie UnbekannteZahl kann alsTyp verwendet werden, sodass eine mit diesem Typ deklarierte VariableObjekte dieser Klasse enthalten kann. Generell spricht man von den In-stanzen eines Typswenn man alle Werte meint, die von diesem Typ sind.Ganze Zahlen sind demnach Instanzen von int, und true und falsesind Instanzen von boolean.

    Die Methodengleich undkleiner werdendefiniert,nicht nur dekla-riert, das heit, es werden alle Details festgelegt, und diese bleiben im Lau-fe der Zeit gleich. Die Methoden eines Objekts erlauben anderen Objekten,mit diesem Objekt in Kontakt zu treten. Man tritt mit einem Objekt inKontakt, indem man ihm eine Nachrichtschickt, und das Objekt beant-wortet die Nachricht. Die Klasse beschreibt ber Methoden die Nachrich-ten, welche die Objekte der Klasse verstehen, sowie das Objektverhalten,also das, was die Objekte machen, wenn sie solche Nachrichten empfangen.Obwohl der Wert der Variablen zahl in anderen Klassen nicht sichtbar

    ist, kann ber die berall sichtbaren Methoden gleich und kleineretwas ber diesen Wert herausgefunden werden. Sowohlgleichals auchkleinerliefert ein Ergebnis vom Typ booleanzurck, das heit, sol-che Nachrichten an ein Objekt von UnbekannteZahlwerden mittrueoder false beantwortet. Eine Nachricht gleich(3) fragt an, ob dieunbekannte Zahl gleich drei ist, und kleiner(3) ob die unbekannteZahl kleiner drei ist. Das funktioniert auch mit anderen Zahlen. Wertewie die Zahl 3, die als Teil einer Nachricht an ein Objekt geschickt wer-den, nennt manArgumenteoderaktuelle Parameterder Nachricht. Neben

    14

  • 7/22/2019 Programmkonstruktion

    15/487

    1.1 Ein Java-Programm

    der Sichtbarkeit, dem Ergebnistyp und dem Namen enthlt jede Definiti-on einer Methode eine Liste formaler Parameter-Deklarationenoder kurzParameter-Deklarationen in runden Klammern und einen Rumpf in ge-

    schwungenen Klammern. Die Deklaration eines formalen Parametersh-nelt der einer Variablen, jedoch fehlt die Sichtbarkeit. Eine Methode wirdin einem Objektausgefhrt,wenn das Objekt eine gleichnamige Nachrichtempfngt. Whrend dieser Ausfhrung enthalten die formalen Parameterdie Werte, die der Nachricht als Argumente mitgegeben wurden. Anzahlund Typen der Argumente mssen der Anzahl und den Typen der for-malen Parameter entsprechen. Bei der Ausfhrung einer Methode werdendie Anweisungen im Rumpf der Methode ausgefhrt, eine nach der an-deren von oben nach unten und von links nach rechts. Die Rmpfe der

    Methoden gleich und kleiner bestehen nur aus je einer return-Anweisung, die eine Antwort an den Sender einer Nachricht zurckgibt.Der zurckgegebene Boolesche Wert ergibt sich aus der Anwendung einesVergleichsoperators (== bzw.

  • 7/22/2019 Programmkonstruktion

    16/487

    1 Maschinen und Programme

    durchgrenzeberechnet. Wenn die Zufallszahl negativ war, ist auch derDivisionsrest negativ. Der an zahlzugewiesene Wert ist somit grer alsgrenze und kleiner als grenze. Die zweite Anweisung, eine bedingteAnweisung, sorgt dafr, dass der Wert von zahl nach Beendigung derAusfhrung des Konstruktors nicht kleiner 0 sein kann. Nur wenn der ak-tuelle Wert vonzahlkleiner 0 ist, das ist die Bedingungin der bedingtenAnweisung, wird die Anweisung zahl = zahl + grenze im Rumpfder bedingten Anweisung ausgefhrt. Dabei wird ein neuer Wert an zahlzugewiesen, der um den Wert von grenze grer ist als der alte Wert.Wie gewnscht ist der Wert von zahldanach sicher grer oder gleich 0und kleiner grenze.

    Die Variablezahl

    bildet zusammen mit dem Konstruktor und den Me-thoden von UnbekannteZahleine untrennbare Einheit. Erst durch dieMethoden wird die Variable sinnvoll verwendbar, und die Methoden brau-chen die Variable um ihre Aufgaben zu erfllen. Variablen und Methodensind quasi in eine gemeinsame Kapsel eingeschlossen. Die Eigenschaft einesObjekts, Variablen und Methoden zu einer Einheit zusammenzufhren,nennt manDatenkapselung.Zusammen mitData-Hiding,dem Versteckenvon Details durchprivate, spricht man vonDatenabstraktion.Wir kn-nen Objekte als abstrakte Einheiten betrachten, ohne wissen zu mssen,

    wie sie genau funktionieren. Auf solche abstrakte Weise haben wir einneues Objekt von Random verwendet: ber eine Nachricht erhalten wireine Zufallszahl, ohne zu wissen, wie sie ermittelt wird. Wir werden sehen:Abstraktion spielt in der Informatik eine sehr groe Rolle.

    1.1.2 Programmablauf

    Listing 1.3 zeigt den Programmcode der Klasse Zahlenraten, die ei-ne unbekannte Zahl in einem kleinen Spiel verwendet. Diese Klasse ist

    nicht dafr gedacht, dass Objekte von ihr erzeugt werden. Daher enthltder Rumpf weder Variablen-Deklarationen noch Konstruktor-Definitionen.Stattdessen enthlt die Klasse eine spezielle Methode namens main, in de-ren Definition das Wort staticklarstellt, dass die Methode zur Klasseselbst, aber nicht zu Objekten der Klasse gehrt. Aufgrund des Ergeb-nistyps void darf man auf eine entsprechende Nachricht keine Antworterwarten. Die Methodemain, die bis auf den Rumpf in jedem Programmso aussehen muss wie hier, definiert den Startpunkt des Programms. ImAllgemeinen enthlt der formale Parameter argsArgumente, die einem

    16

  • 7/22/2019 Programmkonstruktion

    17/487

    1.1 Ein Java-Programm

    Listing 1.3: Spiel zum Erraten der Zahl in einem Objekt von UnbekannteZahl

    1 import java.util.Scanner;2

    3 public class Zahlenraten {4 public static void main (String[] args) {5 UnbekannteZahl zuErraten = new UnbekannteZahl(100);6 Scanner sc = new Scanner(System.in);7 System.out.println("Errate eine Zahl zwischen 0 und 99:");8 while (sc.hasNext()) {9 if (sc.hasNextInt()) {

    10 int versuch = sc.nextInt();11 if (versuch < 0 || versuch > 99) {12 System.out.println("Nur Zahlen von 0 bis 99!");13 }

    14 else if (zuErraten.gleich(versuch)) {15 System.out.println("Gratulation! Zahl erraten!");16 return;17 }18 else if (zuErraten.kleiner(versuch)) {19 System.out.println("Gesuchte Zahl ist kleiner.");20 }21 else {22 System.out.println("Gesuchte Zahl ist grer.");23 }24 }

    25 else {

    26 sc.next();27 System.out.println("Das ist keine erlaubte Zahl!");28 }29 System.out.println("Neuer Versuch (Ende mit ^D):");30 }31 System.out.println("Zahl leider nicht erraten :-(");32 }33 }

    Programmaufruf mitgegeben werden knnen. In diesem Programm brau-chen wir keine solchen Argumente. Trotzdem muss der formale Parametervorhanden sein, weil die Sprachdefinition von Java das so vorsieht. Es istklar, warum wir eine spezielle Methode brauchen: Wenn ein Programm ge-startet wird, gibt es noch keine Objekte, sondern nur Klassen. Wir knnenzu Beginn also keinem Objekt eine Nachricht schicken um die Ausfhrungeiner Methode zu starten. Diese spezielle Methode wird ausgefhrt, ohnevorher eine Nachricht an ein Objekt schicken zu mssen.

    17

  • 7/22/2019 Programmkonstruktion

    18/487

    1 Maschinen und Programme

    Variablen knnen auch im Rumpf einer Methode deklariert werden. Sol-chelokalen Variablenexistieren nur whrend der Ausfhrung der Methodeund sind nur in dem Bereich (innerhalb der geschwungenen Klammern)

    sichtbar, in dem sie deklariert sind; daher brauchen wir auch keine Sicht-barkeit anzugeben. Die VariablezuErratenwird gleich in der Deklarati-on in Zeile 5 mit einem neuen Objekt von UnbekannteZahl im Wertebe-reich von 0 bis 99 initialisiert. In Zeile 6 wird eine lokale Variable sc vomTypScanner, einer ausjava.utilimportierten Klasse, deklariert undmit einem neuen Objekt initialisiert. Objekte von Scanneruntersttzendie Umwandlung von Eingaben ber Tastatur oder aus einer Datei in einDatenformat, das wir innerhalb des Programms bentigen. Dem Konstruk-tor von Scanner bergeben wir als Argument den Wert der Variablen

    System.in. Diese von unserem System vorgegebene Variable steht frdie Standard-Eingabe, die normalerweise mit einem Terminal verbundenist, also mit den ber die Tastatur erfolgten Eingaben in ein Fenster amBildschirm. Unser Objekt vonScannererlaubt uns das Einlesen ber dieTastatur eingegebener Daten in das Programm. In Zeile 7 verwenden wirmit System.outeine weitere vom System vorgegebene Variable, die frdie Standard-Ausgabe steht und normalerweise mit demselben Terminalverbunden ist. An den Wert dieser Variablen schicken wir die Nachrichtprintln(Abkrzung frPrint Line) um die Textzeile im Argument am

    Bildschirm auszugeben. Die Textzeile ist vom Typ String, das ist eineZeichenkette,also eine Folge beliebiger Zeichen eingeschlossen zwischen "am Anfang und Ende. Der ausgegebene Text fordert Benutzer(innen) desProgramms auf, eine Zahl einzutippen.

    Einewhile-Schleifebildet den Hauptteil der Methode (Zeilen 8 bis 30).Der Rumpf der Schleife wird so lange iteriert,also wiederholt ausgefhrt,solange dieSchleifenbedingung sc.hasNext() erfllt ist, das heit, soofthintereinander wie zu Beginn jeder Iteration (= Schleifendurchlauf) aufdie NachrichthasNext()an scdie Antworttruezurckgeliefert wird.

    Die Ausfhrung der Methode hasNext wird so lange warten, bis einenicht-leere Eingabe vorhanden ist, das heit im Wesentlichen, bis jemandber die Tastatur etwas anderes als nur Leerzeichen in das Terminal einge-geben und die Eingabe mit Enter abgeschlossen hat, oder die Standard-Eingabe (beispielsweise durch Eingabe von Control-d) geschlossen wird.Die Antwort ist true wenn eine nicht-leere Eingabe vorhanden ist undfalsewenn die Standard-Eingabe geschlossen wurde. Im ersten Fall wirdder Rumpf der Schleife ausgefhrt siehe unten. Im zweiten Fall wird derSchleifenrumpf nicht mehr durchlaufen, und die erste Anweisung nach der

    18

  • 7/22/2019 Programmkonstruktion

    19/487

    1.1 Ein Java-Programm

    Schleife in Zeile 31 informiert Benutzer(innen) durch eine Textausgabedarber, dass die gesuchte Zahl nicht gefunden wurde. Die Ausfhrungvon main und damit des ganzen Programms endet daraufhin, da es

    keine weiteren Anweisungen mehr gibt.Der Schleifenrumpf beginnt in Zeile 9 mit einer bedingten Anweisung.Diese hat zwei Rmpfe, die wir Zweigenennen. Der erste Zweig ab Zei-le 10 wird nur ausgefhrt wenn die Bedingung wahr ist, der zweite Zweigab Zeile 26, else-Zweig genannt, nur wenn die Bedingung falsch ist. Aufdie Nachricht hasNextInt() an sc in der Bedingung bekommen wirdie Antworttrue, wenn die nchste Eingabe von der wir schon wissen,dass sie existiert eine Zahl ist. Falls sie keine Zahl ist, kommen wir in denelse-Zweig. Dort wird durch die Nachricht next() an sc die nchste

    Eingabe gelesen und gelscht, damit danach nur mehr die darauf folgen-den Eingaben gesehen werden. Die Antwort auf diese Nachricht ignorierenwir, da wir damit nichts anfangen knnen. Stattdessen informieren wirBenutzer(innen) ber die falsche Eingabe. Falls die Eingabe eine Zahl ist,kommen wir in den ersten Zweig, wo die lokale Variable versuchmit derZahl aus der Eingabe initialisiert wird. Auch die Nachricht nextInt()an sc1 lscht die Eingabe, damit danach die darauf folgenden Eingabensichtbar sind. In diesem Zweig machen wir mehrereFallunterscheidungen,das heit, abhngig von verschiedenen Bedingungen wird einer von meh-

    reren mglichen Programmzweigen ausgefhrt. Falls die eingelesene Zahlnicht im erlaubten Wertebereich liegt, also versucheinen Wert kleiner 0oder grer 99 hat (||steht fr oder), informieren wir Benutzer(innen)darber. Andernfalls, falls wir die gesuchte Zahl gefunden haben, informie-ren wir Benutzer(innen) ber diese Tatsache und brechen das Programmab. Normalerweise bricht diereturn-Anweisung nur die Ausfhrung derMethode ab und bestimmt die Antwort der Methode, aber main liefert(wegen void) keine Antwort zurck und ist die spezielle Methode, mitder die Programmausfhrung beginnt und auch endet. Wir haben noch

    zwei mgliche Flle: In einem Fall ist die zu erratende Zahl kleiner und imanderen grer als die eingegebene Zahl. Benutzer(innen) werden jeweilsdarber informiert. Das Programm wird mit der nchsten Anweisung nach

    1Sowohl in Random (siehe Klasse UnbekannteZahl) als auch in Scanner gibt es eineMethode namens nextInt. Diese beiden Methoden haben aber nichts miteinander zutun. Gleiche Nachrichten an Objekte unterschiedlicher Typen knnen ganz unterschiedlicheEffekte haben. Wir knnen anhand der Typen von Variablen leicht unterscheiden, ob dieNachricht nextInt() an ein Objekt von Random oder Scanner (oder einer anderenKlasse) gerichtet ist.

    19

  • 7/22/2019 Programmkonstruktion

    20/487

    1 Maschinen und Programme

    der bedingten Anweisung fortgesetzt. Egal welche Zweige der bedingtenAnweisungen ausgefhrt wurden abgesehen von dem einen Fall, der zumProgrammabbruch fhrt landen wir immer bei der letzten Anweisung

    im Schleifenrumpf. Hier werden Benutzer(innen) durch eine Textausgabeaufgefordert, einen neuen Versuch zu starten. Danach wird die Ausfhrungmit der nchsten berprfung der Schleifenbedingung und gegebenenfallsder nchsten Iteration fortgesetzt.

    Um das Programm auszufhren erstellen wir zunchst die TextdateienUnbekannteZahl.javaund Zahlenraten.java, welche den Codein den Listings1.2und1.3(ohne Zeilennummern) enthalten. DiesenQuell-codemssen wir in einenZwischencodebersetzen, der dann durch einenInterpreteroder einevirtuelle Maschineausgefhrt wird. Dazu brauchen

    wir ein Terminal-Fenster, ber das wir Befehle an den Computer eingeben.Der Befehl javac UnbekannteZahl.java Zahlenraten.javaruft den Compilerauf, der aus den Quellcodedateien die Zwischencode-dateien UnbekannteZahl.class undZahlenraten.class erzeugt.Den Interpreter und das Spiel starten wir durch java Zahlenraten.

    Vor allem Leser ohne oder mit nur wenig Programmiererfahrung solltendas Spiel tatschlich ausprobieren und seine Funktionsweise zu verstehenversuchen. Manche Zusammenhnge werden klarer, wenn man kleine n-derungen vornimmt und schaut, wie sich diese auswirken. Falls das Pro-

    gramm nicht in allen Details verstndlich ist, so ist das jetzt noch keinProblem. Wir mssen wichtige Grundlagen und Konzepte der Program-mierung erst schrittweise einfhren. Dabei ist es aber hilfreich, wenn manzumindest schon einmal versucht hat, ein Programm zu verstehen.

    1.2 Binre Digitale Systeme

    Die Digitaltechnik bildet eine wesentliche Grundlage heutiger Computer

    und vieler anderer technischer Systeme. Digitale Systeme basieren ber-wiegend auf dem binren Zahlensystem, verwenden also die Zahl Zwei alsBasis, nicht die Zahl Zehn wie im gewohnten dezimalen Zahlensystem.

    1.2.1 Entstehung der Digitaltechnik

    Programmierbare Maschinen sind schon seit langem bekannt. Beispiels-weise stellen Falcons und Jacquards Erfindungen von ber Lochkartengesteuerten Websthlen Mitte des 18. Jahrhundert einen Meilenstein der

    20

  • 7/22/2019 Programmkonstruktion

    21/487

    1.2 Binre Digitale Systeme

    Industrialisierung dar. Jede Lochkarte aus Holz oder Karton bestimmtdurch das Vorhanden- oder Nichtvorhandensein eines Loches an einer be-stimmten Stelle die Stellung eines Fadens oberhalb oder unterhalb eines

    kreuzenden Fadens. Viele zu einer endlosen Schleife zusammengehefteteund nacheinander verwendete Lochkarten, je eine Karte pro kreuzendemFaden, erzeugen ein Muster im Stoff. Durch Austausch der Lochkartenist das Muster leicht nderbar, ohne den Mechanismus modifizieren zumssen. Auch moderne Websthle arbeiten nach demselben Prinzip.

    Diese Websthle nutzten wahrscheinlich zum ersten Mal die Digitaltech-nik in industriellem Mastab. Dass Webmuster in digitalerForm alsoals diskrete Werte im Gegensatz zuanalogenbzw. kontinuierlichen Daten aufgezeichnet wurden, liegt an der Verwendung der Daten: Es ist nur

    entscheidend, ob ein Faden oberhalb oder unterhalb eines ihn kreuzendenFadens liegt, wie weit ober oder unter ihm ist egal. Die nchste Loch-karte kommt erst zum Einsatz, wenn ein Faden vollstndig durchgefdeltist. Anders verhlt es sich mit Drehorgeln und Spieluhren, wo die Daten,hnlich wie beim Webstuhl, in Form von Lchern oder Stiften auf Kar-tonbndern, Blechtrommeln und vergleichbaren Datentrgern vorliegen:Die Lngen von sowie Abstnde zwischen Lchern oder Stiften sind vonBedeutung. Damit sind Pausen und die Lngen der Tne oder Strken derAnschlge auf analoge, nicht digitale Weise bestimmt.

    Seit Ende des 19. Jahrhunderts wird die Lochkartentechnik auch ver-breitet fr die Steuerung damals noch rein mechanischer Rechenmaschi-nen und Registrierkassen eingesetzt. Bekannt wurde die Technik vor allemdurch die US-amerikanische Volkszhlung 1890, die durch den Einsatz ei-nes Systems von Lochkarten, Stanzmaschinen und Zhlmaschinen in nureinem Jahr abgeschlossen werden konnte. Jede Person wurde durch eineLochkarte aus Karton identifiziert, die personenbezogene Daten durch L-cher an bestimmten Stellen festhielt. Solche Lochkarten wurden weltweitbis etwa 1980 in der Verwaltung eingesetzt, dann aber durch zuverlssigere

    magnetische Datentrger (z.B. Magnetstreifenkarten) und in jngster Zeitmehr oder weniger intelligente Speicherchips (z.B. Chipkarten) ersetzt.

    Ein Trend ist trotz aller technologischen nderungen seit Beginn derautomationsuntersttzten Datenverarbeitung gleich geblieben: Daten wer-den zunehmend in digitaler Form aufgezeichnet und fast ausschlielichin digitaler Form weiterverarbeitet. Wenn Daten auf natrliche Weise inanaloger Form vorliegen, werden sie durch digitale Daten angenhert. Bei-spielsweise wird die Krpergre nur auf ganze Zentimeter genau angege-ben, ein Fingerabdruck nur durch dessen wichtigste Merkmale auf nor-

    21

  • 7/22/2019 Programmkonstruktion

    22/487

    1 Maschinen und Programme

    mierte Weise beschrieben, und eine Schallwelle durch eine Folge von ingleichmig kurzen Abstnden abgetasteten ungefhren Amplitudenwer-ten dargestellt. Dabei entstehen immer Digitalisierungsfehler (beispiels-

    weise nur eine Krpergre von 180 cm angegeben, obwohl tatschlich180,3 cm gemessen wurden), die aber in Kauf genommen werden. DerVorteil der Digitalisierung liegt auf der Hand: Digitale Daten knnen oh-ne weiteren Qualittsverlust leicht gespeichert und verarbeitet werden,gleichgltig ob auf Lochkarten, magnetischen Speichermedien oder Spei-cherchips. Bei der Speicherung und Verarbeitung analoger Daten tritt da-gegen durch Einflsse von auen (Temperatur, Feuchtigkeit, Magnetfel-der, Ste, etc.) praktisch immer ein Qualittsverlust auf, das heit, dieDaten werden unkontrollierbar verndert. Auerdem kann der Digitalisie-

    rungsfehler immer so klein wie ntig gehalten werden. Man knnte dieKrpergre auch in Millimetern statt Zentimetern angeben, sodass derMessfehler vermutlich grer wre als der Digitalisierungsfehler.

    Vor gar nicht so langer Zeit bliche analoge Rechenschieber findet mannur mehr im Museum. Viele Taschenrechner sind solchen Przisionsinstru-menten preislich und leistungsmig klar berlegen. Auch Bild- und Ton-material wird fast nur mehr digital aufgezeichnet. Enthusiasten schwrenzwar immer noch auf die unvergleichliche Qualitt alter Schallplatten ohneDigitalisierungsrauschen, aber kaum jemand kann sich einen Plattenspie-

    ler leisten, bei dem der Qualittsverlust durch die analoge Verarbeitungnicht deutlich grer ist als der durch kleine Digitalisierungsfehler.

    1.2.2 Binre Systeme

    Auch ein weiteres Prinzip ist seit dem ersten programmierbaren Webstuhlunverndert geblieben: Daten werden berwiegend in binrer Form dar-gestellt. Dabei wird nur zwischen zwei mglichen Werten unterschieden,die fr 0 und 1, Ja und Nein, Wahr und Falsch, Ein- und Ausgeschal-

    tet, Faden kreuzt einen anderen unterhalb oder oberhalb (Webstuhl), etc.stehen. Speichermedien, Datenbertragungsleitungen und Maschinen ver-wenden verschiedene physikalische Ausprgungen zur Unterscheidung die-ser Werte Lcher, nderungen der Magnetisierungsrichtung, elektrischeSpannungen oder Strme ber einem Schwellenwert, Breite von hellenund dunklen Streifen in Barcodes, etc. Wie die Werte unterschieden wer-den, spielt keine Rolle. Wichtig sind hingegen einige vereinfachende ma-thematische Eigenschaften binrer Systeme. Vor allem ist es einfach, mitWahrheitswerten (Wahr und Falsch) umzugehen, und darauf aufbauende

    22

  • 7/22/2019 Programmkonstruktion

    23/487

    1.2 Binre Digitale Systeme

    0000 = 0 (0) 0100 = 4 (4) 1000 = 8 (-8) 1100 = 12 (-4)0001 = 1 (1) 0101 = 5 (5) 1001 = 9 (-7) 1101 = 13 (-3)0010 = 2 (2) 0110 = 6 (6) 1010 = 10 (-6) 1110 = 14 (-2)0011 = 3 (3) 0111 = 7 (7) 1011 = 11 (-5) 1111 = 15 (-1)

    Abbildung 1.4: Binrdarstellung der Zahlen 0 . . . 15 (bzw.8 . . . 7)

    binre Logik-Systeme werden intensiv genutzt. Mit Binrzahlen knnenMaschinen einfacher rechnen als mit Dezimalzahlen oder in anderen Zah-lensystemen. Man knnte statt binrer Systeme beispielsweise dreiwertigeSysteme verwenden und zwischen Null, Eins und Zwei oder Wahr, Falschund Unbekannt, etc. unterscheiden. Davon macht man kaum Gebrauch,da man die mathematische Einfachheit binrer Systeme verlieren wrde.

    Eine einstellige binre Zahl (also 0 oder 1) nennt manBit.Mit einem Bitalleine fngt man nicht viel an, mit mehreren Bits zusammen aber schon.Man verwendet eine fixe Anzahl von Bits als grundlegende Einheit fr dieDarstellung von Daten, so wie jede Lochkarte eine fixe Anzahl von Bitsenthlt. Ein solchesWort(auchMaschinenwortoderBinrwortgenannt)

    enthlt in modernen Computern hufig 32 oder 64 Bits, aber es gibt auchkleinere mit nur 4, 8 oder 16 Bits und grere mit 256, 512 oder 1024 Bits.Obwohl Worte (oder Wrter) mit 2k Bits bevorzugt werden, kommen auchsolche mit beispielsweise 12, 24 oder 28 Bits vor.

    InnBits lassen sich 2n unterschiedliche Werte ausdrcken, beispielswei-se 16 Werte in 4 Bits. Welchem Wert ein bestimmtes Bitmuster entspricht,ist jedoch nicht fix vorgegeben, sondern hngt von der Codierungder Wer-te ab. Abbildung1.4zeigt zwei bliche Codierungen fr Zahlen in 4 Bits,wobei eine nur nicht-negative Zahlen und die andere (in Klammern,Zwei-

    erkompliment genannt) negative wie positive Zahlen darstellen kann. InJava bestimmt der Typ die Codierung. So legt der Typ int fest, dass Wer-te als Zweierkompliment mit 32 Bit codiert werden. Dabei bestimmt dasam weitesten links stehende Bit das Vorzeichen, und einen Wert negiertman, indem man ihn um eins verkleinert und dann alle Bits umkehrt (al-so das Kompliment bildet). Beispielsweise erhlt man die Binrdarstellung1011 von -5 als Kompliment der Binrdarstellung 0100 von 4.

    Das ganz links stehende Bit eines Wortes ist das Most-Significant-Bit(MSB), das ganz rechts stehende das Least-Significant-Bit (LSB). Diese

    23

  • 7/22/2019 Programmkonstruktion

    24/487

    1 Maschinen und Programme

    1 Kilobyte (kB oder KB) = 210 Byte = 1.024 Byte103 Byte1 Megabyte (MB) = 220 Byte = 1.048.576 Byte106 Byte

    1 Gigabyte (GB) = 230 Byte = 1.073.741.824 Byte109 Byte1 Terabyte (TB) = 240 Byte = 1.099.511.627.776 Byte1012 Byte

    Abbildung 1.5: Am hufigsten verwendete Greneinheiten fr Daten

    Begriffe sind auch dann klar, wenn links und rechts von der Blickrich-tung abhngen, beispielsweise auf Lochkarten oder Schaltplnen.

    Aus historischen Grnden nennt man je 8 nebeneinander liegende Bitsin einem Wort einByte.Ein Wort mit 32 Bits enthlt also 4 Bytes. Frherwurde jedes Zeichen (Buchstabe, Ziffer, Sonderzeichen, etc.) in einem Bytedargestellt. Da sich die vielen lnderspezifischen Zeichen in den 28 = 256mglichen Werten eines Bytes nicht ausgehen, stellt man seltener benutzteZeichen in mehreren Bytes dar. Manchmal nimmt man auch 16- oder 32-Bit-Worte. Dessen ungeachtet ist es blich, die Gre von Daten, die ineinem Block aneinandergereihter Worte abgelegt sind, in Bytes anzugeben.Fr Texte entspricht diese Angabe grob genhert der Anzahl der Zeichen.

    Byte ist eine praktische Grenangabe fr kleine Datenmengen. Frgroe verwenden wir eher Kilobyte, Megabyte, Gigabyte und so weiter,siehe Abbildung1.5. Da diese Einheiten hauptschlich in binren Syste-men vorkommen, definiert man sie ber Zweierpotenzen (statt wie sonstblich ber Zehnerpotenzen). So hat ein Kilobyte 210 Byte, ein Megabyte210 Kilobyte und so weiter. Der Multiplikationsfaktor 210 = 1.024 kommtnahe genug an 103 = 1.000 heran, sodass zumindest die Grenordnungstimmt, wenn wir in Zehnerpotenzen statt in Zweierpotenzen denken.

    Die Einheit fr Information ist bit. Obwohl ein bit (klein geschrieben)viel mit einem Bit (gro geschrieben) gemeinsam hat, gibt es doch wichtigeUnterschiede. Beispielsweise kommen Bits nur ganzzahlig vor, whrend3,2 bit ein sinnvolles Ma ist siehe Kapitel 7.

    1.2.3 Rechnen mit Binrzahlen

    Ein Vorteil des Rechnens mit Binrzahlen liegt darin, dass es nur weni-ge Mglichkeiten gibt, zwei einstellige Binrzahlen zu kombinieren. Das

    24

  • 7/22/2019 Programmkonstruktion

    25/487

    1.2 Binre Digitale Systeme

    AND: 000 010 100 111OR: 000 011 101 111XOR: 000 011 101 110NOT: 01 10

    Abbildung 1.6: Einfache Bit-Operationen

    kleine Einmaleins ist schnell aufgelistet:

    0 0 = 0 0 1 = 0 1 0 = 0 1 1 = 1Diese Operation ist ein AND, bei der das Ergebnis genau dann 1 ist wennbeide Argumente 1 sind, siehe Abbildung1.6. Bei OR ist das Ergebnis ge-nau dann 1 wenn mindestens ein Argument 1 ist, und bei XOR (exklusivesOder) wenn genau ein Argument 1 ist. NOT negiert ein Bit. KomplexereOperationen lassen sich auf diese einfachen Operationen zurckfhren.

    Manchmal haben Ergebnisse mehr Stellen als die Argumente. Betrach-ten wir die Addition zweier einstelliger Binrzahlen:

    0 + 0 = 00 0 + 1 = 01 1 + 0 = 01 1 + 1 = 10

    Das zustzliche Bit des Ergebnisses heit bertrag.Das eigentliche Addi-tionsergebnis wird durch XOR gebildet, der bertrag durch AND. Wennmehrstellige Zahlen addiert werden, ist der bertrag zum nchsthherenBit zu addieren. Beispielsweise wird 11 + 01 = 100 nach demselben Sche-ma, nach dem wir Dezimalzahlen addieren, so berechnet: Wir beginnenmit dem LSB und bekommen 1 + 1 = 10. Das letzte Bit des Ergebnis-ses ist daher 0. Dann addieren wir die nchsten Bits zu 1 + 0 = 01 und

    zu dieser Zahl den bertrag aus der Berechnung des vorigen Bits, also01 + 1 = 10. Das sind die vorderen Stellen des Ergebnisses.

    Ein Schema zum Berechnen eines Ergebnisses nennt man Algorithmus.Multiplikationen mehrstelliger Binrzahlen knnen doppelt soviele Stel-

    len haben wie die multiplizierten Zahlen, siehe Abbildung1.7. Wir knnendafr denselben Algorithmus verwenden wie fr Dezimalzahlen.

    Folgendes Programmstck soll inhaltliche Aussagen verdeutlichen undeinen Vorgeschmack auf die Programmierung in Java geben. Lesern ohneProgrammiererfahrung wird empfohlen, das Programmstck aufmerksam

    25

  • 7/22/2019 Programmkonstruktion

    26/487

    1 Maschinen und Programme

    00 00 = 0000 01 00 = 0000 10 00 = 0000 11 00 = 000000 01 = 0000 01 01 = 0001 10 01 = 0010 11 01 = 001100 10 = 0000 01 10 = 0010 10 10 = 0100 11 10 = 011000 11 = 0000 01 11 = 0011 10 11 = 0110 11 11 = 1001

    Abbildung 1.7: Multiplikation von zwei zweistelligen Binrzahlen

    durchzulesen und darin nach Anhaltspunkten zu suchen, die einen Sinn er-geben. Keine Sorge: Dieses Beispiel muss noch nicht im Detail verstandenwerden. Es geht eher darum, ein Gespr fr das Aussehen von Program-men und den Klang der Beschreibungen zu entwickeln.

    Die Klasse BitsAndWords in Listing 1.8 beschreibt Methoden, dieeinfache logische Operationen auf einzelnen Bits darstellen, sowie Metho-den fr die Addition und vorzeichenlose Multiplikation von Worten. FrBits verwenden wir Boolesche Werte. Alle Methoden sind public (alsoberall sichtbar) sowie static(direkt in der Klasse aufrufbar, ohne einObjekt der Klasse zu bentigen). Die Methoden and, or, xor und notsind deswegen so einfach, weil Java fr diese Operationen die Operatoren

    &&, ||, ^und !besitzt, die direkt verwendet werden.Die Methoden addund mulsind etwas komplexer. Sie operieren nichtauf einzelnen Bits, sondern auf Worten, die aus mehreren Bits bestehen.Ein Wort wird durch ein Arrayvon Booleschen Werten beschrieben, er-kennbar an den eckigen Klammern[]. Ein Array ist eine Aneinanderrei-hung mehrerer Werte gleichen Typs, wobei man ber einen Index alsoeine Zahl in eckigen Klammern angibt, der wievielte Wert in der Reihegemeint ist. InBitsAndWords ist nirgends festgelegt, wie gro ein Arrayist, also aus wie vielen Bits ein Wort besteht. Wenn abzw.beine Variable

    oder ein Parameter ist, der ein Array enthlt, kann man ber a.lengthbzw. b.lengthdie Anzahl der Werte im Array feststellen. Hier wird da-von ausgegangen, dass alle zu addierenden bzw. multiplizierenden Wortedieselbe Gre haben. Auch die Ergebnisse haben diese Gre.

    Addition und Multiplikation iterieren in for-Schleifen ber die einzel-nen Bits, vom LSB zum MSB. Eine Iteration ist der einmalige Durchlaufdurch den Rumpf einer Schleife. Wir haben je eine Iteration fr jedes Bit,das heit, wir iterieren ber die Bits. Einefor-Schleife erlaubt eine etwaskompaktere Darstellung des Codes als eine while-Schleife:

    26

  • 7/22/2019 Programmkonstruktion

    27/487

    1.2 Binre Digitale Systeme

    Listing 1.8: Bit-Operationen sowie Addition und Multiplikation von Worten

    1 public class BitsAndWords {2 public static boolean and(boolean a, boolean b) {

    3 return (a && b); // a und b sind wahr4 }5 public static boolean or(boolean a, boolean b) {6 return (a || b); // a oder b oder beide sind wahr7 }8 public static boolean xor(boolean a, boolean b) {9 return (a ^ b); // entweder a oder b ist wahr

    10 }11 public static boolean not(boolean a) {12 return (! a); // a ist nicht wahr13 }

    1415 public static boolean[] add(boolean[] a, boolean[] b) {16 // addiere zwei Worte a und b; a.length == b.length17 boolean[] word = new boolean[a.length];18 boolean carry = false;19 for (int i = 0; i < a.length; i++) {20 boolean bit1 = xor(a[i], b[i]); // 1. Halbaddierer21 boolean carry1 = and(a[i], b[i]);22 boolean bit2 = xor(bit1, carry); // 2. Halbaddierer23 boolean carry2 = and(bit1, carry);24 word[i] = bit2; // Zusammenfassen der Teilergebnisse

    25 carry = or(carry1, carry2);

    26 }27 return word;28 }29 public static boolean[] mul(boolean[] a, boolean[] b) {30 // multipliziere zwei Worte a und b; a.length == b.length31 boolean[] word = new boolean[a.length];32 for (int i = 0; i < a.length; i++) {33 word[i] = false;34 }35 boolean[] shift = a;36 for (int i = 0; i < a.length; i++) {

    37 if (b[i]) {38 word = add(word, shift);39 }40 shift = add(shift, shift);41 }42 }43 }

    27

  • 7/22/2019 Programmkonstruktion

    28/487

    1 Maschinen und Programme

    for (int i = 0; i < a.length; i++) { ... }

    Zuerst wird einSchleifenzhlerials lokale Variable vor der ersten Iterati-on deklariert und mit 0 initialisiert, dann kommt die Schleifenbedingung,die wie in einer while-Schleife vor jeder Iteration berprft wird, da-nach steht die Anweisung i++ gleichbedeutend mit i = i + 1, die amEnde jeder Iteration ausgefhrt wird und den Schleifenzhler erhht, undschlielich kommt noch der Schleifenrumpf, der in jeder Iteration (vor derAnweisungi++) ausgefhrt wird.

    In der Methodeadd wird zunchst eine lokale Variable worddeklariertund mit einem neuen Array derselben Gre wie ainitialisiert. Hier wirdin der Schleife das Ergebnis-Wort, also die Summe von a und b Bit fr

    Bit abgelegt. Auerdem wird noch die lokale Variable carry deklariertund mit false initialisiert. Sie enthlt den bertrag von der Additioneines Bits zur Addition des nchsten Bits. Im Rumpf der Schleife wird dasErgebnis einer Bit-Addition schrittweise berechnet, wobei weitere lokaleVariablen zum Speichern von Zwischenergebnissen verwendet werden. Eskommen zwei sogenannte Halbaddiererzum Einsatz, die jeweils das Er-gebnis der Addition zweier Bits sowie den bertrag berechnen. Der ersteHalbaddierer bildet die Summe der beiden einander entsprechenden Bitsin a undb. Der zweite bildet dann die Summe aus dem Ergebnis des ersten

    Halbaddierers und dem bertragsbitcarry. Das Ergebnisbit des zweitenHalbaddierers ist das Ergebnis der gesamten Addition und wird in wordabgelegt, whrend der bertrag zum nchsten zu addierenden Bit durchOR aus den beiden bertragsbits der beiden Halbaddierer gebildet wird.

    Die Methodemul verwendet ebenso eine lokale Variable wordzum Ab-legen des Ergebnisses. Allerdings wird das Ergebniswort nicht Bit fr Bitberechnet, sondern durch wiederholte Additionen. Deshalb ist es notwen-dig, dass jeder Wert inword in der ersten Schleife mit false gefllt wird,sodass die erste Addition von der wohldefinierten Zahl 0 in wordausge-

    hen kann. Die lokale Variable shift enthlt zu Beginn dasselbe Arraywie a. In der ersten Iteration der zweiten Schleife wird shift zu wordaddiert falls das LSB von b den Wert true hat, sonst nicht. Auerdemwird danach shift zu shift addiert (was einer Multiplikation mit 2entspricht). In der nchsten Iteration wird also der doppelte Wert von azu word addiert falls das zweite Bit von b true ist, in der darauffol-genden Iteration der vierfache Wert falls das dritte Bit true ist und soweiter. Es wird also stets a2n1 hinzuaddiert falls das n-te Bit von btrueist.

    28

  • 7/22/2019 Programmkonstruktion

    29/487

    1.2 Binre Digitale Systeme

    Eigentlich berechnet add nicht a+ b, sondern (a+ b)modulo2a.length,weil der letzte Wert von carry unbercksichtigt bleibt. In der Praxiswerden solche Modulo-Rechnungen hufig verwendet, beispielsweise fastberall in Java. Ebenso berechnet mul (a b)modulo2a.length, schneidetalso alles ab, was ber die darstellbaren Bits hinausgeht.

    Wir haben angenommen, dass Worte nicht-negative Werte codieren. DieMultiplikation vorzeichenbehafteter Zahlen ist aufwendiger. Die Additi-on von Zahlen in Zweierkomplementdarstellung entspricht jedoch der vonnicht-negativen Zahlen. Es ergeben sich jedoch eigenartige Effekte, wennErgebnisse mehr Binrstellen bentigen als vorhanden sind und daherabgeschnitten werden. Berechnungsergebnisse sind dann gnzlich falsch.

    Beispielsweise kann durch Abschneiden des Vorzeichenbits die Additionzweier positiver Zahlen ein negatives Ergebnis liefern.

    1.2.4 Logische Schaltungen

    Heutige digitale Systeme sind fast ausschlielich als elektrische Schalt-kreise auf der Basis von Halbleitern, also Transistoren und Dioden rea-lisiert. Informatiker interessieren sich dafr, wie ein System aus vorge-gebenen logischen Bausteinenzusammengesetzt ist. Wie diese Bausteine

    intern durch Halbleiter realisiert sind, ist fr ein Verstndnis des Systemsnicht entscheidend. Die wichtigsten logischen Bausteine sind sogenannteGatter,welche die oben beschriebenen einfachen Bit-Operationen ausfh-ren. Beispielsweise hat ein AND-Gatter zwei Eingnge und einen Ausgangund sorgt dafr, dass am Ausgang eine dem Wert 1 (oder true) entspre-chende elektrische Spannung liegt wenn an beiden Eingngen ebenfallseine 1 entsprechende Spannung liegt, sonst liegt am Ausgang eine 0 (oderfalse) entsprechende Spannung. OR-, XOR- und NOT-Gatter erfllenihre Funktionen auf hnliche Weise. Oft sind mehrere logische Funktio-

    nen in ein Gatter integriert, beispielsweise AND und NOT in ein NAND-Gatter. Komplexere Schaltungen entstehen durch Kombination mehrererGatter, beispielsweise ein Halbaddierer durch die Kombination eines XOR-und eines AND-Gatters. Aus zwei NAND-Gattern lsst sich einFlip-Flopbauen, das als Speicher fr ein Bit dient. Gatter reichen aus, um darausganze Computer zu bauen.

    Gatter brauchen einige Zeit, bevor der Ausgang den Spannungslevel er-reicht, den er aufgrund der Spannungen an den Eingngen haben sollte.Solche Gatterlaufzeiten bewegen sich im Bereich von weniger als 0,1 ns

    29

  • 7/22/2019 Programmkonstruktion

    30/487

    1 Maschinen und Programme

    XOR

    XOR

    AND

    AND OR

    C

    B

    A C

    Y

    Abbildung 1.9: Volladdierer bestehend aus mehreren Gattern

    bis ber 100 ns (Nanosekunden, 1 ns = 109 Sekunden). Wenn fr eineBerechnung mehrere Gatter hintereinander durchlaufen werden, addieren

    sich die Gatterlaufzeiten. Beispielsweise liegt im Volladdierer in Abbil-dung1.9(der aus zwei Halbaddierern und einem OR-Gatter besteht) dasErgebnisbit Y erst nach zwei und der neue bertrag C erst nach dreiGatterdurchlufen vor. Meist werden viele Berechnungen durchgefhrt,wobei Zwischenergebnisse in folgende Berechnungen einflieen. Dabei istes wichtig zu wissen, ab wann die Ergebnisse einer Berechnung vorliegen,die Ausgangssignale also stabil sind. Erst dann kann die nchste Berech-nung gestartet werden. Meist gibt man einen fixen Takt vor. Mit jedemTakt beginnt eine neue Berechnung. Die Taktfrequenz wird so gewhlt,

    dass alle Ergebnisse zu Beginn des nchsten Taktes sicher vorliegen.Es ist leicht vorstellbar, wie ein Webstuhl programmiert wird: Man ent-wirft ein Webmuster und stanzt hndisch fr bestimmte berkreuzungender Fden an entsprechenden Stellen Lcher in die Lochkarten. Fast al-le logischen Schaltungen werden dagegen durch Programme spezifiziert.Eine verbreitete Hardwarebeschreibungssprache ist VHDL, siehe Abbil-dung 1.10. Sowohl kleine als auch groe Schaltungen bis hin zu ganzenProzessoren sind damit beschreibbar. Derart beschriebene Schaltungenknnen auf Computern simuliert werden um Fehler zu finden, und es ist

    mglich, die Beschreibungen in Hardware zu gieen, also daraus echteintegrierte Schaltkreise (Chips) zu erzeugen. Eine nachtrgliche nderungeinmal erzeugter integrierter Schaltkreise ist aber nicht mehr mglich.

    VHDL Programme beschreiben die Struktur der logischen Schaltungen,nicht den dynamischen Ablauf, also die Hintereinanderreihung einzelnerBerechnungsschritte. Die bliche Programmierung von Computern kon-zentriert sich aber genau auf den dynamischen Ablauf und nimmt dieStruktur der logischen Schaltungen als fix vorgegeben an. Ab jetzt werdenwir uns verstrkt mit dem dynamischen Ablauf beschftigen.

    30

  • 7/22/2019 Programmkonstruktion

    31/487

    1.3 Maschinen und Architekturen

    library IEEE; -- aus der Bibliothek IEEE:

    use IEEE.std_logic_1164.all; -- Form der Bit-Darstellung

    entity ANDGATE is -- ein ANDGATE hat

    port (IN1 : in std_logic; -- zwei Eingaenge (IN1, IN2)IN2 : in std_logic; -- und einen Ausgang (OUT1)

    OUT1: out std_logic); -- als einfache Bits

    end ANDGATE;

    architecture RTL of ANDGATE is

    begin

    OUT1

  • 7/22/2019 Programmkonstruktion

    32/487

    1 Maschinen und Programme

    Bus

    ALU Memory I/O

    Control-Unit

    Festplatte

    Ethernet

    Drucker

    Terminal

    Abbildung 1.11: Von Neumann-Architektur

    cher anweisen Daten zu liefern, die ALU darauf eine Operation aus-zufhren, und wieder den Speicher die Ergebnisse abzulegen.

    Memory: Der Speicher enthlt die Daten und macht sie bei Bedarf denanderen Komponenten (vor allem der ALU) zugnglich.

    I/O Unit: Die Ein-/Ausgabeeinheit stellt die Verbindung zur Peripherie,also zu Gerten wie Festplatte, Tastatur, Grafikkarte und Bildschirmund damit auch zur Auenwelt des Computers her.

    Alle Komponenten sind ber ein gemeinsamesBus-System,das ist ein Sy-stem elektrischer Leiter, miteinander verbunden. Protokolle sorgen (hn-lich den Verkehrsregeln fr eine Strae) dafr, dass der Nachrichtentrans-port mit mglichst wenig gegenseitiger Behinderung vonstatten geht. Ab-bildung1.11veranschaulicht diese Architektur.

    Der Speicher ist als Random-Access-Memory (RAM) aufgebaut, dasheit, die im Speicher abgelegten Worte sind einzeln ansprechbar. Pro-gramme werden, wie auch alle anderen Daten, im Speicher abgelegt. Aneiner speziellen Adresse liegt derBefehlszeiger (Program-Counter = PC),der die Adresse des nchsten auszufhrenden Programmbefehls enthlt.

    Folgende Schritte werden endlos (bis zum Abschalten) wiederholt:

    Ein Befehl wird von der Adresse, auf die der PC zeigt, aus demSpeicher in die Control-Unit gelesen.

    Der PC wird erhht, sodass er auf den nchsten Befehl zeigt.

    Der Befehl wird von der Control-Unit interpretiert und ausgefhrt.

    32

  • 7/22/2019 Programmkonstruktion

    33/487

    1.3 Maschinen und Architekturen

    Die Ausfhrung eines Befehls kann den PC verndern, sodass der nchsteBefehl nicht unmittelbar nach dem vorigen stehen muss. Eine solche nde-rung im Programmablauf nennt manProgrammsprungoder kurzSprung.ber Sprnge werden Schleifen und bedingte Verzweigungen realisiert.

    DieHarvard-Architekturndert die Von Neumann-Architektur dahinge-hend ab, dass Befehle und Daten in getrennten Speichern liegen. Das hatVorteile hinsichtlich der Effizienz und Betriebssicherheit, da Befehle nichtmehr (unabsichtlich) durch Daten berschrieben werden knnen. AktuelleComputer verwenden sowohl Elemente der Von Neumann-Architektur alsauch der Harvard-Architektur.

    Oft gibt es eine ganze Hierarchie von Speicherebenen, je hher die Ebe-

    ne, desto effizienter und kleiner. Ganz oben stehen Registerfr die geradeverarbeiteten Daten. Fr den PC und hnliches gibt es Spezialregister,die nur von speziellen Befehlen, z.B. Sprungbefehlen, verwendet werden.Zugriffe auf Register sind in der Regel sehr effizient. Die nchsten EbenenbildenCaches,meist getrennt in Daten- und Befehls-Caches. Diese enthal-ten eine Auswahl der Daten aus der untersten Ebene, dem Hauptspeicher,um raschere Zugriffe darauf zu erlauben.

    Die am hufigsten verwendeten Daten kommen automatisch in Caches,sodass wir uns beim Programmieren nicht darum kmmern mssen. Ca-

    ches sind technische Details zur Leistungssteigerung, die in derArchitekturder Maschine oft nicht sichtbar sind. Wir unterscheiden die Architekturvon der Implementierung der Architektur. Letzteres ist eine konkret rea-lisierte Maschine. Die Architektur beschreibt nur eine Grobstruktur unddie ausfhrbaren Befehle, also alles, was man zum Programmieren berdie Maschine wissen muss. Alle Implementierungen einer Architektur ver-stehen die Programme, die fr diese Architektur geschrieben werden.

    Befehle werden durch Maschinenworte dargestellt, also durch Bitmu-ster, mit denen Maschinen einfach umgehen knnen, Menschen aber nicht.

    Fr die hardware-nahe Programmierung verwendet man daherAssembler-Sprachenund nicht direkt Maschinen-Sprachen. Eine Assembler-Sprachestellt Befehle, Adressen und Daten durch fr Menschen besser lesbareSymbole dar, und ein Assembler bersetzt die Symbole in die eigentli-chen Befehle. Abbildung1.12zeigt ein Assembler-Programm fr die In-tel i386 Architektur unter dem Betriebssystem Linux. Das Programm istnur mit viel Wissen ber die Maschine und das Betriebssystem verstnd-lich. Wegen dieser ungnstigen Eigenschaften meidet man die Assembler-Programmierung weitgehend und programmiert in hheren Sprachen.

    33

  • 7/22/2019 Programmkonstruktion

    34/487

    1 Maschinen und Programme

    section .text ; Beginn des Abschnitts mit Programmcode

    global _start ; Ausfuehrung beginnt bei _start

    _start:

    mov ecx, hello ; Kopiere Adresse des Textes nach Register ecx

    mov edx, length ; Kopiere Laenge des Textes nach Register edxmov ebx, 1 ; Dateinummer der Standard-Ausgabe (= 1) in ebx

    mov eax, 4 ; Funktionsnummer 4 des Systemaufrufs = Ausgabe

    int 80h ; System-Interrupt; Linux fuehrt Funktion aus

    mov ebx, 0 ; Lege Ergebniswert des Programms in ebx ab

    mov eax, 1 ; Funktionsnummer 1 in eax = Programm beenden

    int 80h ; System-Interrupt; Linux beendet Programm

    section .data ; Beginn des Abschnitts mit Daten

    hello db Hello World! ; der auszugebende Text

    length equ $ - hello ; aktuelle Position minus Beginn von hello

    Abbildung 1.12: Einfaches Intel i386 Assembler-Programm (Hello World!)

    EinProzessorfasst die zentralen Teile eines Computers auf einem Chipzusammen, das sind ALU, Register, Control-Unit und (Teile der) Speicher-verwaltung. Meist zhlen auch Caches dazu, aber nicht der Hauptspeicher.Viele Prozessoren haben mehrereProzessor-Kerne,die weitgehend unab-

    hngig voneinander arbeiten, so als ob wir mehrere Prozessoren htten.Damit sind mehrere Programme gleichzeitig ausfhrbar. Manchmal wer-den Programme in Teile aufgespaltet, die gleichzeitig (nebenlufig oderparallel) ausfhrbar sind und die Ressourcen mehrerer Prozessoren undProzessor-Kerne nutzen knnen. Nebenlufige Ausfhrungen innerhalb ei-nes Programms heienThreads.

    1.3.2 Abstrakte Maschinen und Modelle

    Genaugenommen bezieht sich der Begriff Architektur, wie wir ihn inAbschnitt1.3.1eingefhrt haben, auf eine abstrakte Maschine, also eineabstrakte Beschreibung von Implementierungen. Im Falle der Computer-Architektur ist der Abstraktionsgrad gering, das heit, die Architekturkommt nahe an eine reale Maschine heran. Hufig verwenden und pro-grammieren wir abstrakte Maschinen mit einem hheren Abstraktions-grad. Die genaue Beziehung zwischen der abstrakten Maschine und derenImplementierung auf einer realen Maschine ist dabei kaum erkennbar.

    DieJava-Virtual-Machine (JVM)ist eine abstrakte Maschine. Auf den

    34

  • 7/22/2019 Programmkonstruktion

    35/487

    1.3 Maschinen und Architekturen

    public class Hello extends java.lang.Object{

    public Hello(); //Konstruktor (nicht verwendet)

    Code:

    0: aload_0

    1: invokespecial #1; //Method java/lang/Object.""4: return

    public static void main(java.lang.String[]);

    Code:

    0: getstatic #2; //Field java/lang/System.out

    3: ldc #3; //String Hello World!

    5: invokevirtual #4; //Method java/io/PrintStream.println

    8: return

    }

    Abbildung 1.13: JVM-Code entsprechend der Klasse Hello (Listing1.1)

    ersten Blick unterscheiden sich JVM-Programme (siehe Abbildung 1.13)nur unwesentlich von Assembler-Programmen. Allerdings wurden die Be-fehle einer Hardware-Architektur dafr optimiert, dass sie effizient auf be-stimmten realen Maschinen ausfhrbar sind, whrend die Befehle der JVMhinsichtlich der Unabhngigkeit von realen Maschinen optimiert wurden.Programme fr eine Hardware-Architektur laufen nur auf den Compu-tern, die diese Architektur unter einem bestimmten Betriebssystem ver-wenden. Der hhere Abstraktionsgrad entkoppelt die JVM von Hardware-und Betriebssystem-Details, sodass JVM-Programme fast berall laufenknnen. Sie sind portabel, also von einer Maschine auf eine andere ber-tragbar. Damit knnen Computer in Netzwerken einfacher miteinanderkooperieren. Allerdings hat der hhere Abstraktionsgrad auch einen Preis:Programme sind nicht so effizient ausfhrbar und in Betriebssysteme ein-gebunden als wenn sie fr ein bestimmtes System entwickelt worden wren.

    Die Programmierung abstrakter Maschinen ist einfacher da man De-tails der Hardware und des Betriebssystems nicht kennen muss. Aber dieJVM ist fr die Programmierung bei weitem noch nicht abstrakt genug.Programme werden auf einer viel hheren Abstraktionsebene entwickelt.

    Abstrakte Maschinen auf sehr hohem Abstraktionsniveau werden alsBerechnungsmodellebezeichnet. Eines der einflussreichsten Berechnungs-modelle ist derLambda-Kalkl,der den Begriff der mathematischen Funk-tion definiert und alles berechnen kann, was ber Funktionen ausdrckbarist, siehe Abschnitte1.5.2und1.5.3. DieTuring-Maschineist ein anderes,

    35

  • 7/22/2019 Programmkonstruktion

    36/487

    1 Maschinen und Programme

    historisch bedeutendes Berechnungsmodell, das Berechnungen durch Be-schreiben und Lesen eines gedanklich unendlich langen Bandes durchfhrtund nichts mit dem Lambda-Kalkl zu tun hat. Es spielt keine Rolle, ob ei-

    ne solche Maschine tatschlich realisierbar ist. Vielmehr handelt es sich umMaschinen, die nur in unserer Vorstellung existieren und sich daher nichtan technische Grenzen halten mssen. Das gibt uns groe Freiheit. Wie wiraus Untersuchungen einer Vielzahl solcher Berechnungsmodelle wissen, istdie Freiheit aber nicht unendlich gro. Auch Berechnungsmodelle unter-liegen gewissen Gesetzmigkeiten und Grenzen, genauso wie die PhysikGesetzmigkeiten und Grenzen in der Natur aufzeigt. Nicht alles, waswir gerne berechnen wrden, ist tatschlich berechenbar. Was berechenbarist, hngt (ab einer bestimmten Mchtigkeit des Modells) nicht vom Be-

    rechnungsmodell ab. So knnen Lambda-Kalkl und Turing-Maschine wieviele weitere Maschinen (die Turing-vollstndigen Maschinen) trotz ihrerUnterschiedlichkeit genau dasselbe berechnen. Das Erkennen von Gesetz-migkeiten in Berechnungsmodellen macht einen Groteil der Informatikaus. Daneben geht es natrlich auch darum, Aufgaben so zu lsen, dasswir Gesetzmigkeiten ausntzen und nicht an die Grenzen stoen.

    Hinter jeder Programmiersprache steckt ein Berechnungsmodell. Wirprogrammieren diese abstrakte Maschine, die wir dabei (oft unbewusst) imKopf haben. Losgelst vom Berechnungsmodell ergibt eine Sprache keinen

    Sinn. Bevorzugt verwenden wir Berechnungsmodelle, die fr Menschenrelativ einfach zu verstehen sind und die Intuition untersttzen. Das, wasberechenbar ist, hngt ja nicht vom Berechnungsmodell ab, solange dieSprache bzw. das Modell Turing-vollstndig ist. Vom Modell hngt abersehr wohl ab, wie einfach etwas ausdrckbar ist, wie viel Text dafr ntigist, wie einfach Programme lesbar und nderbar sind, und so weiter.

    Viele Berechnungsmodelle sind mathematische Modelle als Grundlagenfr theoretische Analysen auf uerst abstraktem Niveau. Programmier-sprachen haben einen etwas anderen Fokus: Manchmal mchte man auf

    einer hardware-nheren Ebene programmieren und Eigenschaften realerMaschinen direkt beeinflussen knnen. Berechnungsmodelle hinter hhe-ren Programmiersprachengehen von mathematischen Modellen aus, er-weitern diese aber oft um Konzepte auf hardware-nheren Ebenen. Esgibt Unterschiede im Abstraktionsgrad: Hardware-nahe hhere Program-miersprachen haben eine gute Untersttzung fr die Programmierung aufniedrigerem Abstraktionsniveau neben dem auf hohem Niveau, whrendreine Hochsprachen kaum auf niedrigerem Niveau programmierbar sind,aber die Programmierung auf hohem Niveau meist besser untersttzen.

    36

  • 7/22/2019 Programmkonstruktion

    37/487

    1.3 Maschinen und Architekturen

    1.3.3 Objekte als Maschinen

    In Abschnitt 1.1 haben wir gesehen, dass Objekte in Java-Programmeneine essentielle Rolle spielen. Software-Objekte simulieren Objekte der

    realen Welt, sodass wir Wissen aus der realen Welt direkt in die Soft-ware bertragen knnen. Wir knnen jedes einzelne Objekt aber auch alsabstrakte Maschine sehen, welche die durch die Sprache vorgegebene Ma-schine erweitert. Dabei helfen folgende drei Eigenschaften von Objekten:

    Objektzustand: Die Werte aller Variablen eines Objekts ergeben zusam-men den Objektzustand. Dieser ist durch Zuweisungen anderer Wertean die Variablen nderbar. Man kann den Objektzustand mit demZustand eines Computers (vor allem des Speicherinhalts) vergleichen,

    jedoch ist ein Objekt kleiner als der Computer und der Zustand einesObjekts damit leichter berschaubar als der des ganzen Computers.

    Objektverhalten: Das Objektverhalten beschreibt, wie das Objekt aufden Empfang von Nachrichten reagiert. Das entspricht dem Code inden Methodendefinitionen. hnlich wie ein Computer einen Befehlnach dem anderen ausfhrt und dabei den Speicherzustand vern-dert, so wird auch im Objekt (entsprechend den empfangenen Nach-richten) eine Methode nach der anderen ausgefhrt und dabei der

    Objektzustand verndert.Objektidentitt: Jedes Objekt hat eine eindeutige Identitt, die das Ob-

    jekt unverwechselbar macht. Diese ist ntig, um ein Objekt von an-deren hnlichen Objekten zu unterscheiden (auch wenn sich der Ob-jektzustand verndert) und Nachrichten an ganz bestimmte Objektesenden zu knnen. Computer verwenden hufig Internetadressen zureindeutigen Identifizierung und zum Senden von Nachrichten.

    Hinter allen Objekten einer Klasse steckt dieselbe abstrakte Maschine.

    Wenn wir eine Klasse entwickeln, denken wir oft an diese abstrakte Maschi-ne. Durch diese Denkweise knnen wir uns auf die wesentlichen Aspekte ei-nes ganz bestimmten kleinen Teils der Software konzentrieren. Wir vermei-den damit, dass wir stets die viel zahlreicheren und undurchschaubarerenAbhngigkeiten zwischen den Zustnden des ganzen Programms im Kopfhaben mssen. Beispielsweise beschreibt die KlasseUnbekannteZahl inListing1.2eine abstrakte Maschine, die fr Leser mit Programmiererfah-rung durchaus verstndlich ist. Diese Klasse ist aber kein vollstndigesProgramm, weil wesentliche Teile fehlen. Erst die Klasse Zahlenraten

    37

  • 7/22/2019 Programmkonstruktion

    38/487

    1 Maschinen und Programme

    in Listing1.3 stellt ber Ein- und Ausgaben eine Verbindung zwischeneinem Objekt von UnbekannteZahlund der Auenwelt her.

    Man knnte meinen,UnbekannteZahlsei gar nicht ntig, weil die zu

    erratende Zahl gleich als Instanz von int in Zahlenraten dargestelltwerden knnte. Eine solche Sichtweise ist verstndlich. Allerdings wr-de man dabei viel verlieren: UnbekannteZahlwurde als in sich logischkonsistente Einheit unabhngig von Zahlenratenentwickelt und kannauch in anderen Programmen verwendet werden. Jede der beiden Klas-sen ist einfacher verstndlich als eine kombinierte Klasse. Einfachheit undVerstndlichkeit sind in der Softwareentwicklung sehr wichtig.

    Um ein Objekt zu verwenden, brauchen wir nur dessen Schnittstelleverstehen. Die Schnittstelle beschreibt die Nachrichten, die vom Objekt

    verstanden werden. DieImplementierung des Objektsbzw. dieImplemen-tierungen der Methodender entsprechenden Klasse, also den Code, derbeim Empfang von Nachrichten ausgefhrt wird, brauchen wir dagegennicht kennen. Wir mssen beispielsweise nur wissen, dass eine Nachrichtgleich(3)an ein Objekt vonUnbekannteZahlgenau danntruealsAntwort liefert, wenn die gekapselte Zahl gleich 3 ist. Dagegen spielt eskeine Rolle, wie die gekapselte Zahl intern dargestellt ist und wie der Ver-gleich funktioniert. Wir knnen die Implementierung so verndern, dassdie Schnittstelle und damit die Verwendungsmglichkeiten gleich bleiben.

    1.3.4 Softwarearchitekturen

    Der BegriffArchitekturbezieht sich nicht nur auf die Baukunst oder Hard-ware, sondern auch auf Software. Unter einerSoftwarearchitekturverste-hen wir eine Beschreibung der wichtigsten Teile der Software und derBeziehungen zwischen diesen Teilen. Man bezeichnet diese Teile als Kom-ponenten oder Module. Auch Klassen und Objektesind Teile von Archi-tekturen. Komponenten haben viele Eigenschaften von Objekten, knnen

    aber deutlich grer sein. Eine wichtige Rolle kommt ihrenSchnittstellenzu, die bestimmen, wie die Komponenten zusammenspielen und mitein-ander kombinierbar sind.

    In anderen Bereichen der Technik wie im Maschinenbau, in der Elektro-technik und im Bauwesen ist eine auf Komponenten ausgelegte Entwick-lung schon seit langem nicht mehr wegzudenken. Beispielsweise bestehtein Auto aus Komponenten wie Motor, Getriebe und Radaufhngung. Ei-ne kaputte Komponente ist gegen eine neue austauschbar. Komponentenknnen unabhngig voneinander entwickelt werden, solange die Schnitt-

    38

  • 7/22/2019 Programmkonstruktion

    39/487

    1.3 Maschinen und Architekturen

    stellen zusammenpassen. Auf das Auto bezogen ist das der Fall, wennSchrauben, Bohrungen und Flansche an den richtigen Stellen sitzen unddie bertragenen Krfte innerhalb der erwarteten Grenzen liegen. Ganz

    unterschiedliche Experten knnen sich um die Entwicklung der einzelnenKomponenten und den Zusammenbau des Ganzen kmmern. Ein Moto-renbauer wei nur wenig ber Radaufhngungen, der Experte fr Radauf-hngungen nur wenig ber Motoren, und der Autobauer kennt alle Kom-ponenten oberflchlich, hat sie aber nicht selbst entwickelt. So betrachtetjeder nur seine Maschine auf dem jeweils notwendigen Detailliertheitsgrad.

    In der Softwareentwicklung ist es hnlich. Hufig konstruieren wir Soft-ware, indem wir (wie ein Autobauer) fertige Komponenten miteinanderkombinieren. Oft erstellen wir (wie ein Motorenbauer) eine Komponente,

    die von anderen genutzt wird. Dabei profitieren wir von unserem Spezi-alwissen in einem engen Bereich und achten darauf, dass die Schnittstel-len unserer Komponente mit denen anderer zusammenpassen. Anders alsKomponenten am Auto geht Software nicht durch Abnutzung kaputt, aberauch Software altert: Erwartungen und Einsatzbereiche ndern sich, unddaher mssen auch Softwarekomponenten gelegentlich erneuert werden.

    Es gibt vielfltige Gestaltungsmglichkeiten fr Softwarearchitekturen.Beispielsweise hat sich in vielen Bereichen eine aus Schichten aufgebauteArchitektur bewhrt, die wie die Schalen einer Zwiebel bereinander lie-

    gen. Die Komponenten einer Schicht haben nur Schnittstellen zu Kompo-nenten der direkt darunter bzw. darber liegenden Schicht. Das entkoppeltdie Komponenten voneinander und macht sie leichter austauschbar, wirktsich aber negativ auf die Laufzeiteffizienz aus. Zahlreiche neuere Anwen-dungsprogramme sind in drei Schichten aufgebaut: Die oberste Schichtdient der Prsentation und Eingabe von Daten und wird oft durch einenWeb-Browser realisiert. Die unterste Schicht verwaltet die Daten meistin einer Datenbank. Die mittlere Schicht enthlt die eigentliche Anwen-dungslogik, verknpft Eingaben aus der obersten Schicht mit Daten aus

    der untersten und sorgt dafr, dass alle Daten in sich konsistent und ge-schtzt bleiben. Klare Trennungen erlauben die Ausfhrung unterschied-licher Schichten auf unterschiedlichen Rechnern. So spiegelt die Software-architektur manchmal auch die Hardwarearchitektur wider.

    Bei ausreichend detaillierter Betrachtung kann jede Komponente wie-derum aus Komponenten in mehreren Schichten aufgebaut sein. Software-architekturen sorgen durch Abstraktion ber Details dafr, dass die Ge-samtstruktur eines groen Systems verstndlich bleibt. Wir knnen dasSystem auf jedem Detailliertheitsgrad betrachten, und auf jeder Betrach-

    39

  • 7/22/2019 Programmkonstruktion

    40/487

    1 Maschinen und Programme

    tungsebene sehen wir eine andere abstrakte Maschine, die unser Denkenauf signifikante Weise beeinflusst. Gerade wegen dieses starken Einflussesauf unser Denken ist die Softwarearchitektur so wichtig: Eine gute Ar-

    chitektur macht vieles einfacher, eine schlechte lsst sich durch noch soausgefeilte Programmiertechniken kaum in den Griff bekommen.

    1.4 Formale Sprachen, bersetzer und Interpreter

    Programmiersprachen unterscheiden sich wesentlich von natrlichen Spra-chen wie Deutsch oder Englisch. Der Grund dafr liegt in ganz anderenZielsetzungen: In einem Programm gibt man einer dummen, interesselo-sen Maschine przise Anweisungen, die ohne berlegung befolgt werdenknnen. Menschen kommunizieren miteinander auf annhernd gleichemNiveau, sodass der Austausch emotionaler und unprziser Informationenviel effektiver ist. Programmiersprachen hneln eher den in der Mathe-matik verwendeten formalen Modellen und Sprachen, da es auf Przisionankommt. Wir wollen einige Grundlagen von Sprachen betrachten und un-tersuchen, wie Programme auf einer Maschine zur Ausfhrung kommen.

    1.4.1 Syntax, Semantik und Pragmatik

    So gut wie alle Beschreibungen natrlicher wie formaler Sprachen umfas-sen folgende drei Aspekte:

    Syntax: Die Syntax regelt den Aufbauder Stze bzw. eines Programms.Alle Satz- oder Programmteile stehen zueinander in Beziehungen,die durch ein Regelsystem, die Grammatik der Sprache, beschrie-ben sind. In natrlichen Sprachen gibt es beispielsweise Regeln frSatzformen, die Beistrichsetzung, die Groschreibung, etc. In forma-len Sprachen ist es hnlich. Regeln schreiben beispielsweise vor, wie

    Deklarationen, Definitionen und Anweisungen aufgebaut sind, dasseinfache Anweisungen mit Strichpunkt enden und Rmpfe von Me-thoden in geschwungene Klammern eingeschlossen sind. Anhand derSyntax eines Sprachelements knnen wir erkennen, ob es sich umeine Deklaration, eine Anweisung oder etwas anderes handelt.

    Semantik: Die Semantik legt die Bedeutungvon Begriffen, Stzen bzw.Programmen fest. Zumindest fr formale Sprachen ist auch die Se-mantik ber Regeln festgelegt. Diese Regeln bestimmen den genauen

    40

  • 7/22/2019 Programmkonstruktion

    41/487

    1.4 Formale Sprachen, bersetzer und Interpreter

    Statement = {{Statement}}| if (Expression )Statement [elseStatement]| for (ForInit;[Expression] ;[Expression] )Statement| while (Expression )Statement| return[Expression] ;| [Expression];| . . .

    Abbildung 1.14: A