Rechner sind zum Rechnen da – das ist ihr Kerngeschäft und da bildet der Amiga keine Ausnahme. BlitzBasic/AmiBlitz3 bringt bereits eine große Anzahl an mathematischen Bibliotheksfunktionen für alle Anwendungsfälle mit, die sich bei Bedarf jederzeit um selbstgeschriebene, eigene Funktionen erweitern lassen – und darum geht es in diesem Teil unseres Tutorials.
Die Grundrechenarten
Um einfache Berechnungen anzustellen, bedarf es keiner umfangreichen Mathe-Bibliotheken und -funktionen. BlitzBasic beherrscht ohne weiteren Aufwand Addition (+), Subtraktion (-), Multiplikation (*) und Division (/). Um eine Berechnung durchzuführen genügt es, zwei Zahlen mit dem entsprechenden Operator zu verknüpfen und das Ergebnis einer Variablen zuzuweisen. Beispiele:
summe.w = 47 + 11 ; Addition summe.w = 50 - 8 ; Subtraktion produkt.w = 33 * 3 ; Multiplikation quotient.q = 42 / 3 ; Division quotient.q = 42 / 0 ; Division durch Null nicht erlaubt!
Priorität von Rechenoperationen
Tauchen in einem Term (einer Anweisung) unterschiedliche Rechenoperationen auf, so muss man die Priorität der einzelnen Operationen beachten. Die Hierarchie ist wie folgt aufgebaut:
- Potenzierung
- Multiplikation und Division („Punktrechnung“)
- Addition und Subtraktion („Strichrechnung“)
Beachtet man diese Rangordnung nicht, so kann es zu unerwarteten Seiteneffekten aufgrund falscher Ergebnisse kommen. Beispiel:
meinErgebnis.w = 5 + 5 * 3 Erwartetes Ergebnis: 30 Tatsächliches Ergebnis: 20
Überrascht? Wir haben in diesem Beispiel die Faustregel „Punkt- vor Strichrechnung“ nicht beachtet und denken uns: 5 + 5 = 10, 10 * 3 = 30. Der Computer macht alles richtig und rechnet stattdessen: 5 * 3 = 15, 5 + 15 = 20.
Klammerung von Termen
Um die Priorität einer verketteten Berechnung zu ändern, setzt man runde Klammern entsprechend der gewünschten Priorisierung:
meinErgebnis.w = (5 + 5)* 3 Erwartetes Ergebnis: 20 Tatsächliches Ergebnis: 20
Jetzt werden tatsächlich 5 + 5 addiert, bevor die Multiplikation durchgeführt wird.
Die Wahl eines „passenden“ Datentyps
Wenn man das Ergebnis einer Berechnung einer Variablen zuweisen möchte, dann muss man sich bereits im Vorfeld Gedanken darüber machen, welche Art von Zahlen und Zahlengrößen dabei anfallen können. Die Zahl muss ja schließlich auch in die Variable hinein passen. Werden nur sehr kleine Zahlen als Ergebnis erwartet? Kann ich mich auf Ganzzahlen beschränken, oder sind Fließkommazahlen zu erwarten? Wie groß kann ein Ergebnis ausfallen, falls sich die Werte der Berechnung ändern?
Der Datentyp einer Variable bestimmt, ob eine abzulegende Zahl fehlerfrei dargestellt werden kann (siehe Anhang A) oder nicht. Ausschlaggebend ist dabei sein Wertebereich. Ist er zu klein bemessen, dann könnte die Variable überlaufen und falsche Resultate liefern. Bemisst man ihn zu groß, so verschwendet man Ressourcen. Weist man eine Fließkommazahl einem Ganzzahlen-Typen zu, dann gehen die Nachkommastellen verloren, was wiederum zu Fehlern im Programm führen kann. Gerade bei der Division zweier Zahlen muss z.B. regelmäßig mit einem Ergebnis in Form einer Fließkommazahl gerechnet werden. Du siehst, es erfordert Hirnschmalz. Der Leitsatz zur Wahl eines passenden Datentyps könnte etwa so lauten: „So viel wie nötig, aber so wenig wie möglich“.
Das Listing „calc1.ab3“ führt die Grundrechenarten vor und zeigt kleine Unterschiede zwischen Berechnungen mit Ganzzahlen und solchen mit Fließkommazahlen auf:
; ----------------------- ; File:calc1.ab3 ; Grundrechenarten ; Version: 1.0 ; ----------------------- OPTIMIZE 1 ; Optimierung für Amiga mit Turbokarte/A1200 SYNTAX 1 ; strenge Syntaxprüfung ; Amiga Version String und das Compilerdatum !version {"calc1 1.0 (\\__DATE_GER__)"} ; Variablen deklarieren DEFTYPE .l l_zahl1,l_zahl2, l_result ; Datentyp: Long DEFTYPE .f f_zahl1, f_zahl2, f_result ; Datentyp: Float ; Variablen initialisieren l_zahl1 = 3201 l_zahl2 = 500 f_zahl1 = 3201.5 f_zahl2 = 500.2 ; Addition l_result = l_zahl1 + l_zahl2 f_result = l_zahl1 + l_zahl2 NPrint "Addition (integer) Ergebnis : " + Str$(l_result) NPrint "Addition (float) Ergebnis : " + Str$(f_result) NPrint "Addition (float-Werte) Ergebnis : " + Str$(f_zahl1 + f_zahl2) NPrint "" ; Subtraktion l_result = l_zahl1 - l_zahl2 f_result = l_zahl1 - l_zahl2 NPrint "Subtraktion (integer) Ergebnis : " + Str$(l_result) NPrint "Subtraktion (float) Ergebnis : " + Str$(f_result) NPrint "Subtraktion (float-Werte) Ergebnis : " + Str$(f_zahl1 - f_zahl2) NPrint "" ; Multiplikation l_result = l_zahl1 * l_zahl2 f_result = l_zahl1 * l_zahl2 NPrint "Multiplikation (integer) Ergebnis : " + Str$(l_result) NPrint "Multiplikation (float) Ergebnis : " + Str$(f_result) NPrint "Multiplikation (float-Werte) Ergebnis: " + Str$(f_zahl1 * f_zahl2) NPrint "" ; Multiplikation l_result = l_zahl1 / l_zahl2 f_result = l_zahl1 / l_zahl2 NPrint "Division (integer) Ergebnis : " + Str$(l_result) NPrint "Division (float) Ergebnis : " + Str$(f_result) NPrint "Division (float-Werte) Ergebnis : " + Str$(f_zahl1 / f_zahl2) NPrint "" End
Ausgabe:
Addition (integer) Ergebnis : 3701 Addition (float) Ergebnis : 3701 Addition (float-Werte) Ergebnis : 3701.699 Subtraktion (integer) Ergebnis : 2701 Subtraktion (float) Ergebnis : 2701 Subtraktion (float-Werte) Ergebnis : 2701.3 Multiplikation (integer) Ergebnis : 1600500 Multiplikation (float) Ergebnis : 1600500 Multiplikation (float-Werte) Ergebnis: 1601390 Division (integer) Ergebnis : 6 Division (float) Ergebnis : 6.401999 Division (float-Werte) Ergebnis : 6.400439
Programmanalyse:
- in den Zeilen 13 bis 20 deklarieren und initialisieren wir, wie gewohnt, die Variablen des Programms. Verwendet werden Ganzzahlenwerte (Integerwerte) vom Typ Long und große Fließkommawerte vom Typ Float.
- die Zeilen 23 bis 28 führen Additionen durch und geben anschließend deren Summen aus. Dabei addiert die Berechnung in Zeile 24 zwei Ganzzahlen und weist die Summe einer Float-Variablen zu. Beachte: Die Ausgabe zeigt trotzdem lediglich eine Ganzzahl an.
- die Ausgabe in Zeile 27 erfolgt mit einer direkt an NPrint übergebenen, mittels Str$ in einen String umgewandelten Berechnung mit zwei Fließkommazahlen. Die Ausgabe zeigt hier, wie erwartet, eine Fließkommazahl als Ergebnis an.
- Analog zum Gesagten erfolgt in den Zeilen 31 bis 38 die Subtraktion, in den Zeilen 39 bis 44 die Multiplikation und in den Zeilen 46 bis 52 die Division.
Erinnerung: Print und NPrint erwarten bei der Verwendung von aus Zahlen und Strings zusammengesetzten Parametern, dass die Zahlen in einem zusammengesetzten String ebenfalls als String vorliegen! Darum wandeln wir solche Zahlen per Str$ um.
Anstatt des „großen“ Typs Float hätten wir hier auch den kleineren Typ Quick verwenden können. Beide Typen unterscheiden sich allerdings sowohl in ihrem Wertebereich, als auch in ihrer Genauigkeit bezüglich ihrer Anzahl an Nachkommastellen. Das kurze Listing „floatcalc.ab3“ veranschaulicht die Unterschiede beider Datentypen:
; -------------------------- ; File:floatcalc.ab3 ; Division von Float-Zahlen ; Version: 1.0 ; -------------------------- OPTIMIZE 1 SYNTAX 1 ; Amiga Version String und das Compilerdatum !version {"floatcalc 1.0 (\\__DATE_GER__)"} ; Variablen deklarieren DEFTYPE .q q_zahl1,q_zahl2, q_result ; Datentyp: Quick DEFTYPE .f f_zahl1, f_zahl2, f_result ; Datentyp: Float ; Variablen initialisieren q_zahl1 = 3201.5123456 q_zahl2 = 500.7123478 f_zahl1 = 3201.5123456 f_zahl2 = 500.7123456 ; Division q_result = q_zahl1 / q_zahl2 f_result = f_zahl1 / f_zahl2 NPrint "Division (quick) Ergebnis: " + Str$(q_result) NPrint "Division (float) Ergebnis: " + Str$(f_result) NPrint "" End
Ausgabe:
Division (quick) Ergebnis: 6.3939 Division (float) Ergebnis: 6.393915
Zum Ablauf dieses Programms gibt es nicht viel zu sagen. Wir initialisieren die Variablen jeweils mit den gleichen Inhalten. Quick liefert als Ergebnis der Berechnung eine Zahl mit 4 Nachkommastellen, bei Float sind es 6.
Aufgaben:
- Versuche spaßeshalber einmal, alle Variablen mit zusätzlichen Nachkommastellen zu initialisieren und compiliere das Programm erneut. Beachte die Fehlermeldung des Compilers.
- Initialisiere eine Quick-Variable mit dem Wert 37900001.5123456 und compiliere das Programm. Was sagt der Compiler?
- Schreibe ein Programm mit einer Quick-Variablen und weise dieser den Wert 32767.1 zu. Gib diesen Wert aus. Addiere nun 1.0 zum Wert und gib die Variable erneut aus. Was passiert?
Modulo – der Rest einer Division
Modulo ist eine mathematische Operation, die den Rest einer ganzzahligen Division bezeichnet. Programmierer verwenden diese Operation z.B. zur Prüfung, ob eine ganzzahligen Division einen Nachkommaanteil besitzt. Ist dies der Fall, so liefert die Operation den Wert 1 zurück, andernfalls 0. BlitzBasic verwendet den Befehl MOD, um die Operation durchzuführen. Beispiele:
rest.w = 4 MOD 3 ; Ergebnis: 1, es gibt einen Rest rest.w = 4 MOD 2 ; Ergebnis: 0, es gibt keinen Rest
Das Listing „modulus.ab3“ demonstriert die Verwendung:
; ----------------------- ; File: modulus.ab3 ; Rest einer Division ; Version: 1.0 ; ----------------------- OPTIMIZE 1 SYNTAX 1 ; Amiga Version String und das Compilerdatum !version {"modulus 1.0 (\\__DATE_GER__)"} DEFTYPE .w modulus, zahl1, zahl2 ; Werte eingeben NPrint "Rest einer Division testen" NPrint "Gib zwei Ganzzahlen ein!" Print "Erste Zahl: " zahl1 = Edit(10) Print "Zweite Zahl: " zahl2 = Edit(10) NPrint"" ; Modulus-Operation modulus = zahl1 MOD zahl2 ; Auswertung If (modulus = 0) NPrint "Die Division hat keinen Rest." Else NPrint "Die Division weist einen Rest auf." EndIf End
Programmanalyse:
- in den Zeilen 16 bis 20 fragen wir den Benutzer nach der Eingabe von zwei Ganzzahlen und lesen diese jeweils in den Zeilen 18 und 20 ein. Dazu verwenden wir die Funktion Edit(), das Gegenstück für Zahlen zu Edit$() (Letzteres haben wir bereits in anderen Programmen verwendet, um Zeichenketten einzulesen). Der Parameter in Klammern gibt dabei die Anzahl zulässiger Ziffern an – hier sind es 10.
- Zeile 24 führt die Modulus-Operation aus und weist deren Resultat der Variablen modulus zu.
- in den Zeilen 27 bis 31 untersuchen wir mit einer if…else…endif-Abfrage, ob ein Rest vorliegt und geben eine entsprechende Meldung aus. WENN der Wert der Variablen modulus Null beträgt, so gibt es keinen Rest – ANDERNFALLS existiert ein Rest (später mehr zu vergleichenden Abfragen).
Potenzierung
Eine Potenz ist das Ergebnis des Potenzierens (der Exponentiation), das wie das Multiplizieren seinem Ursprung nach eine abkürzende Schreibweise für eine wiederholte mathematische Rechenoperation ist. Wie beim Multiplizieren ein Summand wiederholt addiert wird, so wird beim Potenzieren ein Faktor wiederholt multipliziert. Dabei heißt die Zahl, die zu multiplizieren ist, Basis. Wie oft diese Basis als Faktor auftritt, wird durch den Exponenten angegeben. Man schreibt:
BlitzBasic verwendet zur Potenzierung das Zeichen „^“. Auch diese Rechenoperation schauen wir uns an einem Beispiel an – „power.ab3“:
; ----------------------- ; File: power.ab3 ; Potenzieren ; Version: 1.0 ; ----------------------- OPTIMIZE 1 SYNTAX 1 ; Amiga Version String und das Compilerdatum !version {"power 1.0 (\\__DATE_GER__)"} DEFTYPE .w potenz, basis, faktor ; Werte eingeben NPrint "Potenzieren:" NPrint "Gib zwei Ganzzahlen ein!" Print "Basis: " basis = Edit(5) Print "Faktor: " faktor = Edit(5) NPrint"" ; Potenz-Operation potenz = basis ^ faktor ; Ausgabe NPrint "Die Potenz von " + Str$(basis) + " hoch " + Str$(faktor) + " ist " + Str$(potenz) End
Ausgabe:
Potenzieren: Gib zwei Ganzzahlen ein! Basis: 2 Faktor: 16 Die Potenz von 2 hoch 16 ist 65536
Zum Programmaufbau gibt es nicht viel zu sagen. Den Datentyp der Variablen haben wir mit Long Word (.l) angegeben – Word (.w) wäre zu klein, da beim Potenzieren sehr große Zahlen entstehen können. Den Ablauf dieses Programms solltest du inzwischen ohne weitere Erläuterung verstehen können.
Prozeduren, Statements und Funktionen
Eine Prozedur (Procedure) ist eine Möglichkeit, Routinen (wie z.B. wiederkehrende Berechnungen) in eigenständige Teile des Programms zu „verpacken“. Sobald eine Routine in eine Prozedur verpackt ist, kann sie von deinem Hauptcode aus aufgerufen werden. Parameter können übergeben werden, und ein optionaler Wert wird an den Hauptcode zurückgegeben. Da eine Prozedur ihren eigenen lokalen Variablenbereich enthält, kannst du sicher sein, dass keine deiner Haupt- oder globalen Variablen durch den Aufruf der Prozedur verändert wird. Diese Eigenschaft bedeutet, dass Prozeduren sehr portabel sind, d.h. sie können in andere Programme portiert werden, ohne dass es zu Konflikten mit dort verwendeten Variablennamen gibt.
Einfache Prozeduren geben keine Werte an ihren Aufrufer zurück und werden als Statements bezeichnet. Prozeduren, die Werte zurück liefern, heißen unter BlitzBasic Funktionen. Procedure ist also lediglich der Oberbegriff für Beides.
Funktionen und Statements unter BlitzBasic haben die folgenden Eigenschaften:
- Die Anzahl der Parameter ist auf 6 begrenzt.
- Gosub und Goto zu Labels außerhalb des Codes einer Prozedur sind streng verboten.
- Alle lokalen Variablen, die innerhalb einer Prozedur verwendet werden, werden bei jedem Aufruf neu initialisiert. Ihre Werte sind also nur so lange gültig, wie die Prozedur läuft.
Statements
Ein Statement definiert man nach folgender Schablone:
Statement Name{Parameter} ... Anweisungen ... End Statement
Der Name des Statements ist frei wählbar. Einem Statement können innerhalb der geschweiften Klammern bis zu 6 Parameter mitgegeben werden, die Statement-intern weiterverarbeitet werden. Einem Statement muss nicht zwingend ein Parameter übergeben werden – in dem Fall bleiben die geschweiften Klammern leer. Variablen innerhalb eines Statements sind stets lokal, d.h. nur innerhalb des Statements gültig – es sei denn, man macht sie mit dem Schlüsselwort SHARED allgemein zugänglich.
Das Listing „statement.ab3“ verwendet ein Statement, um den Fakultätsfaktor einer Zahl fünfmal auszugeben.
Beachte, dass bei Verwendung der strengen Syntaxprüfung mittels OPTION 1 sämtliche Variablen im Vorfeld deklariert werden müssen! Außerdem müssen sie in diesem Fall mit ihrem vollen Namen inklusive der Extension (hier: .l) angesprochen werden.
; ---------------------------- ; File: statement.ab3 ; Funktion ohne Rueckgabewert ; Version: 1.0 ; ---------------------------- OPTIMIZE 1 SYNTAX 1 ; Amiga Version String und das Compilerdatum !version {"statement 1.0 (\\__DATE_GER__)"} DEFTYPE .l k ; globale Variable: k ; ein Statement definieren Statement fact{n.l} DEFTYPE .l a, k ; Lokale Variablen: a, k a.l = 1 For k.l = 2 To n.l a.l = a.l * k.l Next NPrint a End Statement ; Hauptteil For k.l = 1 To 5 fact{k.l} ; Aufruf des Statements Next End
Ausgabe:
1 2 6 24 120
Programmanalyse:
- Zeile 12 deklariert die im Hauptteil (außerhalb des Statements) verwendete globale Variable als Long Word.
- die Zeilen 15 bis 24 definieren das Statement fact{n.l}.
- Zeile 15 ist der Kopf des Statements, bestehend aus dem Schlüsselwort Statement, dem Namen (fact) und der Parameterliste in geschweiften Klammern. Sie enthält nur einen Parameter: n. Beachte, dass aufgrund der strengen Syntaxprüfung der Parameter n mit einem Datentyp deklariert werden muss.
- die Zeilen 16 bis 23 sind der Rumpf des Statements, der in Zeile 24 mit der Anweisung End Statement abgeschlossen wird.
- Zeile 16 deklariert die lokalen Variablen des Statements als Long Word.
- Zeile 18 initialisiert die lokale Variable a.l mit dem Wert 1.
- in den Zeilen 19 bis 21 wird mittels einer for…next-Schleife (später mehr dazu!) der Wert der Variablen a.l mit sich selbst multipliziert.
- der berechnete Wert wird in Zeile 23 ausgegeben.
- Auch im Hauptteil ab Zeile 27 wird eine for…next-Schleife verwendet. Sie läuft fünf mal und ruft bei jedem Durchlauf einmal das Statement fact{n.l} auf. Würde man also den Zähler der Schleife erhöhen, so würden dementsprechend mehr Zahlen ausgegeben werden. Versuche es spaßeshalber: Ersetze die Zahl 5 in Zeile 27 mit der Zahl 10 und compiliere und starte das Programm erneut.
Anmerkung: Das geht nur bis maximal zur Zahl 16 gut – ab 17 läuft die Variable über!
Funktionen
Im Gegensatz zu Statements liefern Funktionen über die Anweisung Function Return einen weiter verarbeitbaren Wert an den Aufrufer zurück. Eine Funktion definiert man nach folgender Schablone:
Funktion Name{Parameter} ... Anweisungen ... Function Return Variable ; Rückgabewert End Funktion
Unser Beispiel für ein Statement lässt sich ohne Aufwand auch als Funktion realisieren. Dabei geben wir die berechnete Zahl nicht gleich direkt aus, sondern übergeben sie dem Aufrufer im Hauptteil des Programms. Das Listing „function.ab3“ zeigt, wie es funktioniert:
; ---------------------------- ; File: function.ab3 ; Funktion mit Rueckgabewert ; Version: 1.0 ; ---------------------------- OPTIMIZE 1 SYNTAX 1 ; Amiga Version String und das Compilerdatum !version {"function 1.0 (\\__DATE_GER__)"} DEFTYPE .l k ;Globale Variablen deklarieren ; Funktion definieren Function fact{n.l} DEFTYPE .l a, k ; Lokale Variablen deklarieren a.l = 1 For k.l = 2 To n.l a.l = a.l * k.l Next Function Return a.l ; Rueckgabewert End Function ; Hauptteil For k.l = 1 To 5 NPrint fact{k.l} ; Rueckgabewert drucken Next End
Die Programmlogik ist nahezu identisch zum vorherigen Listing – allerdings geben wir nun in Zeile 23 den berechneten Wert mit Function Return an den Aufrufer (NPrint) in Zeile 28 zurück.
Zugriff auf globale Variablen
Manchmal ist es notwendig, dass eine Prozedur auf eine oder mehrere globale Variablen eines Programms zugreifen kann. Zu diesem Zweck erlaubt der SHARED-Befehl, bestimmte Variablen innerhalb einer Prozedur als globale Variablen zu behandelt. Dazu ein schnelles Beispiel:
Statement example{} SHARED k NPrint k End Statement For k=1 To 5 example{} Next
Per SHARED-Befehl teilst du dem Compiler mit, dass die Prozedur die globale Variable k verwenden soll, anstatt eine lokale Variable k zu erzeugen. Versuche dasselbe Programm ohne den SHARED-Befehl: Jetzt ist k innerhalb der Prozedur eine lokale Variable und wird daher jedes Mal 0 sein, wenn die Prozedur aufgerufen wird.
Rekursion
Der von den lokalen Variablen einer Prozedur verwendete Speicher ist nicht nur für die eigentliche Prozedur, sondern für jeden Aufruf der Prozedur reserviert. Jedes Mal, wenn eine Prozedur aufgerufen wird, wird ein neuer Speicherblock zugewiesen und erst nach Beendigung der Prozedur wieder freigegeben. Dies hat zur Folge, dass eine Prozedur sich selbst aufrufen kann, ohne ihre eigenen lokalen Variablen zu beschädigen. Das ermöglicht ein Phänomen, das als Rekursion bekannt ist. Hier ist eine neue Version der faktoriellen Funktion, die Rekursion verwendet:
; ---------------------------- ; File: recursion.ab3 ; rekursiver Funktionsaufruf ; Version: 1.0 ; ---------------------------- OPTIMIZE 1 SYNTAX 1 ; Amiga Version String und das Compilerdatum !version {"recursion 1.0 (\\__DATE_GER__)"} DEFTYPE .l n ;Globale Variablen deklarieren ; Funktion definieren Function fact{n.l} If n.l > 2 Then n.l = n.l * fact{n.l - 1} ; Rekursiver Aufruf Function Return n.l ; Rueckgabewert End Function ; Hauptteil For n.l = 1 To 5 NPrint fact{n.l} ; Rueckgabewert drucken Next End
Dieses Beispiel beruht auf dem Konzept, dass die Berechnung der Fakultät einer Zahl eigentlich die Zahl, multipliziert mit dem Faktor von Eins weniger als die Zahl darstellt (Zahl – 1, vergl. Zeile 16).
Zusammenfassung
In diesem Teil des Tutorials haben wir gelernt
- wie man unter BlitzBasic die Grundrechenarten und den Modulo-Operator verwendet und wie man Zahlen potenziert.
- wie die Hierarchie der Rechenoperationen aufgebaut ist und wie man sie durch Klammerung verändern kann.
- auf was es bei der Wahl des Datentyps für eine Variable ankommt.
- wie man einen numerischen Wert mittels des Edit()-Befehls einliest.
- das bei Zuweisung einer Fließkommavariablen an eine Ganzzahlvariable der Nachkommaanteil verloren geht.
- das Prozeduren ein Oberbegriff für Statements und Funktionen sind.
- das man Prozeduren maximal 6 Parameter übergeben kann.
- das Statements im Gegensatz zu Funktionen keinen Rückgabewert liefern.
- das Variablen innerhalb von Prozeduren lokaler Natur sind und nur innerhalb der jeweiligen Prozedur Gültigkeit besitzen.
- Das lokale Variablen für andere Prozeduren und das Hauptprogramm nicht sichtbar sind, mittels des Schlüsselwortes SHARED aber sichtbar gemacht werden können.
- das Prozeduren sich selbst rekursiv aufrufen können, wobei die Werte lokaler Variablen erhalten bleiben.
Ausblick
Im kommenden Teil des Tutorials werden wir uns Kontrollstrukturen zur Fallunterscheidung und Verzweigung, Wiederholungsschleifen, Wahrheitswerte und Vergleichsoperatoren näher betrachten.
[Zurück zur Übersicht] | [zurück] | [vowärts]