13.1. Funktionen & Prozeduren mit Parameterübergabe |
![]() |
![]() |
Letztmalig dran rumgefummelt: 06.06.12 21:46:21 |
![]() |
Durch Unterprogamme
(Subroutinen) wird
unter einem Namen etwas getan oder durch einen entsprechenden Algorithmus
Werte ermittelt, die dann vom aufrufenden Programm abgefordert werden können
(vermittelt durch einen Referenz- oder Übergabeparameter). Die zu
bearbeitenden aktuellen Werte gehen in das Unterprogramm ein, welches den
Algorithmus zu deren Verarbeitung enthält. Alle Unterprogramme haben ihren
eigentlichen Sinn im mehrfachen Zurverfügungstellen häufig benötigter
Programmteile an verschiedenen Stellen des Programmes. Sie können somit
theoretisch unendlich viele Male im Programm aufgerufen werden und erledigen
immer die gleiche Operation. Später wurden sie zur Grundlage des modularen
Aufbaus von Programmen sowie des Konzepts der objektorientierten
Programmierung. Das Prinzip der Rekursion und des Verlassens von Programmen
macht es sogar möglich, daß sich Unterprogramme selbst mehrfach aufrufen
können. Jede Funktion lässt sich als Prozedur umschreiben, aber nicht jede Prozedur als Funktion! Unterprogramme in Turbo-PASCAL werden unterschieden nach PROCEDURE (Prozeduren), bzw. FUNCTION (Funktionen)
|
||||
![]() |
0. Unterprogramme - Gültigkeitsbereiche von Deklarationen |
||||
![]() |
|
||||
![]() |
Quellen:
|
||||
![]() |
Prozeduren und Funktionen sind an und für sich nichts Neues für den geübten Programmierer - zumal nicht in Delphi. Als vordefinierte Funktionen sowie Ereignisprozeduren sind sie ständig präsent. Wie aber funktioniert alles genau und welche Konsequenzen hat ihre Verwendung in rekursiven Datenstrukturen? Dies ist nunmehr an dieser Stelle abzuklären. |
0. Unterprogramme - Gültigkeitsbereiche von Deklarationen |
![]() |
![]() |
![]() |
![]() |
Unterprogramme - also Subroutines sind Bestandteile
eines Programmes, welche, ähnlich Zyklen, mehrfach "aufgerufen" werden
können - das Konzept mancher Programmiersysteme (wie z. B. Delphi) nutzt
diese auch mit nur einem Aufruf - und das lohnt sich laufzeittechnisch. Der
Unterschied zu Zyklen liegt genau darin, dass jeweils verschiedene Parameter
verarbeitet werden können, was mit einer Schleife so nicht möglich ist. Die
hoch spezialisierten Software-Entwicklungssysteme wie C ++ und PASCAL
unterstützen die Trennung in PROZEDUREN und FUNKTIONEN und unterscheiden
diese sehr wohl!!! Nicht alle innerhalb eines Programms verwendeten Vereinbarungen sind auch überall bekannt und somit gültig. Unterschieden werden lokale und globale Deklarationen - dies hat Konsequenzen auch für die Bezeichner, denn die Namen lokaler Größen dürfen in verschiedenen Subroutinen prinzipiell auch mehrfach vorkommen und sind trotzdem eigenständige Größe. |
||||||||||
![]() |
|||||||||||
![]() |
|||||||||||
![]() |
|
||||||||||
![]() |
... es gilt der alte Lehrsatz: ... deklariere so lokal wie möglich und so global wie notwendig - jede Großzügigkeit hierin rächt sich im logischen Programmlauf!!! | ||||||||||
![]() |
Lokale Vereinbarungen haben nur innerhalb einer Verwaltungseinheit Gültigkeit und dürfen mit gleichem Namen in anderen Verwaltungseinheiten deklariert werden - sie sind dort auch etwas anderes | ||||||||||
![]() |
die FORWARD-Deklaration |
1. Prozeduren |
![]() |
![]() |
![]() |
![]() |
Alle in sich logisch selbständig arbeitenden Programmelemente sollten als solche Prozeduren vereinbart werden. Das bringt den Vorteil, dass sie sicher getestet werden und leicht in das Hauptprogramm einbindbar sind. Wird eine solche Prozedur einmal nicht benötigt, braucht sie nur im Aufruf des Hauptprogrammes gestrichen zu werden. Zusätzlich lässt sich mit wenig Aufwand bei Bedarf der Speicheraufwand senken, denn fertige Prozeduren sind sofort in UNIT's oder INCLUDE-Files konvertierbar. | |||
![]() |
Prozeduren können mehrere Werte aus einer rufenden Struktur übernehmen und auch mehrere solcher Parameter zurückgeben (das macht natürlich nur dann Sinn, wenn die zugehörigen Parameter auch als Referenzen deklariert wurden | |||
![]() |
|
2. Funktionen |
![]() |
![]() |
![]() |
![]() |
Hierbei wird unter einem Namen ein Wert berechnet oder durch einen entsprechenden Algorithmus ermittelt, der dann unter diesem Namen vom aufrufenden Programm abgefordert werden kann (vermittelt durch einen Werteparameter - das ist in diesem Falle der Name der Funktion selbst!). Die zu verrechnenden aktuellen Werte gehen in die Funktion ein, welche den Algorithmus zu deren Verarbeitung enthält. Die Ergebnisse können nur einer Variablen des übergeordneten Programmes, vermittelt durch den Namen der Funktion, zugeordnet werden. Sie stehen nicht als eigenständige Anweisungsfolge zur Verfügung (stehen also im rufenden Programm niemals allein auf einer Zeile!) sondern bilden einen Ausdruck, der faktisch in einer Variablen (nämlich dem Funktionsnamen) ein Ergebnis ermittelt und dies als Wert übergeben kann, bzw. wird über WRITELN(funktionsname) der aktuelle Inhalt des wie eine Variable gehandhabten Funktionsnamen ausgegeben. | |||
![]() |
Deklaration einer Funktion
FUNCTION
funktionsname (formalparameterliste:typ):ergebnistyp; |
|||
![]() |
Aufruf einer Funktion
variable:=functionsname(parameterliste); |
|||
![]() |
Besonderheiten einer Funktion
|
|||
![]() |
Beispiel einer Funktionsanwendung
PROGRAM
negation_einer_zahl (INPUT,OUTPUT); |
|||
![]() |
|
3. Formale Parameter |
![]() |
![]() |
![]() |
![]() |
Sie bilden die Stellvertreter der zu übergebenden Parameter innerhalb der Subroutine. Sie sind in jedem Falle lokale Deklarationen und können als Werte- oder Referenzparameter inintialisiert werden. Referenzen sind in jedem Falle speicheroptimaler, da keine neuen Speicherbreiche reserviert werden müssen, was insbesondere bei Übergabe von Arrays und/oder Objekten folgenreich sein kann, wenn diese groß sind. |
![]() |
beiden ist aber das Prinzip des rekursiven Abstiegs und nachfolgenden rekursiven Aufstiegs gemein |
4. Aktuelle und/oder Übergabeparameter |
![]() |
![]() |
![]() |
![]() |
Sie bilden die aktuellen Werte, welche an eine zu rufende Struktur aus einer übergordneten Einheit heraus mit gegeben werden. Sie sind genau diejenigen Daten, welche von einer zu rufenden Einheit verarbeitet werden sollen. |
![]() |
5. Call by Value |
![]() |
![]() |
![]() |
![]() |
In diesem Falle baut die zu rufende Stuktur eine neue lokale Deklaration auf, welche nur solange instanziert wird, wie diejenige Struktur selbst aktiv ist - danach wird sie automatisch wieder frei gegeben, was auch für den zugehörigen Speicherplatz gilt. Das bedeutet aber auch, dass Veränderungen dieser Parameter nach Austritt aus der Subroutine verloren gehen. |
![]() |
6. Call by References |
![]() |
![]() |
![]() |
![]() |
In einem Ast wird gerechnet, im anderen mit veränderten Argument nur die Funktion oder Prozedur bis zu Abbruchbedingung selbst aufgerufen. Ob im ausfsteigenden oder absteigenden Ast gerechnet wird, hängt von der physischen Stelle des Unterprogrammaufrufes auf sich selbst ab (Anfang oder Ende). |
![]() |
7. Verwandte Themen |
![]() |
![]() |
![]() |
![]() |
Das Vorangestellte hilft wirtschaften, löst jedoch kein einziges Problem (allerdings ohne Beachtung der Worst-Case-Strategien wird man auch nicht erfolgreich Software entwickeln und/oder informatische Projekte realisieren können). Deshalb nunmehr das, was wirklich Arbeiten hilft. | ||||||||||||
![]() |
|
||||||||||||
![]() |
|
||||||||||||
![]() |
|
![]() zur Hauptseite |
© Samuel-von-Pufendorf-Gymnasium Flöha | © Frank Rost im September 2007 |
... dieser Text wurde nach den Regeln irgendeiner Rechtschreibreform verfasst - ich hab' irgendwann einmal beschlossen, an diesem Zirkus nicht mehr teilzunehmen ;-) „Dieses Land braucht eine Steuerreform, dieses Land braucht eine Rentenreform - wir schreiben Schiffahrt mit drei „f“!“ Diddi Hallervorden, dt. Komiker und Kabarettist |
Diese Seite wurde ohne Zusatz irgendwelcher Konversationsstoffe erstellt ;-) |