Prozeduren und Funktionen

Visual Basic unterscheidet Prozeduren und Funktionen. Funktionen liefern Rückgabewerte zurück, während Prozeduren dies nicht tun. Im Folgenden werden Prozeduren und Funktionen synonym verwendet, wenn dies nicht ausdrücklich anders gesagt wird.

Parameterlisten

Parametervereinbarungen in Prozeduren oder Funktionen haben die folgende Syntax:

< BYREF | BYVAL > Variable AS Datentyp

Bei der Paramterübergabe wird zwischen Wert- (Call-By-Value) und Referenzübergabe (Call-By-Reference) unterschieden. BYREF und BYVAL sind alternativ zu gebrauchen (wird beides weggelassen wird standardmäßig Call-By-Value durchgeführt).
Die Unterscheidung Call-By-Value, Call-By-Reference ist für Anfänger erst einmal nicht einsichtig. Man muss wissen, dass bei Wertübergabe eine physikalische Kopie des Wertes übergeben wird, bei einer Referenzübergabe wird ein Verweis auf die Variable aus der aufrufenden Prozedur übergeben. Ändert nun die Prozedur den Eingabeparameter, wird dieser neue Wert bei Referenzübergabe an die aufrufende Prozedur weitergereicht. Bei Wertübergabe ist dies nicht der Fall. Ein Beispiel dazu im Kapitel 1.3.2. Parameterlisten haben folgende Syntax:

[Parametervereinbarung] [, Parameterliste] ]

Es können also leere oder beliebig viele durch Komma getrennte Parametervereinbarungen in einer Liste stehen. Beispiel:

X AS INTEGER, Y AS SINGLE

Prozeduren

Im Prozedurkopf wird neben dem Prozedurnamen die Parameterliste deklariert. Eine Prozedur muss mit dem Fuß END SUB enden. Mit Hilfe des Befehls EXIT SUB kann eine Prozedur vorzeitig verlassen werden. Syntax:

SUB Prozedure-Name (Parameterliste) Anweisungsfolge .... [EXIT SUB] ... END SUB

Beispiel: Prozedurvereinbarung
Die folgende Prozedur berechnet die Fakultät des Parameter n und gibt das Ergebnis mit Hilfe einer MessageBox aus. Das numerische Ergebnis wird dafür durch die Funktion Str in einen String umgewandelt. (Die Syntax der Funktion MsgBox finden Sie im zweiten Kapitel.)

SUB factorial (n AS BYTE) DIM i AS INTEGER, result AS LONG result = 1 FOR i = 2 TO n result = result * i NEXT i MSGBOX STR(result) END

Es ist zu bemerken, dass diese Prozedur für große n fehlschlagen kann. Es erfolgt dann ein Überlauf, da der zulässige Bereich von LONG überschritten wird. Ändert nun die Prozedur beispielsweise die Variable n, passiert in der aufrufenden Prozedur mit dem Eingabeparameter nichts. (Dies ist allerdings auch kein sonderlich guter Stil!) Wäre n als Referenz übergeben, würde in der aufrufenden Prozedur die Variable auch verändert. Beispiel: Referenzübergabe
Das folgende Beispiel gibt im Parameter result das Ergebnis zurück. Wie im vorigen Beispiel wird die Fakultät von n berechnet. Die Aufrufende Funktion TestFactorial gibt das Ergebnis dann per MessageBox aus.

SUB factorial (n AS BYTE, result AS LONG) DIM i AS INTEGER result = 1 FOR i = 2 TO n result = result * i NEXT i END SUB SUB TestFactorial DIM a AS BYTE, b AS LONG a = 10 CALL factorial(a, b) MSGBOX STR(b) END SUB

In diesem Beispiel sieht man nun auch einen Prozeudraufruf, der hier mit dem Befehl CALL erfolgt. Syntax eines Prozeduraufrufs:

[CALL] Prozedurname [Argumentliste]

Es ist nicht notwendig bei einem Prozeduraufruf das Schlüsselwort CALL zu benutzen. Wird CALL für einen Aufruf mit Parameter verwendet, so sind die Parameter in Klammern zu setzen. Wird CALL weggelassen, so müssen auch die Klammeren um etwaige Parameter weggelassen werden.
Um ein ganzes Array zu übergeben, wird der Name des Arrays mit nachfolgendem leeren Klammernpaar als Parameter angegeben. Auch Funktionen können auf diese Art aufgerufen werden. Dann wird allerdings der Rückgabewert ignoriert. Beispiel: Übergabe eines Arrays

DIM a (20) AS INTEGER SortArray a()

Hier wurde das Schlüsselwort CALL und die Klammern um die Parameterliste weggelassen. Wir führen das obige Beispiel fort und geben noch die Prozedur SortArray an. Als Übergabeparameter wird ein eindimensionales Array aus Integer-Variablen erwartet, das verändert wird. Beispiel: Übergabe eines Arrays
Als Sortieralgorithmus wird der nicht besonders effiziente, dafür relativ einfache BubbleSort verwendet. (Mehr darüber findet man in jedem besseren Informatik-Buch.) Zur Bestimmung der Arraygrenzen werden die Funktionen LBOUND(a,d) und UBOUND(a,d) verwendet. (Siehe dazu Kapitel 1.1.2 Variablenvereinbarung) Unser Array ist eindimensional, so dass d = 1 ist.

SUB SortArray(a() AS INTEGER) DIM i AS INTEGER, j AS INTEGER FOR i = UBound(a, 1) TO LBound(a, 1) STEP -1 FOR j = LBound(a, 1) TO (i - 1) IF a(j) > a(j + 1) THEN ' Vertausche j und j+1 tes Element temp = a(j) a(j) = a(j + 1) a(j + 1) = temp END IF NEXT j NEXTi END SUB

Funktionen

Die Syntax einer Funktionsdeklaration ist der einer Prozedurdeklaration sehr ähnlich, bis auf das Schlüsselwort FUNCTION anstatt SUB. Mit Hilfe des Befehls EXIT FUNCTION kann eine Funktion vorzeitig verlassen werden.

FUNCTION Prozedure-Name ([Parameterliste]) AS Variablentyp Anweisungsfolge ... [EXIT FUNCTION] .... Prozedur-Name = Rückgabewert ... [EXIT FUNCTION] ... END FUNCTION

Zu beachten ist, dass der Rügabewert durch Zuweisung an den Funktionsnamen zurückgegeben wird. Beispiel: Größter gemeinsamen Teilers
Mit Hilfe des Modulo-Operators kann der berühmte Algorithmus von Euklid zur Bestimmung des größten gemeinsamen Teilers zweier natürlicher Zahlen implementiert werden. Hier ist die rekursive Variante angegeben.

FUNCTION ggt (x AS INTEGER, y AS INTEGER) AS INTEGER DIM result as INTEGER IF y = 0 THEN result = abs (x) ELSE result = ggt (y, x MOD y) ENDIF ggt = result END FUNCTION

Der Aufruf einer Funktion ist hier schon zu sehen und ist analog zu den Aufrufen für eingebaute Funktionen. Siehe dazu auch die Syntax des CALL Befehls im vorigen Abschnitt.