Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Linked List in FreeBASIC

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Fausti



Anmeldungsdatum: 31.07.2005
Beiträge: 7

BeitragVerfasst am: 01.08.2005, 18:24    Titel: Linked List in FreeBASIC Antworten mit Zitat

Dank dem Typcasting der neuen Freebasic Version habe ich meine Idee für eine allgemein verwendbare linked list wieder aufgegriffen. Natürlich habe ich mir in der Vergangenheit schon tonnenweise Tutorials über dieses Thema gesaugt und durchgearbeitet, aber die waren eher für andere Programmiersprachen (gab auch das eine oder andere gute englische tut für fb zwinkern, und obwohl das Grundmuster fast immer gleich ist, setzt jeder Programmierer sie eigentlich doch ein wenig anders um, oder erweitert sie sogar. Es mag auch genügend fertige Umsetzungen für z.B. C geben, die man auch in FB benutzen könnte, aber man lernt doch am besten, wenn man etwas selbst programmiert.

Ich fände es also toll, wenn wir hier unsere Ideen/Umsetzungen/Ratschläge posten würden und darüber dann diskutieren könnten. Vielleicht wird daraus ja dann eine Art Tutorial für FB, oder gar eine Erweiterung für FB, die dann Einzug in spätere Versionen hält?

Mal ein paar Stichpunkte:

- Iteratoren ja/nein/wie/warum?
- Implementation einer Liste für einen bestimmten Datentyp oder lieber allgemein (Any Ptr)?
- Wichtige/Nützliche Funktionen? Funktionen um das Arbeiten intuitiver zu gestalten?
- Optimierungen? Error Checking?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
helium



Anmeldungsdatum: 10.09.2004
Beiträge: 397
Wohnort: Leverkusen

BeitragVerfasst am: 02.08.2005, 11:38    Titel: Antworten mit Zitat

Zitat:
- Iteratoren ja/nein/wie/warum?

Hängt davon ab, wie du die Liste gestaltest. Bei einer einfachen version kommt man ohne Iteratoren aus, sondern verwendt direkt Zeiger auf die entsprechenden Nodes.


Zitat:
- Implementation einer Liste für einen bestimmten Datentyp oder lieber allgemein (Any Ptr)?

Dinge, wie Collections und Algorithmen sollten immer so allgemein wie möglich gehalten werden.

Zitat:
- Wichtige/Nützliche Funktionen? Funktionen um das Arbeiten intuitiver zu gestalten?

- length (länge bestimmen)
- exists (existiert ein bestimmtes Element)
- nth (ntes Element)
- reverse (umdrehen)

Andere wichtige Standardfunktionen wären
- filter (filtern anhand eines bestimmten Kriteriums (Funktion übergeben))
- map (Generieren einer neuen Liste aus der alten, wobei die übergebene Funktion auf jedes Element angewendet wird)
- foldLeft (Falten von links)
- foldRight (Falten von rechts)
sind in FB aber vermutlich nicht sonderlich intuitiv einsetzbar.


Zitat:
- Optimierungen? Error Checking?

Abhängig von konkreten Anforderungen.
Hast du nur einfach Nodes, mit denen der Programmierer arbeitet, oder sind Sie eher Implementationsdetail und du kapselst das ganze nochmal weg? Ist es dann vielleicht sinnvoll die Länge extra mitzuspeichern? ...
_________________
Bevor Sie aufhören sich körperlich zu betätigen sollten Sie ihren Doktor befragen. Körperliche Inaktivität ist abnormal und gefährlich für Ihre Gesundheit.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fausti



Anmeldungsdatum: 31.07.2005
Beiträge: 7

BeitragVerfasst am: 02.08.2005, 14:37    Titel: Antworten mit Zitat

Zum herumbasteln habe ich einfach mal folgenden Aufbau gewählt:

Code:

Type LListItem
  _data As Any Ptr ' Pointer auf die gespeicherten Daten
  _prev As LListItem Ptr ' vorheriges LListItem
  _next As LListItem Ptr ' nächstes LListItem
' _list As LList Ptr ' Pointer auf LList in dem sich das LListItem befindet
End Type

Type LList
  _first As LListItem Ptr ' Pointer auf den ersten Listeneintrag
  _last  As LListItem Ptr ' Pointer auf den letzten Listeneintrag
End Type

Type LListIterator
  _list As LList Ptr ' Pointer auf die zugehörige LList
  _item As LListItem Ptr ' Pointer auf das aktuelle LListItem
End Type

Function LList_Create() As LList Ptr
  Dim temp As LList Ptr
  temp = callocate(Len(LList))
  temp->_first = 0
  temp->_last  = 0
  Return temp
End Function

Function LListItem_Create() As LListItem Ptr
  Dim temp As LListItem Ptr
  temp = callocate(Len(LListItem))
  temp->_data = 0
  temp->_next = 0
  temp->_prev = 0
  Return temp
End Function

Function LList_AddItem(byval l As LList Ptr, byval d As Any Ptr) As LListItem Ptr
  Dim temp As LListItem Ptr
  temp = LListItem_Create()
  If temp = 0 Then Return 0
 
  If l->_first = 0 Then
    l->_first = temp
    l->_last  = temp
  Else
    l->_last->_next = temp
    temp->_prev = l->_last
    l->_last = temp
  End If
 
  temp->_next = 0
  temp->_data = d
 
  Return temp
End Function

Function LList_RemoveItem(byval l As LList Ptr, byval i As LListItem Ptr) As Any Ptr
  Dim pr As LListItem Ptr
  Dim ne As LListItem Ptr
  Dim da As Any Ptr
 
  pr = i->_prev
  ne = i->_next
 
  If pr <> 0 Then pr->_next = ne Else l->_first = ne
  If ne <> 0 Then ne->_prev = pr Else l->_last = pr
 
  da = i->_data
  deallocate i
 
  Return da
End Function


Ist im Moment wirklich nur rudimentär zwinkern Zum herumspielen mit dem neuen Typcasting hats gereicht (*BEGEISTERT*).

Den Iterator-UDT habe ich nur als kleine Gedächtnisstütze eingebaut. Ich kenne ihn aus der STL von C++ und diversen Tuts, aber bin mir noch nicht wirklich darüber im Klaren, ob ich ihn wirklich brauche, wenn ich dem jetzigen Aufbau treu bleibe, denn LListItem könnte seine Funktion momentan auch übernehmen.

Noch eine Idee wäre es, wenn ich in LListItem noch irgendwie den Typ der gespeicherten Daten speichere, denn dank Any Ptr kann ich ja in ein und derselben Liste Daten mit verschiedenen Typen speichern.

Hatte auch mal vor einiger Zeit probiert, wie man eine Liste (ohne den Typ der gespeicherten Daten zu wissen) in eine Datei speichern könne, um sie später wieder einzulesen so wie es auch in Python geht. Hat bis auf Strings und UDTs mit Stringfeldern und sonstigen Pointern in den UDTs auch funktioniert. Ich konnte leider nicht prüfen, ob die Daten die ich direkt aus dem Speicher gelesen hatte nun Adressen waren, oder Daten. Nach nem Programmneustart waren an den gespeicherten Adressen ja nicht mehr die gewünschten Daten -> BLUESCREEN *lol* Naja, wenn man das noch irgendwie hinbekommen könnte zwinkern

Könntest du mir das mit foldLeft/Right irgendwie erklären?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
helium



Anmeldungsdatum: 10.09.2004
Beiträge: 397
Wohnort: Leverkusen

BeitragVerfasst am: 05.08.2005, 13:52    Titel: Antworten mit Zitat

Ach 'ne doppelt verkettete Liste? Naja, tut ja nicht viel zur Sache.


Zitat:
Den Iterator-UDT habe ich nur als kleine Gedächtnisstütze eingebaut. Ich kenne ihn aus der STL von C++ und diversen Tuts, aber bin mir noch nicht wirklich darüber im Klaren, ob ich ihn wirklich brauche, wenn ich dem jetzigen Aufbau treu bleibe, denn LListItem könnte seine Funktion momentan auch übernehmen.

In der STL gibt es drei Ebenen: Container, Iteratoren, Algorithmen. Algorithmen arbeiten prinzipiell nur mit Iteratoren und sind somit unabhängig von den Containern.
Das wird dir in FB aber nicht gelingen, aa es zur Zeit weder die Template-Fähigkeiten von C++ gibt noch Polymorphie, die als andere Alternative denkbar wäre.
(Natürlich kann man auch in FB mit viel Trickserei zu einem ähnlichen Ergebnis kommen, nur wäre der Aufwand zu groß und das Ergebnis vermutlch nicht bequem einsetzbar.)

Deswegen denke ich, dass du das Iterator-Konzept zunächst außen vor lassen soltest.

Zitat:
Noch eine Idee wäre es, wenn ich in LListItem noch irgendwie den Typ der gespeicherten Daten speichere, denn dank Any Ptr kann ich ja in ein und derselben Liste Daten mit verschiedenen Typen speichern.

Hast du auch 'ne Idee, wie das gehen könnte? AFAIK besitzt FB zur Laufzeit keine Informationen über die Typen.

Zitat:
Hatte auch mal vor einiger Zeit probiert, wie man eine Liste (ohne den Typ der gespeicherten Daten zu wissen) in eine Datei speichern könne, um sie später wieder einzulesen so wie es auch in Python geht.

Python kennt den Typ jedes Objekts.
Ich sehe im Moment keinen Weg, wie du die Daten serialisieren könntest.

Zitat:
Könntest du mir das mit foldLeft/Right irgendwie erklären?


Wenn du Faltung nicht kennst, weiß ich nicht, ob es jetzt besonders sinnvoll ist. Außerdem denke ich sowieso, dass der durchschnitts FB-Programmierer wenig mit Faltung anfangen kann.
_________________
Bevor Sie aufhören sich körperlich zu betätigen sollten Sie ihren Doktor befragen. Körperliche Inaktivität ist abnormal und gefährlich für Ihre Gesundheit.


Zuletzt bearbeitet von helium am 06.08.2005, 13:07, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fausti



Anmeldungsdatum: 31.07.2005
Beiträge: 7

BeitragVerfasst am: 05.08.2005, 15:23    Titel: Antworten mit Zitat

Zitat:
Hast du auch 'ne Idee, wie das gehen könnte? AFAIK besitzt FB zur Laufzeit keine Informationen über die Typen.


Konnte jetzt zwar den Quelltext zu meinem Versuch nicht mehr finden (ist auch schon ne Weile her) aber ich versuche es mal aus dem Gedächtnis so gut es geht.

Code:

Const TYP_NPC = 0
Const TYP_OBJ = 1
Const TYP_TILE = 2

Type tNPC
  TYP As Byte
  X As Byte
  Y As Byte
  FLAGS As Byte
  SCRIPT As Byte
  IMG As Byte
  ANI As Byte
End Type

Type tOBJ
  TYP As Byte
  X As Byte
  Y As Byte
  IMG As Byte
  ANI As Byte
  FLAGS As Byte
End Type

Type tTILE
  TYP As Byte
  X As Byte
  Y As Byte
  IMG As Byte
End Type


Das sind jetzt mal einfach 3 verschiedene UDTs die ich mit zufälligen Daten gefüllt und in zufälliger Anzahl/Reihenfolge in einer Liste, ähnlich der aus meinem letzten Posting, gespeichert habe.

Wichtig ist hier in jedem UDT das Feld TYP und das es gleich als erstes in der Typdeklaration steht. Beim Erstellen einer Variable habe ich im TYP Feld immer gespeichert, um welchen UDT es sich handelte. Dann gab es noch ein 4. UDT:

Code:

Type tTEMPLATE
  TYP As Byte
End Type


Beim Speichern der Liste in eine Datei bin ich einfach die gesamte Liste durchgegangen und habe mittels Len() die Länge des Objektes erfragt und mittels seiner Adresse dann seinen Speicherbereich ausgelesen, und in eine Datei geschrieben.

Der "Clou" kam dann beim Einlesen. Als ersten kommt ja von jedem Objekt das TYP Feld. Anhand dessen konnte ich erfahren was für einen UDT ich anlegen musste und wie lang er ist (wieder mit LEN()). Habe dann die jeweilige Anzahl Daten ausgelesen und in eine neue Variable vom jeweiligen Typ gespeichert, und diese dann in die Liste eingefügt.

Wenn ich mit der Prozedur durch war, konnte ich wie gewohnt auf die Daten aus der Liste zugreifen. Funktioniert aber leider wie schon erwähnt nicht, wenn FB anstelle der Daten nur die Adresse der Daten gespeichert hat, wie es bei Strings der Fall ist.

Naja, so super Weltbewegend ist das ganze wohl nicht, denn eigentlich ist es nur nen kleiner Trick um Daten mit verschiedenen Daten in ein und derselben Liste zu speichern, und mittels des vorgetäuschten Castings auf tTEMPLATE zugriff auf den Typ eines Objektes zu bekommen.

Wenn man aber aus irgendwelchen Gründen eh keine Strings oder Pointer auf andere Variablen in den zu speichernden Daten hat, kann man ohne großen Aufwand ne ganze Menge an verschiedenen UDTs in dieser Liste verwalten/speichern und laden, ohne jedesmal erst noch für jeden Typ eigene speichern/laden programmteile zu schreiben. Und Programmteile wo man doch ne unterscheidung braucht lassen sich ganz einfach mit select case realisieren.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz