Proceduren mit einer variablen Anzahl an Parametern

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Proceduren mit einer variablen Anzahl an Parametern

Beitrag von ts-soft »

Ich glaube, wir hatten hier schon ähnliche Beiträge, konnte die aber nicht finden.

Aus C, Freebasic oder anderen Sprachen kennt Ihr vielleicht Funktionsaufrufe, mit
variabler Parameteranzahl, meist durch 3 Punkte dargestellt.

Ich hab hier mal eine Variante für PB gebastelt, die vielleicht für den einen oder
anderen nützlich sein könnte.

ACHTUNG: Für strings bitte unbedingt das Beispiel angucken!

Die Übergabe erfolgt per strukturiertem Array. Das weitere kann man aus dem
Code ersehen.
Parameter werden mit der Procedure V_ARG_Add() hinzugefügt.
Wenn alle Parameter hinzugefügt wurden, dann unser Procedure,
siehe Foo(), mit diesem Array aufrufen.

Code: Alles auswählen

;==================================================================
; ###  Example to use variable parameters for Procedures    ###
; Author:            Thomas <ts-soft> Schulz
; Date:              Mrz 16, 2012
; Version:           1.0
; Target OS:         All
; Target Compiler:   PureBasic 4.40 and later
;==================================================================

EnableExplicit

Structure V_ARG
  Type.l
  StructureUnion
    a.a
    b.b
    c.c
    d.d
    f.f
    i.i
    l.l
    *s.String
    q.q
    u.u
    w.w
  EndStructureUnion
EndStructure

Procedure V_ARG_Add(Array V_ARG.V_ARG(1), Type.l, *value)
  Protected index = ArraySize(V_ARG())
  Protected *v.Quad = *value
  ReDim V_ARG(index + 1)

  With V_ARG(index)
    \Type = Type
    \q = *v\q
  EndWith
EndProcedure

; example
Procedure Foo(Array V_ARG.V_ARG(1))
  Protected i
  Protected count = ArraySize(V_ARG())
  Debug "Count of parameters: " + Str(count)
  Debug ""
  For i = 0 To count - 1
    With V_ARG(i)
      Select \Type
        Case #PB_Ascii
          Debug "Parameter " + Str(i + 1) + " = UByte, Value = " + Str(V_ARG(i)\a)
        Case #PB_Byte
          Debug "Parameter " + Str(i + 1) + " = Byte, Value = " + Str(V_ARG(i)\b)
        Case #PB_Character
          Debug "Parameter " + Str(i + 1) + " = Char, Value = " + Str(V_ARG(i)\c)
        Case #PB_Double
          Debug "Parameter " + Str(i + 1) + " = Double, Value = " + StrD(V_ARG(i)\d)
        Case #PB_Float
          Debug "Parameter " + Str(i + 1) + " = FLoat, Value = " + StrF(V_ARG(i)\f)
        Case #PB_Integer
          Debug "Parameter " + Str(i + 1) + " = Integer, Value = " + Str(V_ARG(i)\i)
        Case #PB_Long
          Debug "Parameter " + Str(i + 1) + " = Long, Value = " + Str(V_ARG(i)\l)
        Case #PB_Quad
          Debug "Parameter" + Str(i + 1) + " = Quad, Value = " + Str(V_ARG(i)\q)
        Case #PB_String
          Debug "Parameter " + Str(i + 1) + " = String, Value = " + PeekS(V_ARG(i)\s)
        Case #PB_Unicode
          Debug "Parameter " + Str(i + 1) + " = UWord, Value = " + Str(V_ARG(i)\u)
        Case #PB_Word
          Debug "Parameter " + Str(i + 1) + " = Word, Value = " + Str(V_ARG(i)\w)
      EndSelect
    EndWith
  Next
EndProcedure

Dim para_array.V_ARG(0)

Define Text.String
Text\s = "Feel the ..Pure.. Power"
V_ARG_Add(para_array(), #PB_String, @Text)

Define pi.d = #PI
V_ARG_Add(para_array(), #PB_Double, @pi)

Define word.w = 65535
V_ARG_Add(para_array(), #PB_Word, @word)
V_ARG_Add(para_array(), #PB_Unicode, @word)

Foo(para_array())

PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Proceduren mit einer variablen Anzahl an Parametern

Beitrag von STARGÅTE »

Hier ist der Beitrag (von mir) den du vermutlich gesucht hast:
DimP - Viele ProcedurParameter (max 16) als Array verwenden

Deine Lösung nimmt einem ja nicht wirklich viel Arbeit ab ^^
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Proceduren mit einer variablen Anzahl an Parametern

Beitrag von ts-soft »

STARGÅTE hat geschrieben:Hier ist der Beitrag (von mir) den du vermutlich gesucht hast:
DimP - Viele ProcedurParameter (max 16) als Array verwenden

Deine Lösung nimmt einem ja nicht wirklich viel Arbeit ab ^^
Meine Lösung ist aber nicht auf einen typ und 16 Parameter begrenzt :wink:

Es soll auch nicht unbedingt eine Arbeitserleichterung sein, sondern eher ein Beispiel,
wie man so etwas umsetzen könnte.

// edit
hier mal ein Beispiel, wie so etwas in FB aussieht:

Code: Alles auswählen

Sub myPrint Cdecl (FormatierString As String, ...)
  Dim As Any Ptr argument = va_first()
  Dim As Integer i
  Dim As ZString Ptr p
  
  For i = 1 To Len(FormatierString)
  
    Select Case Mid(FormatierString, i, 1)
      Case "i"
        Print "Integer: " & va_arg(argument, Integer)
        argument = va_next(argument, Integer)
      Case "l"
        Print "LongInt: " & va_arg(argument, LongInt)
        argument = va_next(argument, LongInt)
      Case "f", "d"
        Print "Double: " & va_arg(argument, Double)
        argument = va_next(argument, Double)
      Case "s"
        Print "String: " & *va_arg(argument, ZString Ptr)
        argument = va_next(argument, ZString Ptr)
    End Select
  Next
End Sub

'###############################################################

Dim s As String = "String2"

myPrint( "ilfdss", 1, 4294967296, 1.2, 3.4, "String1", s )
Sleep
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Proceduren mit einer variablen Anzahl an Parametern

Beitrag von STARGÅTE »

Jo, klar, aber du übergibst ja nicht wirklich mehrer Parameter, sonden trotzdem nur einen.
In meinem Code war es ja damals wirklich so, dass echte Parameter übergeben wurde, und da brauchst man in der regel nicht mehr als 16.
Wenn man 100 Parameter übergeben will, ist das sowieso der falsche Weg ...

Mir ging es damals wirklich nur um Max/Min-Sachen, wo man mal 2 bis 5 Elemente hat.

Bei dir ist natürlich der Vorteil, dass du viele verschiede Typen Parameter übergeben kannst :allright:
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
mk-soft
Beiträge: 3856
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Proceduren mit einer variablen Anzahl an Parametern

Beitrag von mk-soft »

@ts-soft

Ist schon sehr lange her was du suchtest.

http://www.purebasic.fr/german/viewtopi ... 08&start=0

P.S. Bügelt aber immer 12 Parameter auf den Stack. Vielleicht das macro Args nach bedarf einschränken...

P.S. Bei Variablentype die vorher nicht definiert sind nehme ich immer Variant...
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Antworten