Programmier-Anfängern wird hier gezeigt,
worauf es beim Programmieren ankommt.
Nicht nur für Taschenrechner.
- Einleitung
- Programmiersprachen
- Voraussetzungen zum Programmieren
- Schlüsselwörter
- Deklarationen
- Anweisungen
- Ausdrücke
- Operatoren
- Programmsteuerung (Kontrollstrukturen)
- Funktionen, Unterprogramme
- Schlußwort
Viele Leute beginnen mit dem Programmieren von PCs oder programmierbaren wissenschaftlichen Taschenrechnern und haben keine Ahnung davon. Sie probieren solange herum, bis ein Programm "läuft". Das kostet Zeit und Mühe und bringt keine Erfolgserlebnisse.
Programmieren ist ein Handwerk, das gelernt werden muß. Da gibt es einige Grundlagen, die man beherrschen muß. Diese Grundlagen werden in dem Begriff "Programmierlogik" zusammengefaßt.
Mit der Programmierlogik allein ist es aber nicht getan. Man muß auch das Fachgebiet beherrschen, für das man Programme schreibt.
Beispiel:
Wenn man ein Programm für die Berechnung eines Staudamms schreiben will, dann nützt es wenig, wenn man nur die Programmierlogik beherrscht. Man muß auch wissen, wie man einen Staudamm berechnet.
Man muß das Problem (z.B. Staudamm berechnen) mit allen Nebeneffekten kennen. Dieses Problem muß analysiert werden. Dann findet der Fachmann auch die Problemlösung. Diese wird umgesetzt in eine Programmstruktur. Nun wird beides, Programmstruktur und Problemlösung, unter Berücksichtigung der Programmierlogik in einer bestimmten Programmiersprache formuliert, es entsteht der Quellcode (engl.: source code).
Der Quellcode wird dann mittels eines Übersetzungsprogramms (Compiler) in eine maschinenlesbare Form umgesetzt, die der Computer versteht. Dadurch entsteht das lauffähige Programm, das dann als ausführbare Datei im Rechner gespeichert wird.
Es gibt jede Menge maschinennaher und höherer Programmiersprachen. Die Programmierlogik ist bei allen ähnlich. Unterschiede bestehen natürlich hinsichtlich der mathematischen Formulierungen, der Umsetzung der Eingabe- und Ausgabeanweisungen und des Fachbereichs, für den ein Programm geschrieben wird. Beispielsweise brauchen Programme zur Steuerung von Robotern Funktionen für Aktoren und Sensoren, während Programme für astronomische Berechnungen mathematische Funktionen zur Berechnung genauer Zahlenwerte benötigen.
Bei allen Programmiersprachen ist es von grundlegender Bedeutung, daß man die Syntax und die Semantik genau einhält.
- Syntax ist die Form, wie eine Programmanweisung geschrieben oder eine Funktion aufgerufen werden muß und wie die Werte zu übergeben sind.
Also wie man schreibt.
Die Syntaxprüfung ist eine reine Formprüfung des Quellcodes. Fehler in der Syntax kann der Compiler erkennen. Der meckert dann solange ("Syntaxfehler!"), bis die Syntax stimmt.
- Die Semantik beschreibt die inhaltliche Bedeutung des Quellcodes und den logischen Zusammenhang der Funktionen, Zahlentypen und Formate, die man verwendet.
Also was man schreibt, was der Rechner tun soll.
Die Prüfung der Semantik ist eine Logikprüfung (Logik des Ablaufs), die der Compiler nicht vornehmen kann. Diese wird beim Ablauf des Programms auf dem Zielrechner (auf dem das Programm laufen soll) durchgeführt (Ablaufprüfung). Deshalb werden Fehler in der Semantik meist erst bei der Programmausführung ("Runtime-Error!") vom Zielrechner erkannt und gemeldet, wenn er die falschen Eingabewerte bekommen hat, mit denen er nichts anfangen kann oder wenn eine Berechnung falsch programmiert wurde und zu unzulässigen Werten führt (z.B. Division durch Null, Überschreiten der Grenzen von Zahlenbereichen, falsche Formate, falsche Datentypen, falsche Ausgabekanäle).
Im schlimmsten Fall, wenn Systemkomponenten falsch aufgerufen oder unzulässig verwendet wurden, bringt ein Semantikfehler den gesamten Rechner zum Absturz und man erfährt dann überhaupt nicht, was die Ursache dafür ist.
Deshalb lautet die leidvolle Erfahrung vieler Programmierergenerationen:
Das Programm tut nicht was du willst, sondern was du schreibst.
1. Man muß sein Fachgebiet beherrschen, für das man Programme schreiben will. 2. Man muß die Grundlagen der Programmierlogik beherrschen. 3. Man muß die Programmiersprache richtig anwenden. Nur wenn alle drei Voraussetzungen bei einem "Programmierer" vorhanden sind, kann man erwarten, daß die Programme auch einwandfrei funktionieren werden.
Deshalb ist "Programmierer" auch kein eigener Beruf, sondern nur eine Zusatzqualifikation zu einer schon vorhandenen Qualifikation (Beruf, Spezialfach, Fachwissen).
Programmcode in Englisch!
Da Programme international austauschbar sein sollen, hat man sich weltweit darauf geeinigt, daß die Sprachelemente einer Programmiersprache aus dem englischen Wortschatz stammen sollen.
Namen für Programmbefehle und für Elemente der Syntax sind reservierte Wörter bzw. reservierte Namen aus dem englischen Wortschatz. Sie werden Schlüsselwörter (engl.: key words oder keys) genannt und haben in der Programmiersprache eine feste Bedeutung. Diese Schlüsselwörter dürfen nicht als Variablennamen oder in anderer Bedeutung innerhalb des Programms verwendet werden.
Deshalb ist der Wunsch unsinnig, bei programmierbaren Taschenrechnern deutsche Schlüsselwörter zu verlangen. Beim HP 49G wären die Programme dann nicht weltweit einsetzbar, weil andere HP49G-Rechner die deutschen Befehle nicht verstünden. Beim TI-89 kann man die Programmierung auf deutsch (und andere Sprachen) umstellen. Die Schreibweise der Funktionen auf dem Rechner (z.B.: deutsch: Faktor( ), englisch: factor( ), u.s.w.) ist mit den (englischen) Bezeichnungen im deutschen Handbuch nicht identisch.
Da jeder bereits in der Schule Englisch gelernt hat, dürfte diese Sprache kein Problem für jemanden sein, der Programmieren lernen will.
Dialog und Ergebnisse in Deutsch!
Obwohl die Programmbefehle und die Schlüsselwörter in Englisch geschrieben werden müssen, kann ein Programm so gestaltet werden, daß der gesamte Dialog zwischen Benutzer und Programm in Deutsch erfolgen kann. Eingabeaufforderungen und Ergebnisausgaben können von Programmierer mit deutschen Texten gestaltet werden. Der Benutzer des Programms merkt nichts davon, daß der Quellcode mit englischen Schlüsselwörtern programmiert werden mußte.
Am Anfang eines Programms muß man dem Computer Regeln vorgeben, die er (und auch der Programmierer) für dieses Programm einhalten muß. Man muß ihm sagen, wie er die Inhalte der Speicherzellen behandeln soll und wie er mit der Außenwelt in Verbindung treten soll.
Die ersten Computer wurden noch direkt programmiert. Es gab noch keine Programmiersprachen. Der Mensch gab die Nummer der Speicherzelle an und mußte sich merken, in welcher Speicherzelle welcher Wert gespeichert war. Das war sehr mühsam. Deshalb wurden symbolische Programmiersprachen entwickelt.
Anstelle der Speicherzellennummern (Speicheradressen) wurden Namen (engl.: identifier) verwendet. Der Compiler setzt die Namen in die entsprechenden Speicheradressen um und legt die Speicherzuordnung fest. Namen sind lediglich "Bezeichner", die aber eindeutig sein müssen. Deshalb kann der Programmierer sie frei wählen.
Beispiel:
Der eine Programmierer bezeichnet z.B. die Länge und Breite eines Rechtecks mit a und b, der andere verwendet dafür L und B und ein dritter nimmt die ausgeschriebenen Namen Laenge und Breite. Dem Computer ist dies egal. Er muß nur wissen, was er damit machen muß. In diesem Fall muß er die Werte dieser beiden so bezeichneten Speicherstellen multiplizieren und das Ergebnis in eine dritte Speicherstelle schreiben, die c, oder F oder Flaeche (oder ganz anders, z.B. G23b56) heißen kann.
Wenn die Variablennamen eine Beziehung zum Inhalt der Variablen haben, wie z.B. Laenge und Breite, so sind dies "sprechende Namen", weil sie auf die Bedeutung der Inhalte schließen lassen. Man könnte für Länge und Breite auch die Namen Gurke und Salat verwenden und den Flächeninhalt dann mit Gurkensalat bezeichnen. Diese Namen hätten aber dann keine Beziehung mehr zum tatsächlichen Inhalt und das Programm würde für den Menschen "schwer lesbar".
Zur besseren Lesbarkeit von Programmen (Quelltexten) durch den Menschen sollten stets "sprechende Namen" verwendet werden. Für den Computer ist es unerheblich, wie die Namen lauten, sie müssen nur eindeutig sein.
Beispiel:
Bei E = m · c2 weiß jeder, was gemeint ist.
Nimmt man aber andere Namen und schreibt Emil = Katze · Maus2,
dann weiß kein Mensch, was gemeint ist.Für die Schreibweise der Namen muß eine Namenskonvention eingehalten werden, die von der jeweiligen Programmiersprache abhängt. So darf ein Name nicht mit einer Ziffer beginnen. Der Name 5NE6 ist nicht zulässig, während N5E6 ein zulässiger Name ist. Die Länge des Namens ist meist auch auf 8, 16, 32 oder auch 255 Zeichen beschränkt. Der zulässige Zeichensatz ist in der Sprachbeschreibung der Programmiersprache festgelegt. Der Zeichensatz enthält meist nicht alle Sonderzeichen.
Durch Deklarationen muß dem Computer gesagt werden, wie er die Namen und die Werte im Speicher zuordnen muß. Der Datentyp und die Dimension müssen festgelegt werden. Es muß festgelegt sein, ob der gespeicherte Wert eine ganze Zahl (integer), eine reelle Zahl (real), eine komplexe Zahl (complex), ein binärer Wert (binary), ein logischer Wert (logical), ein Zahlenfeld mit einer bestimmten Dimension (array), ein Text bestimmter Länge (string), eine interne Datei (file) oder ein zusammengesetztes Objekt (object) sein soll. Diese Datenypen haben unterschiedlichen Speicherbedarf je nach Dimension oder Länge. Den Datentypen sind bestimmte Regeln und Variablengrößen (engl.: size) zugeordnet, die der Computer kennt und bei der Berechnung beachtet. In neueren Programmiersprachen gibt es zusätzlich noch benutzerdefinierte Datentypen, die der Programmierer nach Wunsch selbst festlegen kann.
Hat man Dimensionen, Datentypen und Namen, dann kann man die Speicherbereiche festlegen, wo die Werte gespeichert werden. Eine Konstante ist bestimmt durch Datentyp und Name und enthält einen festen Wert, der sich für dieses Programm nie ändert. Deshalb baut der Compiler diesen Wert fest in den Programmcode ein. Man muß nur vorher den Datentyp (z.B. real) und den Namen (z.B. PI) für die Konstante (z.B. mit const real PI = 3.14159265359) festlegen.
Eine Variable ist ebenfalls bestimmt durch Datentyp und Name (z.B. var real Laenge) und enthält einen Wert, der sich während des Programmablaufs ändern kann. Der Compiler weist der Variablen entsprechend dem Datentyp einen Speicherbereich zu.
Variablen enthalten bei Programmstart irgendeinen unbestimmten Wert, der in der zugeordneten Speicherstelle zufällig vorhanden ist. Deshalb sollte der Programmierer einen definierten Anfangswert vorgeben (Initialisierung der Variablen). Wenn man die Variablen ohne vorherige Initialisierung verwendet, kann es Fehler im Berechnungsergebnis geben, weil der ursprünglich gespeicherte (zufällige) Wert verwendet wird.
Der Programmierer kann für Konstanten und Variablen festlegen, ob sie auch in den Unterprogrammen gelten sollen. Dann werden sie in einem gemeinsamen Speicherbereich (common) gespeichert.
Bevor das Computerprogramm die Eingabewerte von der Außenwelt übernehmen kann oder Ergebnisse ausgeben kann, muß man die Ein- und Ausgabekanäle festlegen. Das sind Speicheradressen, die mit einem Gerät (engl.: device code) oder einer Schnittstelle (engl.: port number) verbunden sind. Dieser Teil des Programms ist sehr stark abhängig vom verwendeten Computerfabrikat (hardware-abhängig) und vom angeschlossenen Gerät, dessen Möglichkeiten meist über ein vom Gerätehersteller mitgeliefertes Unterprogramm (Geräte-Treiber) zugänglich gemacht werden.
Bei manchen Computern muß man noch den Modus deklarieren, wie Winkel oder Fehlerrückmeldungen zu behandeln sind.
Winkel werden bei programmierbaren wissenschaftlichen Taschenrechnern entweder in Grad (°), Gon (g) oder im Bogenmaß Radiant (rad) verarbeitet. Die Einstellung erfolgt über bestimmte Flags oder Modus-Masken. Bei höheren Programmiersprachen wird meist nur Radiant verwendet. Der Programmierer muß dann selber in Grad oder Gon umrechnen.
Fehlerrückmeldungen erfolgen meist durch Ausgabe von Fehlernummern, die man nach Einstellung des Fehlermodus auch im Klartext angezeigt bekommen kann. Fängt der Programmierer diese Fehler nicht durch entsprechende Fehlerroutinen ab, dann bricht das Programm bei einem Fehler mit einer Fehlermeldung ab. Bei längeren Programmen ist die Fehlerbehandlung innerhalb des Programmes für die Benutzerfreundlichkeit von großer Bedeutung. Man kann zwar kein Programm idiotensicher machen, aber man sollte Fehler, die jedem passieren können (Eingabefehler), durch entsprechende Fehlerroutinen abfangen.
Anweisungen sind Befehle des Programmierers an das Programm, etwas zu tun.
Die oben angegebenen Deklarationen sind nicht-ausführbare Anweisungen. Sie sagen dem Compiler, wie er die Vorgaben umsetzen soll. Das Programm ist entsprechend diesen Anweisungen kompiliert und erzeugt worden. Im lauffähigen Programm selbst sind diese Deklarationen nicht als Anweisungen vorhanden.
Ein- und Ausgabeanweisungen sind ausführbar, das heißt das Programm muß sie entsprechend den programmierten Vorgaben ausführen.
Die Anweisung "Hole den Wert von der Tastatur und speichere ihn in der Variablen a" lautet z. B. in der Programmiersprache FORTRAN: READ(1) a.
Für den Computer heißt das: "Lese von Eingabekanal 1 und schreibe den Wert in a". Nach Ausführung dieser Anweisung enthält a den eingegebenen Wert. Der Eingabekanal 1 (= Tastatur) muß im Quelltext durch eine OPEN-Anweisung zugeordnet worden sein oder ist für die Programmiersprache allgemein festgelegt (voreingestellt, engl.: default)Die Anweisung, den Wert in a auf den Bildschirm zu schreiben, lautet: WRITE(2) a, wobei Ausgabekanal 2 = Bildschirm ist.
Wenn Ausgabekanal 5 z.B. dem Druckeranschluß zugeordnet ist, kann man schreiben: WRITE(5) a, dann wird der Wert ausgedruckt. Wenn Ausgabekanal 6 vorher durch eine OPEN-Anweisung einem Dateinamen zugeordnet worden ist, bewirkt die Anweisung WRITE(6) a, daß der Wert a in eine Datei mit dem betreffenden Namen geschrieben wird.
Die Kanalnummern (engl.: unit number oder unit specification) können beliebig gewählt werden.
- Mit einer OPEN-Anweisung wird eine Einheit (Tastatur, Drucker, Bildschirm, Dateiname) einer Kanalnummer zugeordnet.
- Mit einer CLOSE-Anweisung wird die Zuordnung Einheit zu Kanalnummer wieder aufgehoben.
Beispiel:
Wenn aus einer Datei (z.B. Eingabekanal = 51) gelesen werden soll und das Ergebnis in eine andere Datei (z.B. Ausgabekanal = 52) geschrieben werden soll, dann ordnet man mit jeweils einer OPEN-Anweisung den betreffenden Dateinamen einem Kanal zu. Dann liest man z.B. für eine Koordinatentransformation mit READ(51) r,phi,rho drei Zahlen aus der Eingabedatei und schreibt die daraus transformierten Koordinatenwerte der Variablen x, y und z mit WRITE(52) x,y,z in die Ausgabedatei.
Beide Dateien sind während der Berechnung "geöffnet", die Kanäle 51 und 52 sind aktiv, die Dateien sind für die Dauer dieser Zuordnung für andere Programme gesperrt. Sind die Aktionen abgeschlossen, dann schließt das Programm die Dateien mit CLOSE(51) und CLOSE(52) wieder und gibt sie damit für andere Programme frei.
In höheren Programmiersprachen muß bei Ein- und Ausgabe von Werten das Format angegeben werden, weil die Werte Texte oder Zahlen sein können, für die man eine bestimmte Darstellungsart vorgeben muß. Also sagt man dem Computer in der Anweisung noch, was es ist (Zahl oder Text) und wie man bei Ausgaben das Ergebnis sehen will.
Man fügt den Ein- und Ausgabeanweisungen sogenannte Formatanweisungen hinzu.
Beispiele (FORTRAN):
- Soll Text (Zeichenkette, engl.: string) eingegeben werden und die Variable a ist als string deklariert, dann kann man schreiben: READ(1, "A") a. Die Formatanweisung "A" bedeutet "alphanumerisch".
- Soll eine reelle Zahl mit insgesamt 7 Stellen, davon 2 Kommastellen, eingegeben werden und ist a als real deklariert, dann schreibt man READ(1,"F7.2") a. "F7.2" ist die Fließkomma-Darstellung (Fließkomma, engl.: floating point) der reellen Zahlen für die gewünschte Stellenzahl.
Bei vielen höheren Programmiersprachen ist bei Eingabeanweisungen eine automatische Typerkennung eingebaut. Das Programm erkennt den Typ des eingegebenen Objekts automatisch und wandelt ihn selbständig in den passenden Speichertyp um. Dann können die Formatanweisungen für den Eingabekanal weggelassen werden.
Bei der Ausgabe sollte der Programmierer aber das Ausgabeformat angeben, sonst wählt das Programm die interne Darstellung als Ausgabeformat.
Beispiel:
Eine reelle Zahl 1234.56 müßte mit Formatanweisung "F6.2" ausgegeben werden, wenn man sie in der gewohnten Weise darstellen will, sonst schreibt der Computer 0.123456E+4 (interne Darstellung ist halblogarithmisch).
Formatanweisungen benutzt man hauptsächlich bei der Ausgabe von Werten als Formatierung des Textes. Zeilenvorschübe, Leerzeilen, Einrückungen, Tabulatoren und andere Attribute können in Formatanweisungen gesetzt werden. Das Programm steuert die Ausgabe in eine Datei oder auf den Drucker entsprechend diesen Vorgaben. Der Programmierer muß diese Formatanweisungen richtig einsetzen, sonst ist die Ausgabe nicht wunschgemäß.
Bei Taschenrechnern wird das Format meist durch Flags (Nachkommastellen, Winkelformat, Zeitformat, Zahlentyp, Formeldarstellung, Dezimalkomma oder Dezimalpunkt) oder Textattribute (Font, Leerzeichen, Zeilenvorschub) in der Eingabeanweisung (INPUT, INFORM) oder Ausgabeanweisung (DISP, MSGBOX) vorgegeben.
Man kann aber die Daten auch binär (Binärformat, Maschinenformat) ohne Formatanweisungen einlesen oder ausgeben, so daß die Ergebnisse wieder nur von Computern gelesen werden können. Solche Lese- und Schreibvorgänge erfolgen meist bei Magnetbändern. Weil beim Binärformat die Formatumwandlungen wegfallen, wird es für schnelle Übertragungen verwendet.
Ein Ausdruck (engl.: expression) ist die symbolische Formulierung einer mathematischen oder logischen Anweisung. Ein Ausdruck steht meist auf der rechten Seite einer Gleichung.
Beispiel:
c · a2 + d · b2 ist ein solcher Ausdruck,
der im Programm so geschrieben wird: c*a^2+d*b^2Hier wird das Sternchen (*) (engl.: asterix) als Multiplikationszeichen verwendet, weil der Multiplikationspunkt (·) und das Multiplikationskreuz (×) als Kurzzeichen im Zeichensatz meist nicht vorhanden sind.
Ebenso wird die Potenzierung im Ausdruck c · a2 + d · b2 meist als c*a^2+d*b^2 oder, wenn das Zeichen "^" nicht verfügbar ist, auch mit Doppelsternchen als c*a**2+d*b**2 geschrieben.
Die Anweisung A = c*a**2+d*b**2 sagt dem Computer, den Ausdruck rechts vom Gleichheitszeichen auszuwerten (zu evaluieren) und den berechneten Wert in die Variable A zu schreiben.
In Programmen dürfen Multiplikationszeichen nicht weggelassen werden.
Beispiel:
Der mathematische Ausdruck c·a2 + d·b2 ist auch als Formel ca2 + db2 mit den Variablen a, b, c und d eindeutig. Der Compiler betrachtet aber ca und db im Ausdruck ca**2+db**2 als eigene Variablennamen. Weil diese Variablennamen nicht deklariert sind, wird der Compiler Fehlermeldungen oder zumindest Warnungen ausgeben.
Schwieriger wird es, wenn die Variablen ca und db neben den Variablen a, b, c und d innerhalb des Programms tatsächlich existieren. Dann wundert man sich über die falschen Ergebnisse, weil nicht c*a**2+d*b**2, sondern ca**2 + db**2 berechnet wurde.
Bei Taschenrechnerprogrammen werden keine derartigen Fehler gemeldet, weil es dort Deklarationen im Sinne einer höheren Programmiersprache nicht gibt. Der Taschenrechner erkennt alles als Namen an, was der Namenskonvention entspricht. Den Typ einer Variablen entnimmt der Taschenrechner dem gespeicherten Inhalt. Wenn in a eine reelle Zahl gespeichert ist, dann ist die Variable a vom Typ real, wird anschließend dort Text gespeichert, ist sie vom Typ string. Der Typ hängt also vom momentanen Inhalt ab.
Mathematische Operatoren
Die Zeichen "+", "-", "*" und "/" sind mathematische Operatoren der vier Grundrechenarten. Dazu kommen noch andere Operatoren, z.B. für Potenzierung "**" und für Mengenoperationen. Darauf wird hier nicht weiter eingegangen.
Wertzuweisungen
Soll in der Variablen a (wenn sie als integer deklariert wurde) die ganze Zahl 123456 gespeichert werden, dann schreibt der Programmierer: a = 123456.
"=" ist der Zuweisungsoperator. In manchen Programmiersprachen wird auch ":=" dafür verwendet.
Beispiele:
a = b heißt: In der Variablen a wird der Wert von b gespeichert.
a = a + 1 heißt: Erhöhe den Wert der Variablen a um 1 und speichere das Ergebnis wieder in der Variablen a.
Hinweis: Diese Schreibweise ist, rein mathematisch gesehen, Unsinn, aber hier ist es keine Gleichung, sondern eine Zuweisung.S = a + b + c + d. Hier wird die Summe der Werte aus den vier Variablen a, b, c und d der Variablen S zugewiesen.
Vergleichsoperatoren und logische Operatoren
Um Bedingungen für Verzweigungen und Schleifen programmieren zu können, müssen Vergleichsoperatoren und logische Operatoren festgelegt sein. Die Schreibweise hängt vom Zeichensatz der jeweiligen Programmiersprache ab. Sonderzeichen für Operatoren sind nicht immer verfügbar.
Die Tabelle zeigt die wichtigsten Operatoren.
Bedeutung Operator Operator (Schreibweise in FORTRAN) Vergleichsoperatoren: "größer als" > .gt. (greater than) "kleiner als" < .lt. (less than) "größer als" oder "gleich" >= .ge. (greater than or equal) "kleiner als" oder "gleich" <= .le. (less than or equal) "ungleich" <> .ne. (not equal) "gleich" = = .eq. (equal) Logische Operatoren: logisch "ODER" \/ oder OR .or. (or) logisch "UND" /\ oder AND .and. (and) logisch "NICHT" NOT .not. (not) logisch "XOR" XOR .xor. (exclusive or) Die Operatoren erfordern meist zwei Argumente, das heißt, sie stehen zwischen zwei Ausdrücken, Variablen oder Konstanten. NOT steht vor einem logischen Ausdruck bzw. vor einer logischen Variablen.
Wenn der Programmierer die logischen Operatoren ODER, UND, NICHT und XOR verwendet, sollte er die zweiwertige Logik (Boolesche Algebra) beherrschen, damit die Bedingungen eindeutig formuliert werden.
Beispiel:
NOT (a \/ b) ist gleichbedeutend mit (NOT a) /\ (NOT b), wobei a und b als Typ logical deklariert sein müssen.
Verzweigungen
Programme ohne Verzweigungen kommen kaum vor. Meist werden Bedingungen formuliert, die beim Programmlauf geprüft werden. Treffen die Bedingungen zu, wird entsprechend verzweigt oder wiederholt.
Beispiel:
Umgangssprachliche Formulierung der Verzweigung für ein Programm:
"Wenn das Wetter schön ist, gehen wir spazieren, andernfalls bleiben wir zuhause".Formulierung in einer Programmiersprache:
IF (WETTER = = "schön")
THEN (SPAZIERENGEHEN)
ELSE (ZUHAUSEBLEIBEN)
ENDIF, THEN, ELSE und END sind Schlüsselwörter, die dem Computer eine Verzweigung anzeigen. Nach dem Wort IF kommt die Bedingung, die er auf den Wahrheitsgehalt überprüfen muß. Hinter jeder Bedingung muß man sich ein Fragezeichen denken.
WETTER = = "schön"? heißt die Frage. Der Operator "= =" prüft auf Gleichheit (das einfache Gleichheitszeichen ist bereits als Zuweisungsoperator vergeben, deshalb wird es als Vergleichsoperator doppelt geschrieben).Dazu muß vorher in der Variablen WETTER ein Wert gespeichert worden sein, der entweder "schön" oder irgendwie anders lautet. Durch Vergleich des Inhalts der Variablen und dem angegebenen Wert stellt der Computer fest, ob die Bedingung erfüllt ist oder nicht.
Ist in der Variablen WETTER der Wert "schön" gespeichert, dann ist die Auswertung der Bedingung "wahr" (die Frage wird mit "ja" beantwortet) und der Computer führt die Aktion im THEN-Zweig aus, die da lautet: SPAZIERENGEHEN. Dies sei eine Funktion, die z.B. den Text "Auf geht's, anziehen und Haus verlassen!" ausgeben könnte.
Steht in der Variablen WETTER aber ein anderer Inhalt, dann ist die Auswertung der Bedingung "unwahr" und der Computer führt die Aktion ZUHAUSEBLEIBEN im ELSE-Zweig aus. Auf dem Bildschirm erscheint dann z.B. "Zuhause bleiben". END sagt dem Computer, daß die Formulierung der Verzweigung hier aufhört.
Verzweigungen bei Fallunterscheidungen programmiert man meist mit CASE, wo mehrere verschiedene Bedingungen abgefragt werden und dann entsprechend verzweigt wird. Die Syntax für CASE ist in verschiedenen Programmiersprachen unterschiedlich.
Schleifen
Auch Schleifen werden mit Bedingungen programmiert. Für Schleifen gibt es viele Syntax-Möglichkeiten.
Eine Schleife kann ausgeführt werden, solange eine Bedingung erfüllt ist (WHILE) oder bis eine Bedingung zum ersten Mal erfüllt ist (UNTIL). Man kann auch von Anfang an sagen, daß eine Schleife n-mal durchlaufen werden muß. Diese Wiederholungen werden mit DO oder FOR eingeleitet.
GOTO
Die einfachste Art eine Verzweigung durchzuführen oder eine Schleife zu programmieren, wird mit dem GOTO-Befehl realisiert. Man markiert eine Stelle im Programm mit einem Label (Zahl oder Namen), wo das Programm weiterlaufen soll und springt mit GOTO dort hin.
Beispiel:
In einem Programm-Quelltext steht die Zeile:
IF a > b THEN GOTO 123 ELSE GOTO 012 ENDDie Labels 123 und 012 müssen in diesem Programm existieren, sonst meldet bereits der Compiler "Missing label 123" oder "Missing label 012".
GOTO-Befehle gibt's bei einfacheren Programmiersprachen, bei denen keine komplizierten Verzweigungsstrukturen zweckmäßig sind (z. B. BASIC).
GOTOs sollten möglichst vermieden werden, weil sie jede Programmstruktur stören und zum unbeliebten "Spaghetti-Code" führen. Moderne höhere Programmiersprachen und auch programmierbare wissenschaftliche Taschenrechner kommen ganz ohne GOTOs aus.
Funktionen sind Unterprogramme, die nur einen einzigen Wert als Ergebnis liefern: den Funktionswert.
Bei den meisten höheren Programmiersprachen werden die Standardfunktionen (engl.: intrinsic functions) als Standardbibliothek mitgeliefert. Diese können vom Programmierer wie Konstanten in Ausdrücken verwendet werden. Dem Compiler sind diese Funktionen bekannt.
Nachfolgend eine Aufzählung einiger wichtiger Standardfunktionen. Die Namen der Funktionen können bei verschiedenen Programmiersprachen unterschiedlich sein. Die Klammern hinter dem Funktionsnamen weisen darauf hin, daß beim Aufruf Argumente (Parameter) mitgegeben werden müssen.
Mathematische Funktionen:
Quadratwurzel SQRT( ) oder ROOT( ),
dekadischer Logarithmus LOG10( ),
natürlicher Logarithmus LOG( ) oder LN( ),
trigonometrische Funktionen SIN( ), COS( ) und TAN( ) und
ihre Umkehrfunktionen ASIN( ), ACOS( ) und ATAN( ),
ex-Funktion EXP( ),
Absolutwert ABS( ),
Negativwert NEG( ),
Ganzzahlwert INT( ),
Nachkommawert FRAC( ),
Vorzeichenfeststellung SIGN( ),
Modulo-Funktion MOD( ),
.....Logische Funktionen:
AND( ), OR( ), NOT( ) und XOR( ) (nicht zu verwechseln mit den logischen Operatoren!),
Funktionen für Bit-Manipulationen:
SHIFT( ), ROTATE( ), SWAP( ).
Außer den oben genannten Funktionen gibt es noch Funktionen für andere Zwecke (z.B. Stringbearbeitung, Zeitfunktionen, Dateifunktionen), die hier aber nicht aufgezählt werden, weil jede Programmiersprache ihre eigenen Sonderfunktionen anbietet.
Verwendung der Funktionen
Funktionen können wie Konstanten in Ausdrücken verwendet werden. Der einzige Unterschied ist, daß bei Funktionen Argumente in der Funktionsklammer mitgegeben werden müssen. Der Computer betrachtet den Inhalt der Funktionsklammer als einen mathematischen Ausdruck, den er zuerst berechnet, bevor er die Funktion aufruft.
Beispiel:
Soll der Sinus von 30° und der Cosinus von 75° addiert und in Z gespeichert werden, dann müssen die Winkel vorher von Grad in Radiant umgerechnet werden. Das kann in der Funktionsklammer beim Aufruf erfolgen.
Z = SIN(30*PI/180) + COS(75*PI/180)
Der Wert des Arguments kann auch in einer Variablen gespeichert sein.
Beispiel:
Wenn man Vielfache und Teile eines Winkels als Argument verwenden will, wird dieser Winkel zuerst in RAD umgerechnet und in der Variablen ALPHA gespeichert.
Für Winkel 30°:
ALPHA = 30*PI/180
Z = SIN(3*ALPHA) * SIN(ALPHA/5) + COS(2*ALPHA/3) * COS(ALPHA/10)
Benutzerdefinierte Funktionen und Unterprogramme
Der Programmierer kann auch selbst Funktionsunterprogramme schreiben und wie Standardfunktionen verwenden. Funktionsnamen sind frei wählbar, wenn man die reservierten Namen meidet.
Beispiel:
Wenn man immer wieder die Berechnung der Hypotenuse eines rechtwinkligen Dreiecks braucht, dann schreibt man eine Funktion (nach Pythagoras):
HYP(a,b) = SQRT(a**2+b**2) und gibt beim Aufruf die Werte für die Katheten a und b als Wert oder Ausdruck mit. Der Wertzuweisung c = HYP(3,4) liefert dann den Wert c=5.Wenn man aber nicht nur einen einzigen Funktionswert haben will, sondern aus den Parametern mehrere Werte ermittelt werden sollen, dann muß man ein Unterprogramm (engl.: subroutine) schreiben.
Ein Unterprogramm darf nicht wie eine Konstante in einem Ausdruck verwendet werden, weil es mehrere Werte liefert. Der Aufruf erfolgt mit dem Befehl CALL. Die mitgegebenen Parameter sind Variablen, die innerhalb des Unterprogramms deklariert sein müssen. Man unterscheidet zwischen Eingabe- und Ausgabeparametern.
Die Eingabeparameter enthalten beim Aufruf die Werte, die das Unterprogramm verarbeiten soll. Die Ausgabeparameter sind Variablennamen des aufrufenden Hauptprogramms, in die das Unterprogramm die Ergebnisse schreiben soll. Die Reihenfolge der Parameter ist im Unterprogramm festgelegt und damit für den Aufruf bindend.
Beispiel (mit Aufgabe):
Ein Unterprogramm
DREIECK(a,b,c,alpha,beta,gamma,Flaeche,Umfang) berechnet aus den drei Dreieckseiten a,b und c die drei Eckwinkel in Grad (°), sowie Fläche und Umfang des Dreiecks. a, b und c sind die Eingabeparameter, alpha, beta, gamma, Flaeche und Umfang sind die Ausgabeparameter.
Nach dem Aufruf von
CALL DREIECK(4,6,8,alpha,beta,gamma,Flaeche,Umfang) stehen in den Variablen (vom Typ real) des aufrufenden Hauptprogramms folgende Werte, wobei die Winkel bereits in Grad (°) umgerechnet sind:
alpha = 28.955, beta = 46.567, gamma = 104.478,
Flaeche = 11.619, Umfang = 18.000.Da es beim Aufruf nur auf die Reihenfolge der Parameter ankommt, kann der Aufruf auch mit
CALL DREIECK(4,6,8,a1,a2,a3,F,U) erfolgen. Das Ergebnis ist dann dasselbe, nur die Variablen, in die das Ergebnis geschrieben wird, haben andere Namen:
a1 = 28.955, a2 = 46.567, a3 = 104.478,
F = 11.619, U = 18.000.
Vertauscht man beim Aufruf die Variablennamen, dann steht das richtige Ergebnis in den falschen Variablen. Die Fläche steht immer in der vorletzten und der Umfang in der letzten Variablen der Parameterklammer.Aufgabe für den Leser:
Welche Werte stehen nach Aufruf von
CALL DREIECK(3,4,5,z1,z2,z3,z4,z5)
in den Variablen z1 bis z5 des aufrufenden Hauptprogrammes? Um die Aufgabe nicht zu leicht zu machen, wurden hier keine "sprechenden Namen" für die Variablen verwendet.Der Leser weiß inzwischen, wie Unterprogramme funktionieren und kann die Werte selbst ausrechnen und die Variableninhalte richtig deuten.
Über Programmieren, Programmiersprachen und Programmierlogik gäbe es noch viel mehr zu sagen.
Diese wenigen Hinweise aber mögen genügen, um dem Anfänger einen Eindruck zu vermitteln, worauf es beim Programmieren ankommt.
Um das gründliche Studium der Sprachbeschreibung und das Lernen der Syntax und Semantik einer Programmiersprache wird der angehende Programmierer nicht herumkommen.
Auch hier gilt: Je besser man eine (Programmier-)Sprache beherrscht, desto besser wird man (vom Computer) verstanden.
Zum Beginn des
Beitrags
Zur
Beitragsübersicht
Copyright (C) 2002 Otto Praxl.
Alle Rechte vorbehalten!