Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Tutorial

Variable Parameterlisten

von RedakteurMODSeite 1 von 4

Allgemeine Grundlagen

Meistens weiß man, wie viele Parameter eine Funktion erhalten soll, manchmal weiß man das allerdings nicht. Für den zweiten Fall kann man in einigen Fällen mit Überladung noch nachhelfen, doch wenn es absolut keine Regel für die Parameter gibt, dann hilft auch das nicht.
Ein Beispiel dafür wäre z. B. der interne BefehlsreferenzeintragPrint-Befehl.

Print 1, 2, 3, 4
Print 1, 2, 3, 4, 5
Print "1", "zwei", 3.00

Dem Befehl ist die Anzahl und die Art der Parameter in den meisten Fälle ziemlich egal. Möchten wir nun eine ähnlich funktionierende Funktion erstellen, bietet FreeBASIC dafür eine Lösung.
Folgende Befehle sind hierbei wichtig:

BefehlsreferenzeintragCDECL definiert, in welcher Reihenfolge die Parameter im Speicher abgelegt werden. Standardmäßig verwendet FreeBASIC hier BefehlsreferenzeintragSTDCALL, für eine variable Parameterliste muss aber zwingend CDECL angegeben werden, da es sonst zu einer Fehlermeldung kommt.
Um einfach mal in die Thematik einzutauchen, brauchen wir ein Beispiel, bei dem eine variable Parameterliste nötig sein könnte. Nicht gerade hilfreich, dafür aber sehr verständlich wäre eine Funktion, die einige Zahlen entgegennimmt und die Summe zurückliefert.

Function add Cdecl (anzahl As Integer, ...) As Integer
    Dim As Integer summe

    Dim As Any Ptr argument = va_first()


    For i As Integer = 1 To anzahl
        summe += va_arg(argument, Integer)
        argument = va_next(argument, Integer)
    Next

    Return summe
End Function

Print add(2, 3, 5)
Sleep

Die Erklärung der Befehle folgt gleich, doch probiert erstmal diesen Code aus, denn hier fällt schon beim Starten auf, 2+3+5 ist nicht 8. Was ist also passiert?

Wie man in der ersten Zeile sieht, ist der erste Parameter fest vorgegeben, dieser ist aber nicht der erste Wert, der addiert werden soll, es handelt sich dabei um einen Parameter, der die Anzahl der folgenden Parameter vorgibt. Das hat zwei Gründe.
Bei einer variablen Parameterliste muss mindestens ein Parameter vorgegeben werden. Der zweite Grund ist, dass die im Speicher liegenden Parameter nicht direkt bekannt sind. Somit ist auch nicht erkennbar, wann die Liste endet.
Nun gibt es eben die Möglichkeit, den ersten Parameter dazu zu missbrauchen, wie viele Parameter gelesen werden sollen oder man definiert eine Endbedingung. Ein Beispiel könnte sein: "Lese solange ein, bis Zahl = 0".

Function add Cdecl (wert1 As Integer, ...) As Integer
    Dim As Integer summe
    Dim As Integer zahl = wert1

    Dim As Any Ptr argument = va_first()


    While zahl <> 0
        summe += zahl
        zahl = va_arg(argument, Integer)
        argument = va_next(argument, Integer)
    Wend

    Return summe
End Function

Print add(2, 3, 5, 0)
Sleep

Ob man nun die Anzahl angibt oder eine Endbedingung definiert ist oft nur Geschmackssache. Sobald die Parameter allerdings verschiedene Datentypen enthalten, muss anders vorgegangen werden, dazu aber später mehr.

Jetzt haben wir ein paar Beispiele gesehen, doch was machen nun die einzelnen Befehle? Fangen wir von oben an:

Dim As Any Ptr argument = va_first()

Hier wird zunächst die Adresse des ersten variablen Parameters gesichert.

summe += va_arg(argument, Integer)

VA_ARG nimmt nun diese Adresse und definiert, dass sich an dieser Stelle eine Zahl vom Typ BefehlsreferenzeintragInteger befindet und gibt diese zurück. Der Typ muss angegeben werden, da anhand der Adresse nicht erkannt werden kann, was für Daten dort gespeichert wurden. Also muss der Programmierer dem Programm sagen, dass er dort einen bestimmten Typ erwartet und das Programm diese als solche interpretieren soll.

argument = va_next(argument, Integer)

Zuletzt wird die Adresse aktualisiert. Dafür muss auch hier der Typ angegeben werden, damit die Funktion weiß, wie weit sie zur nächsten Adresse springen soll.

Da ich vorhin erwähnt hatte, dass mindestens ein Parameter vorgegeben sein muss, es können natürlich auch mehr vorgegeben werden. Hier ein Beispiel:

Function add Cdecl (anzahl As Integer, operand As String, ...) As String
    Dim As String ergebnis

    Dim As Any Ptr argument = va_first()


    For i As Integer = 1 To anzahl
        Select Case operand
            Case "+"
                ergebnis += *va_arg(argument, ZString Ptr)
            Case Else
                ergebnis = *va_arg(argument, ZString Ptr)
        End Select

        argument = va_next(argument, ZString Ptr)
    Next

    Return ergebnis
End Function


Print add(2, "+", "Hallo ", "Welt!")
Sleep

Was allerdings nicht geht ist, dass man die variable Parameterliste zwischen vorgegebene legt, also in etwa so:

Function add Cdecl (anzahl As Integer, ..., operand As String) As String

 

Gehe zu Seite Gehe zu Seite  1  2  3  4  
Zusätzliche Informationen und Funktionen
  • Das Tutorial wurde am 06.04.2011 von RedakteurMOD angelegt.
  • Die aktuellste Version wurde am 28.08.2011 von RedakteurMOD gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen