Seite 1 von 1

LinkedList als Procedureaufruf

Verfasst: 01.05.2012 17:53
von Toshy
Mit dem Schlüsselwort "List" kann man "eine Liste" an eine Procedure "übergeben". Das kann man in der Hilfe erlesen, nur in dem kurzen Beispiel wird der Liste in der Procedure gleich ein Typ zugewiesen

Code: Alles auswählen

 Procedure DebugList(c.l, List ParameterList.l())
    AddElement(ParameterList())
    ParameterList() = 3
Ich möchte in der Procedure aber in erster Linie nur ein LEERES Element hinzufügen. Keine Daten in die Struktur oder Variable schreiben. Hintergrund ist ja nicht so wichtig, hat aber was mit Fehlerabfangen und Statistiken zu tun.
Quasi ein erweitertes "AddElement()".

Jetzt zu meinem Anliegen / Problem. Wenn ich bei der Parameterübergabe einen Typ angebe, dann muß ich auch selben Variablen- / Strukturtyp beim Aufruf nutzen. Der Sinn an sich war allerdings, die Procedure mit unterschiedlichen Liststrukturen nutzen zu können.
Kann ich das eventuell doch machen? Eventuell einfach den Variablentyp weg lassen oder anders? In der Procedure soll der Liste nur ein Element hinzugefügt werden. Datenzugriff soll nicht geschehen. Ist das Möglich?

Ursprünglich wollte ich ein Macro nehmen, allerdings läßt sich das bei mir nicht so schön nutzen, da man keine Rückgabewert angeben kann und Daher den Aufrufenden Code anders gestallten muß (ein ganz wenig). Das wollte ich aber gerade nicht.

geht also so etwas wie:

Code: Alles auswählen

NewList Test.strukturirgendetwas()
Procedure DebugList(c.l, List ParameterList())
    *Element = AddElement(ParameterList())
     ProcedureReturn *Element
EndProcedure
*Element = DebugList(10, Test())
ChangeCurrentElement(Test(), *Element)
test()\wasauchimmer = 33
Gruß
Toshy

Re: LinkedList als Procedureaufruf

Verfasst: 01.05.2012 19:38
von NicTheQuick
Als Makro vielleicht?

Code: Alles auswählen

NewList Test.Integer()
Macro DebugList(c, ParameterList)
	AddElement(ParameterList)
EndMacro
*Element = DebugList(10, Test())
ChangeCurrentElement(Test(), *Element)
test()\i = 33

Re: LinkedList als Procedureaufruf

Verfasst: 01.05.2012 20:04
von Toshy
*Grummel*
Meine Schuld. Jetzt wollte ich es so stark verkürzen, damit es verständlich wird und habe mir damit selbst ein Ei gelegt.
Mein Beispiel war jetzt nicht meinem Text entsprechend, also fehlerhaft.

Wie ich schrieb, kann / will ich hier kein Macro verwenden (bzw. wüßte nicht wie. Diese Art von Macro wie du sie schreibst nutze ich bei anderen Dingen schon. Wenn ich meinen Code jetzt aber erweitere,

Code: Alles auswählen

NewList Test.strukturirgendetwas()
Procedure DebugList(c.l, List ParameterList())#
repeat
    *Element = AddElement(ParameterList())
until *element <> 0
procedure_statistik(*element, weitereparameter)
debug "diesunddas"
printN("hierundda")
     ProcedureReturn *Element
EndProcedure
*Element = DebugList(10, Test())
ChangeCurrentElement(Test(), *Element)
test()\wasauchimmer = 33
also nicht nur eine Zeile mit dem Addelement vor kommt, dann haut es n icht mehr hin.

Ich bin jetzt zwar überlegt, ob ich in der letzten Makrozeile ein

Code: Alles auswählen

 = *element
schreibe, also dann quasi als Ergebnis

Code: Alles auswählen

*element = *element
am Ende stehen würde, aber soweit ich mich erinnere, hatte das nie richtig geklappt oder ich nicht hinbekommen, vor allem weiß ich icht ob diese Art erlaubt ist. Auf jeden Fall bin ich jetzt dank dir auf die Idee gekommen, das später mal zu testen.
Unabhängig davon wollte ich halt den "abgeschotteten Variablenraum" einer Procedure nutzen.

Testen werde ich aber weiterhin als Macro und Procedure. Wichtig ist mir vor allem, das es irgend wie hin haut. Egal ob ich dann mit einer Einschränkung leben mußt bzw. einfach umdenken muß.

Wenn Purebasic beim hinzufügen eines Listenelements automatisch die Struktur zur Liste nimmt (intern gespeichert), dann sollte es mit meinen Beispielen keine Probleme geben. Aber das weiß ich halt nicht. Und hier nur "zu testen" bringt wohl nicht so viel. Denn klappen könnte es bis halt einer dieser tollen Speicherfehler auftritt :roll:

Re: LinkedList als Procedureaufruf

Verfasst: 01.05.2012 20:15
von ts-soft
Toshy hat geschrieben: Unabhängig davon wollte ich halt den "abgeschotteten Variablenraum" einer Procedure nutzen.
Was macht ein Macro denn? Es wird dort, wo es aufgerufen wird, eingefügt, also bei Aufruf innerhalb
einer Procedure befindet es sich im "abgeschotteten Variablenraum", bzw. bei Aufruf ausserhalb eben im MainScope.

Re: LinkedList als Procedureaufruf

Verfasst: 02.05.2012 10:57
von CSHW89
Zu deiner Frage mit den Polymorphen Listenparametern: nein kann leider nicht klappen, nicht mal dreckig mit Prototypes und veränderden Parametertypen, wie beispielsweise hier:

Code: Alles auswählen

Structure struc
  u.i
  Array b.Point(15)
EndStructure

Prototype durchlauf_d(List a.d())
Prototype durchlauf_struc(List a.struc())


Procedure durchlauf(List a.i()) ; Funktioniert mit allen Arten von Listen, wenn man Prototypes benutzt
  ForEach a()
    Debug @a()
  Next
EndProcedure


NewList lstd.d()
NewList lststruc.struc()
Define i
Define proc_d.durchlauf_d = @durchlauf()
Define proc_struc.durchlauf_struc = @durchlauf()

For i = 0 To 4
  AddElement(lstd())
  lstd() = i
Next
For i = 0 To 7
  AddElement(lststruc())
  lststruc()\u = i
Next

proc_d(lstd())
Debug "-------"
proc_struc(lststruc())
Man braucht zwar meherere Prototypes für jede Struktur, aber nur eine Procedure "durchlauf" für alle Arten von Listen. Dies geht aber wirklich nur beim Setzen des Listenpointers (ForEach, NextElement, SelectElement, ect...), und beim Auslesen der Adresse eines Elements, so wie hier. Das Hinzufügen (also AddElement) oder Löschen in so einer Procedure wird unweigerlich zu Fehlern führen, da intern bei einem AddElement-Aufruf auch InitializeStructure aufgerufen wird. Dazu muss man die Struktur der Liste kennen. In diesem Fall z.B. müsste bei der lststruc() das Array mit den 16-Point's erstellt werden, wenn man AddElement aufruft.

lg Kevin

Re: LinkedList als Procedureaufruf

Verfasst: 02.05.2012 16:30
von NicTheQuick
Und sowas würdest du nicht wollen?

Code: Alles auswählen

NewList Test.Integer()

Macro DebugList(c, ParameterList, out)
	CompilerIf Defined(*_, #PB_Variable) = #False
		Define *_
	CompilerEndIf
	Repeat
		*_ = AddElement(ParameterList)
	Until *_
	procedure_statistik(*_, weitereparameter)
	Debug "diesunddas"
	PrintN("hierundda")
	out = *_
EndMacro
DebugList(10, Test(), *Element)
ChangeCurrentElement(Test(), *Element)
test()\i = 33

Re: LinkedList als Procedureaufruf

Verfasst: 02.05.2012 16:53
von Toshy
Erst einmal Danke an euch.

Das habe ich leider "befürchtet" mit "Addelement".
Ich hatte aber die Hoffnung, das die Struktur einer Liste irgendwo im Header der Liste gespeichert ist. Dann hätte bei Addelement der Pointer zur Liste genügen können.
Und die Strukturangabe in z.B. einer Procedure oder Hauptprozesse wäre dann nur für den Zugriff notwendig.
Schade das dem wohl nicht so ist.

Und an Nick, danke für das Beispiel. Das wollte ich aber umgehen. So habe ich es auch schon in alten Codes gemacht. Ich hatte nur gehofft, das es auch anders geht.

Wie ich schon schrieb, ist ja keine Katastrophe, denn so geht es schon. Na ja, dann werde ich es wohl (wieder) über Makros lösen.
Aus interesse aber werde ich versuchen noch ein wenig mit der Procedure beschafftigen bzw. hachfragen. Denn wie das mit dem genannten "InitializeStructure" funktioniert wäre schon ein wenig interessant. Aber noch nicht heute :-)

Herzlichen Dank an euch Alle.

Lieber Gruß
Toshy

Re: LinkedList als Procedureaufruf

Verfasst: 02.05.2012 17:10
von NicTheQuick
Da fällt mir sonst nur noch das hier ein:

Code: Alles auswählen

NewList *Test()

Procedure DebugList(c.l, List *ParameterList())
	Repeat
		*element = AddElement(*ParameterList())
	Until *element
	;procedure_statistik(*element, weitereparameter)
	Debug "diesunddas"
	;PrintN("hierundda")
	ProcedureReturn *element
EndProcedure
*element = DebugList(10, *Test())
ChangeCurrentElement(*Test(), *element)
; Adresse des Elements
Debug *element
; Bisheriger Pointer zum Inhalt (0)
Debug *Test()
; Speicher reservieren für gewünschte Struktur
*Test() = AllocateMemory(SizeOf(Integer))
; Struktur initialieren (wichtig für Map-, List-, Array- und String-Member)
InitializeStructure(*Test(), Integer)
; neuer Pointer strukturierter Variable zuweisen
*i_element.Integer = *Test()
; Element ändern
*i_element\i = 33
; Nochmal ausgeben
Debug *i_element
Debug *i_element\i