sub
sub
Deklaration einer Prozedur-Unterfunktion
Details
- Siehe: Verwandte Befehle ,
main,declare,return
Innerhalb einer Prozedur können bis zu 65.500 einzelne Funktionen definiert werden, die sowohl innerhalb der Prozedur als auch von anderen Prozeduren aufgerufen werden können.
Funktionsname
Nach dem Schlüsselwort sub wird der Name der Funktion angegeben. Der Name darf maximal 40 Zeichen lang sein und muss mit einem Buchstaben oder "_" beginnen.
Argumente
Bei einer Funktion können bis zu 64 Argumente deklariert werden. Im Gegensatz zur main-Funktion muss bei der Deklaration der Name der Funktion angegeben werden.
sub <name>
(
<name> : <typ> [[ ; <name> : <typ> ]]
)
Die Deklaration der einzelnen Argumente erfolgt analog zu der Deklaration von Variablen (global).
Dabei werden die Argumente per Wert übergeben, das heißt im jeweiligen Argument steht eine Kopie des übergebenen Wertes (call-by-value). Dabei können keine kompletten Arrays als Wert übergeben werden.
Beispiel:
sub Validate
(
aFieldVal : int;
aDifference : int;
)
Alternativ können die Argumente auch als Referenz deklariert werden (call-by-reference). Dabei wird dem Argumentnamen das Schlüsselwort var vorangestellt. In diesem Fall können auch Arrays übergeben werden. Die Übergabe als Referenz bedeutet, dass das Argument als Bezeichnung der übergebenen Variablen benutzt wird. Eine Veränderung des Argumentwertes hat somit eine gleichzeitige Veränderung der übergebenen Variablen zur Folge, da das Argument lediglich eine Referenz darstellt.
Bei Referenzargumenten können demnach keine konstanten Werte übergeben werden. Zulässig sind ausschließlich Variablen, Elemente von Arrays, Arrays und Felder der Datenstruktur. Dabei muss beachtet werden, dass aus dem Argument die ursprüngliche Art (zum Beispiel Feld oder Variable) der Referenz nicht mehr hervorgeht.
Bei Referenzen dürfen bei einem Übergabewert vom Typ alpha keine Längenangaben stehen und bei einem Array keine Elementanzahl, da diese Werte sich implizit aus den übergebenen Variablen ergeben.
Argumente können auch optional deklariert werden. Dies geschieht durch das vorangestellte Schlüsselwort opt.
Beispiel:
sub Validate
(
aFieldVal : int;
opt aDifference : int;
)
Nach dem ersten opt-Argument müssen alle nachfolgenden Argumente ebenfalls mit opt deklariert werden. opt und var können nicht kombiniert werden. Nicht übergebene Argumente werden in der Funktion mit NULL initialisiert. Es ist ferner zulässig, alle Argumente mit opt zu deklarieren.
Der Aufruf einer Funktion mit optionalen Argumente ist auch mit Call () möglich.
Beispiel:
sub Validate
(
var aFieldVal : int;
var aValTab : byte[];
var aError : alpha;
)
Rückgabewert
Eine Funktion kann mit einem Rückgabetyp deklariert werden. Durch Definition eines Rückgabetyps kann die Funktion bei Zuweisungen, innerhalb eines Ausdrucks oder als Funktionargument benutzt werden. Dabei wird der Typ des Rückgabewerts mit ': <typ>' nach dem Namen bzw. der Argumentliste der Funktion angegeben.
Beispiel:
sub Difference ( aValOrg, aValNew : int; ) : int;
Der Rückgabewert muss mit der return-Anweisung explizit angegeben werden. Dabei sind beliebig viele return-Anweisungen innerhalb der Funktion möglich. Sofern kein return ausgeführt wird, wird ein leerer Wert (0) zurückgegeben. Es ist zu beachten, dass mit return die Funktion an der entsprechenden Stelle beendet wird.
Beispiel:
sub Difference ( aValOrg, aValNew : int; ) : int;
{
if (aValOrg > aValNew)
return(aValOrg - aValNew)
else
return(aValNew - aValOrg)
}
Aufruf von sub-Funktionen
Der Aufruf einer Funktion geschieht durch Angabe des Funktionsnamens, gefolgt von der in Klammern eingeschlossenen Liste der Argumente. Falls das erste Argument einer sub-Funktion vom Typ handle ist, kann das Argument dem Funktionsaufruf mit dem Pfeiloperator -> vorangestellt werden. Alternativ zu Function(aHandle, a, b) kann also auch aHandle->Function(a,b) verwendet werden.
Besitzt die Funktion keine Argumente, wird eine leere Liste angegeben. Beim Aufruf einer sub-Funktion in einer anderen Prozedur muss der Prozedurname dem Funktionsnamen vorangestellt werden.
Beispiele:
Diff(SaveVal, NewVal); // ruft die Funktion Diff in derselben
// Prozedur auf
Test(); // ruft die Funktion Test ohne Argument auf
Kd.Check:TestNr(); // ruft die Funktion TestNr in der Prozedur
// Kd.Check auf
Kd.Check(122); // ruft die main-Funktion in der Prozedur
// Kd.Check mit dem Parameter 122 auf
Hieraus ist ersichtlich, dass die main-Funktion einer anderen Prozedur nur dann aufgerufen werden kann, wenn keine sub-Funktion innerhalb der aufrufenden Prozedur den gleichen Namen hat, wie die aufgerufene Prozedur. Da die übergebenen Argumente an eine Funktion bei der Übersetzung überprüft werden, müssen die benutzten Funktionen aus anderen Prozeduren bereits in kompilierter Form vorliegen.
Sofern die Funktion einen Rückgabewert besitzt, kann dieser in einer Zuweisung, einem Ausdruck oder als Funktionsargument benutzt werden. Funktionen mit Rückgabewert können auch alleinstehend aufgerufen werden, in diesem Fall wird der Rückgabewert ignoriert.
Beispiele:
LocDiff # Diff(SaveVal, NewVal);
if (Diff(SaveVal, NewVal) > 100) ...
Kd.Check(Diff(SaveVal, NewVal));
Sind bei der aufgerufenen Funktion Argumente als Referenz deklariert, so müssen die übergebenen Variablen ebenfalls mit var deklariert werden.
Beispiel:
sub Validate ( var aFieldVal : int; )
...
Validate(var Af.Sum)
Validate(var ValueTab[10])
sub-Funktionen können ebenfalls aus 4.0-kompatiblen Prozeduren aufgerufen werden. Unabhängig vom verwendeten Verfahren für die Parameterübergabe (call-by-reference oder call-by-value) werden die Parameter ohne var deklariert.
Zum Aufruf der Funktion wird beim Befehl Call () der Name der Prozedur und der Name der Funktion durch einen ':' getrennt angegeben. Bei der Angabe der Parameter werden die Parameter mit einem var gekennzeichnet, die als Referenz übergeben werden sollen.
Beispiel:
Call('Kd.Check:TestNumber'); // ruft die Funktion TestNumber in der
// Prozedur Kd.Check auf