LinkedList als Procedureaufruf

Für allgemeine Fragen zur Programmierung mit PureBasic.
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

LinkedList als Procedureaufruf

Beitrag 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
1. Win10
PB6.1
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
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: LinkedList als Procedureaufruf

Beitrag 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
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Re: LinkedList als Procedureaufruf

Beitrag 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:
Zuletzt geändert von Toshy am 01.05.2012 21:00, insgesamt 1-mal geändert.
1. Win10
PB6.1
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: LinkedList als Procedureaufruf

Beitrag 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.
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
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: LinkedList als Procedureaufruf

Beitrag 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
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
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: LinkedList als Procedureaufruf

Beitrag 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
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Re: LinkedList als Procedureaufruf

Beitrag 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
1. Win10
PB6.1
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
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: LinkedList als Procedureaufruf

Beitrag 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
Antworten