Prozedur mit beliebig vielen Argumenten? Möglich?
Prozedur mit beliebig vielen Argumenten? Möglich?
Ist es möglich eine Prozedur zu erstellen der man Argumente übergeben kann, deren Anzahl beliebig ist?
Also ProcedureFoo(para1, para2, para3 ...) und diese müssten dann bei Vorhandensein in der Prozedur verarbeitet werden.
Aber bei der Prozedurdefinition weiß ich im voraus nicht wieviele Argumente dann übergeben werden.
Erst beim benutzen dieser.
Hoffe ich habs nicht zu schwer erklärt.
Wie in einem Ordner bei dem ich beim Öffnen des Ordners festlege wieviele Blätter ich einheften und abarbeiten will.
Ich weiß ich könnte eine Liste im Vorfeld erstellen und diese dann in die Prozedur übernehmen und abarbeiten lassen, jedoch würde ich dies gern anders machen.
Also ProcedureFoo(para1, para2, para3 ...) und diese müssten dann bei Vorhandensein in der Prozedur verarbeitet werden.
Aber bei der Prozedurdefinition weiß ich im voraus nicht wieviele Argumente dann übergeben werden.
Erst beim benutzen dieser.
Hoffe ich habs nicht zu schwer erklärt.
Wie in einem Ordner bei dem ich beim Öffnen des Ordners festlege wieviele Blätter ich einheften und abarbeiten will.
Ich weiß ich könnte eine Liste im Vorfeld erstellen und diese dann in die Prozedur übernehmen und abarbeiten lassen, jedoch würde ich dies gern anders machen.
Laptop: Win10@64bit - i3 2x2Ghz - 8GB Ram - 1TB HDD
Desktop: Win10@64bit - AMD Ryzen 5 2400G - MSI B450 Tomahawk - 8GB Ram - 240GB SSD
Desktop: Win10@64bit - AMD Ryzen 5 2400G - MSI B450 Tomahawk - 8GB Ram - 240GB SSD
Re: Prozedur mit beliebig vielen Argumenten? Möglich?
In prinzip nicht da Purebasic nicht wie "C" arbeiten.
Hatte aber eine alternative vor ewigkeiten mal geschrieben. Sind Max 11 Parameter möglich.
http://www.purebasic.fr/german/viewtopi ... =8&t=13008
An sonsten mit den Parametertype Variant arbeiten...
Hatte aber eine alternative vor ewigkeiten mal geschrieben. Sind Max 11 Parameter möglich.
http://www.purebasic.fr/german/viewtopi ... =8&t=13008
An sonsten mit den Parametertype Variant arbeiten...
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Re: Prozedur mit beliebig vielen Argumenten? Möglich?
Wenn alle Parameter den gleichen Typ haben (Integer z.B.), dann könnte man doch einfach
oder nicht ?
(Wobei man am Ende der Prozedur das übergebene Array auch vernichten könnte, damit keine "Reste" beim
nächsten Aufruf überbleiben)
Code: Alles auswählen
Procedure Foo(Array Params(1))
Debug "Parameter Anzahl : " + ArraySize(Params())
EndProcedure(Wobei man am Ende der Prozedur das übergebene Array auch vernichten könnte, damit keine "Reste" beim
nächsten Aufruf überbleiben)
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom
Re: Prozedur mit beliebig vielen Argumenten? Möglich?
Einfach einen Pointer auf eine Struktur übergeben, ist meiner Meinung nach wesentlich sauberer.
Re: Prozedur mit beliebig vielen Argumenten? Möglich?
@Alexi: Bräuchtest du dazu nicht eine Struktur mit unendlich vielen Feldern?
Hab hier mal schnell zwei verschiedene Möglichkeiten (auf die schnelle, geht alles eleganter, verbraucht garantiert Speicher ohne Ende, falls man es überhaupt mehrmals ausführen kann ohne dass sich die Listen und Array stören, aber soll ja nur ein Denkanstoß sein)
Leider kann man keine Doppelpunkte in den Macroargumenten benutzen, deswegen der umständliche Weg mit myProc und EndMyProc...
Geht auch mit beliebigen Parametern. Man braucht nur die entsprechende Struktur.Bisonte hat geschrieben:Wenn alle Parameter den gleichen Typ haben (Integer z.B.), dann könnte man doch einfachoder nicht ?Code: Alles auswählen
Procedure Foo(Array Params(1)) Debug "Parameter Anzahl : " + ArraySize(Params()) EndProcedure
(Wobei man am Ende der Prozedur das übergebene Array auch vernichten könnte, damit keine "Reste" beim
nächsten Aufruf überbleiben)
Hab hier mal schnell zwei verschiedene Möglichkeiten (auf die schnelle, geht alles eleganter, verbraucht garantiert Speicher ohne Ende, falls man es überhaupt mehrmals ausführen kann ohne dass sich die Listen und Array stören, aber soll ja nur ein Denkanstoß sein)
Code: Alles auswählen
Enumeration 1
#paramType_String
#paramType_Integer
#paramType_Float
EndEnumeration
Structure paramTypes
type.i
string.s
integer.i
float.f
EndStructure
Procedure myProc(Array parameter.paramTypes(1))
Protected numberOfParams = ArraySize(parameter())
Protected k, sumInteger
Protected sumFloat.f
Protected strings.s
For k = 0 To numberOfParams
Select parameter(k)\type
Case #paramType_String
strings = strings + parameter(k)\string + ", "
Case #paramType_Integer
sumInteger + parameter(k)\integer
Case #paramType_Float
sumFloat + parameter(k)\float
EndSelect
Next
Debug strings
Debug sumInteger
Debug sumFloat
EndProcedure
Dim myArray.paramTypes(5)
myArray(0)\type = #paramType_String
myArray(0)\string = "Param1"
myArray(1)\type = #paramType_Float
myArray(1)\float = 0.1
myArray(2)\type = #paramType_Integer
myArray(2)\integer = 7
myArray(3)\type = #paramType_String
myArray(3)\string = "Param2"
myArray(4)\type = #paramType_Float
myArray(4)\float = 0.3
myArray(5)\type = #paramType_Integer
myArray(5)\integer = 9
myProc(myArray())
Leider kann man keine Doppelpunkte in den Macroargumenten benutzen, deswegen der umständliche Weg mit myProc und EndMyProc...
Code: Alles auswählen
Macro bla(foo)
foo
EndMacro
bla(a=1 : b=2) ;Syntax Error :(
Debug a+bCode: Alles auswählen
Enumeration 1
#paramType_String
#paramType_Integer
#paramType_Float
EndEnumeration
Structure paramTypes
type.i
string.s
integer.i
float.f
EndStructure
Procedure myProc(List parameter.paramTypes())
Protected sumInteger.i
Protected strings.s
Protected sumFloat.f
ResetList(parameter())
While NextElement(parameter())
Select parameter()\type
Case #paramType_String
strings = strings + parameter()\string + ", "
Case #paramType_Integer
sumInteger + parameter()\integer
Case #paramType_Float
sumFloat + parameter()\float
EndSelect
Wend
Debug strings
Debug sumInteger
Debug sumFloat
EndProcedure
Macro myString(__string)
AddElement(myList())
myList()\type = #paramType_String
myList()\string = __string
EndMacro
Macro myInteger(__integer)
AddElement(myList())
myList()\type = #paramType_Integer
myList()\integer = __integer
EndMacro
Macro myFloat(__float)
AddElement(myList())
myList()\type = #paramType_Float
myList()\float = __float
EndMacro
Macro _myProc()
NewList myList.paramTypes()
EndMacro
Macro _EndMyProc()
myProc(myList())
EndMacro
_myProc()
myString("Hallo"): myString("Welt"): myInteger(1): myInteger(9): myFloat(0.5)
_EndMyProc()
Signatur und so
- 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: Prozedur mit beliebig vielen Argumenten? Möglich?
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.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

- NicTheQuick
- Ein Admin
- Beiträge: 8837
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Re: Prozedur mit beliebig vielen Argumenten? Möglich?
@ts-soft:
Jetzt wollte ich deinen Code noch etwas vereinfachen, und was passiert? Ich hab mal wieder einen Bug gefunden:
Nichtsdestotrotz hier der einfachere Code:
Jetzt wollte ich deinen Code noch etwas vereinfachen, und was passiert? Ich hab mal wieder einen Bug gefunden:
Code: Alles auswählen
Debug "#PB_Word = " + #PB_Word
Debug "#PB_Structure = " + #PB_Structure
Define.w word
Debug "TypeOf(word) = " + TypeOf(word)Code: Alles auswählen
;==================================================================
; ### Example to use variable parameters for Procedures ###
; Author: Thomas <ts-soft> Schulz & <NicTheQuick>
; Date: Mrz 16, 2012
; Version: 1.1
; Target OS: All
; Target Compiler: PureBasic 5.10 and later
;==================================================================
EnableExplicit
Structure V_ARG
Type.l
StructureUnion
a.a
b.b
c.c
d.d
f.f
i.i
l.l
q.q
u.u
w.w
EndStructureUnion
s.s
EndStructure
Procedure V_ARG_Add_(Array V_ARG.V_ARG(1), Type.l, size.i, *value)
Protected index = ArraySize(V_ARG())
ReDim V_ARG(index + 1)
With V_ARG(index)
\Type = Type
If (Type = #PB_String)
\s = PeekS(*value)
Else
CopyMemory(*value, @V_ARG(index) + OffsetOf(V_ARG\a), size)
EndIf
EndWith
EndProcedure
Macro V_ARG_Add(v_arg, value)
V_ARG_Add_(v_arg, TypeOf(value), SizeOf(value), @value)
EndMacro
; example
Procedure Foo(Array V_ARG.V_ARG(1))
Protected i.i
Protected count.i = ArraySize(V_ARG())
Debug "Count of parameters: " + Str(count)
Debug ""
For i = 0 To count - 1
With V_ARG(i)
Debug \Type
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 = " + 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.s
Text = "Feel the ..Pure.. Power"
V_ARG_Add(para_array(), Text)
Define pi.d = #PI
V_ARG_Add(para_array(), pi)
Define word.w = 65535
V_ARG_Add(para_array(), word)
V_ARG_Add(para_array(), word)
Foo(para_array())Re: Prozedur mit beliebig vielen Argumenten? Möglich?
Vielen lieben dank, aber für mein Vorhaben ist das doch etwas zu überdimensioniert.
Das werd ich dann ein bisschen einfacher lösen.
Aber es ist immer wieder schön etwas dazuzulernen und überhaupt vielen dank an alle die ebenso gerne einfach mal helfen.
Das werd ich dann ein bisschen einfacher lösen.
Aber es ist immer wieder schön etwas dazuzulernen und überhaupt vielen dank an alle die ebenso gerne einfach mal helfen.
Laptop: Win10@64bit - i3 2x2Ghz - 8GB Ram - 1TB HDD
Desktop: Win10@64bit - AMD Ryzen 5 2400G - MSI B450 Tomahawk - 8GB Ram - 240GB SSD
Desktop: Win10@64bit - AMD Ryzen 5 2400G - MSI B450 Tomahawk - 8GB Ram - 240GB SSD
- NicTheQuick
- Ein Admin
- Beiträge: 8837
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Re: Prozedur mit beliebig vielen Argumenten? Möglich?
Durch einen Hinweis im englischen Forum, hab ich jetzt auch verstanden, warum da noch ein Fehler war. Wenn man eine Variable hat, die den selben Namen hat wie eine vorhandene Structure, dann gibt TypeOf() immer #PB_Structure zurück anstatt den Typ der gleichnamigen Variablen. Ich habe das jetzt durch einen CompilerError behoben, der ausgelöst wird, wenn man 'V_ARG_Add()' eine strukturierte Variable oder eben aus Versehen einen Strukturnamen übergibt.
Code: Alles auswählen
;==================================================================
; ### Example to use variable parameters for Procedures ###
; Author: Thomas <ts-soft> Schulz & <NicTheQuick>
; Date: Mrz 16, 2012
; Version: 1.1
; Target OS: All
; Target Compiler: PureBasic 5.10 and later
;==================================================================
EnableExplicit
Structure V_ARG
Type.l
StructureUnion
a.a
b.b
c.c
d.d
f.f
i.i
l.l
q.q
u.u
w.w
EndStructureUnion
s.s
EndStructure
Procedure V_ARG_Add_(Array V_ARG.V_ARG(1), Type.l, size.i, *value)
Protected index = ArraySize(V_ARG())
ReDim V_ARG(index + 1)
With V_ARG(index)
\Type = Type
If (Type = #PB_String)
\s = PeekS(*value)
Else
CopyMemory(*value, @V_ARG(index) + OffsetOf(V_ARG\a), size)
EndIf
EndWith
EndProcedure
Macro V_ARG_Add(v_arg, value)
CompilerIf TypeOf(value) = #PB_Structure
CompilerError "The variable has no native type. This is not supported."
CompilerEndIf
V_ARG_Add_(v_arg, TypeOf(value), SizeOf(value), @value)
EndMacro
; example
Procedure Foo(Array V_ARG.V_ARG(1))
Protected i.i
Protected count.i = ArraySize(V_ARG())
Debug "Count of parameters: " + Str(count)
Debug ""
For i = 0 To count - 1
With V_ARG(i)
Debug \Type
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 = " + 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.s
Text = "Feel the ..Pure.. Power"
V_ARG_Add(para_array(), Text)
Define pi.d = #PI
V_ARG_Add(para_array(), pi)
Define word1.w = 65535
V_ARG_Add(para_array(), word1)
V_ARG_Add(para_array(), word1)
Foo(para_array())