Inhaltsverzeichnis
Bascom Speicherstrukturen
Das Bascom keine Datenstrukturen bilden läßt, ist zwar bedauerlich, es gibt aber durchaus Möglichkeiten, sich zu helfen.
Einfache Strukturen
Da Bascom die Datenfelder im SRAM und im ERAM geschlossen in der Reihenfolge anlegt, wie sie dimensioniert werden, legt man die Felder von, sagen wir, eines Datenrecords auch hintereinander an.
DIM Rec_Header AS BYTE DIM Rec_Length AS BYTE DIM Rec_Usrdata AS STRING * 23 DIM Rec_Trailer AS BYTE
Und wenn wir nun diesen Bereich redefinieren, wobei wir die Gesamtlänge leider ausrechnen müssen,
DIM Record(27) AS BYTE AT Header OVERLAY
können wir dieses Speicherbereich sowohl als "Record" als Byte-Array in der Länge 27 verwenden, aber auch die Felder einzeln ansprechen, was beim byte-seriellen Input/Output recht praktisch ist.
Natürlich ist das noch kein Ersatz für vordefinierte Strukturen, die dann auch mehrfach an beliebigen Stellen deklariert bzw. verwendet werden können, wie es z.B. bei C (GCC) üblich ist. Da hilft leider nur Cut & Paste und ein anderer Prefix (statt "Rec_").
Mehrfache Strukturen a la malloc/new
Aber für den Fall, daß wir sagen können, wieviele dieser "Strukturen" im Programm maximal verwendet werden (was meisten doch der Fall ist) können wir aus einfachen Tabellen auch mehrfache Strukturen bilden.
Nicht so elegant wie "malloc(sizeof(Record))", aber immerhin:
wir definieren
CONST Maxindex = nn ' Die Anzahl, die benötigt wird DIM Usage_Index(Maxindex) AS BYTE ' Hilfstablle der benützen Elemente DIM Temp AS BYTE ' Hilfswert ' -------------- die "struktur"-------------------- DIM Rec_Header(Maxindex) AS BYTE DIM Rec_Length(Maxindex) AS BYTE DIM Rec_Usrdata(Maxindex) AS STRING * 23 DIM Rec_Trailer(Maxindex) AS BYTE
und wenn nun an einer Stelle eine neue Instanz der Struktur gebraucht wird:
FOR Temp = 1 to Maxindex IF Usage_Index(Temp) = 0 then ' da ist was frei Usage_Index(Temp) = 1 ' reservieren EXIT FOR END IF NEXT ' und nun haben wir einen Bereich und können ihn exklusiv verwenden Rec_Header(Temp) = nn Rec_Length(Temp) = nn Rec_Usrdata(Temp) = "aaaaaaa" Rec_Trailer(Temp) = nn
Die reservierende Funktion wird sich "Temp" natürlich als "pointer" merken und kann ihr Bereich dann auch mal freigeben
Usage_Index(Temp) = 0 ' unreserve
Für die "C"-Kundigen User:
Rec_Length(pointer) <entspricht> pointer->Rec_Length
Anmerkung
Von einer wirklichen "Heap" Verwaltung kann man wohl nicht sprechen. Aber vielleicht kann sich dieser oder jener User etwas von der Methodik für seine Zwecke adaptieren und verwenden.
Der größte Unterschied zu "malloc" ist natürlich, daß der aktuell nicht genutzte Bereich NICHT ohne Weiteres für andere Zwecke genutzt werden kann, wie es ja beim original "malloc" der Fall ist. Aber letzterer handelt sich auch eine Menge Probleme damit ein.