BlitzBasic: Type
Merke Type-Listen sind flexibler, einfacher und sicherer zu benutzen als Dim-Felder, weil der Programmieraufwand und die Fehlermöglichkeiten bei Verwendung von Dim-Feldern erheblich ansteigen. Deshalb sollte Type bevorzugt verwendet werden. |
Syntax
[Bearbeiten]Type typename
Parameter
[Bearbeiten]typename : ein eindeutiger Name zur Identifizierung der Type-Liste
Rückgabe
[Bearbeiten]keine
Hinweis
[Bearbeiten]Types sind bei Blitz3D und BlitzPlus nur als Listen gleich großer Einträge (Datensätze) implementiert, um Daten flexibler zu verwalten, als das mit Dim-Feldern möglich wäre. Erst bei BlitzMax sind Types Objekte. Diese Seite beschreibt Type-Listen, wie sie in Blitz3D und BlitzPlus vorkommen. BlitzMax-Types werden unter Type-Object beschrieben.
Beschreibung
[Bearbeiten]- Mit »Type« wird die Definition einer Type-Liste mit einem eindeutigen Namen eingeleitet.
- Type-Listen können nur im Hauptprogramm definiert werden und sind immer Global.
- Auf Einträge kann nicht direkt zugegriffen werden, sondern über Typezeiger.
- Typezeiger sind Variablen, die bei ihrer ersten Verwendung durch anhängen von .typename unlösbar an eine Type-Liste gebunden (definiert) werden.
- Typezeiger können Global oder Local definiert werden.
- Typezeiger können auch Parameter oder Rückgabewerte von Funktionen sein.
- Die Block-Anweisung »Type« ist anders als andere Block-Anweisungen, denn zwischen »Type« und »End Type« dürfen nur Field-Anweisungen oder Kommentare stehen.
- Die Daten im Type sollten möglichst codiert werden, um sehr viele Einträge zu ermöglichen.
Gruppen
[Bearbeiten]Type-Listen
In dieser Gruppe sind Anweisungen und Funktionen, die beim Umgang mit Type-Listen, oder Einträgen von Type-Listen verwendet werden.
Typ | Name | KurzInfo | Blitzversionen |
---|---|---|---|
Block-Anweisung | Type | Startet eine Type-Definition | |
Block-Anweisung | End Type | Beendet eine Type-Definition | |
Anweisung | Field | Definiert Felder für Einträge einer Type-Liste | |
Anweisung | Delete | löscht einen Eintrag in einer Type-Liste | |
Anweisung | Insert | verschiebt einen Eintrag in einer Type-Liste | |
Operator | Null | kennzechnet, dass ein Zeiger auf einen ungültigen Type-Eintrag verweist | |
Funktion | Each | zeigt nacheinander auf alle Einträge einer Type-Liste | |
Funktion | New | erstellt einen neuen Eintrag in einer Type-Liste | |
Funktion | First | holt einen Zeiger auf den ersten Eintrag einer Type-Liste | |
Funktion | Last | holt einen Zeiger auf den letzten Eintrag einer Type-Liste | |
Funktion | After | holt einen Zeiger auf einen nachfolgenden Type-Eintrag | |
Funktion | Before | holt einen Zeiger auf einen vorhergehenden Type-Eintrag | |
Funktion | Handle | ermittelt eine Integer-ID eines Type-Eintrags | |
Funktion | Object | ermittelt einen Type-Eintrag anhand einer Integer-ID |
BlitzBasic: Vorlage:GruppeBlock
Beispiele
[Bearbeiten]Kontakte mit Types verwalten
[Bearbeiten]Jedes Feld in in jedem Eintrag belegt 4 Bytes Speicher. Bei Strings werden diese Bytes als Zeiger auf den sich außerhalb der Type-Liste befindenden String verwendet. Kann jedoch ein String mehrmals vorkommen, spart man erheblich Platz, wenn man Strings in eine andere Type-Liste auslagert, und anstelle eines String einen Typezeiger in einem Feld speichert. Die Type-Liste 'Kontakt' verwendet anstelle jedes String Typezeiger auf die Type-Liste 'Name'. Wenn ein Vorname, Nachname, Strasse oder Stadt mehrmals bei Kontakten vorkommt, spart das Speicherplatz. Außerdem kann nach Feldinhalten schneller gesucht werden, weil ein Vergleich der Type-Zeiger schneller ist, als ein Stringvergleich.
Type Kontakt ;Anfang der Type-Definition 'Kontakt' Field Vorname.Name, Nachname.Name Field Strasse.Name, Nummer% Field PLZ%, Stadt.Name End Type ;Ende der Type-Definition 'Kontakt'
Will man in einer Type-Liste nach einem String suchen, kann das je nach Anzahl der Einträge auch lange dauern, weil bei jedem Type-Eintrag jedes Zeichen des String verglichen werden muss. Besser ist es, aus den Zeichen des String mit einer Checksumme einen Integer-Wert zu ermitteln, da der Integer-Vergleich viel schneller ist.
Type Name ;Anfang der Type-Definition 'Name' Field DatName$ Field ChkName% End Type ;Ende der Type-Definition 'Name'
Durch .Name hinter dem Funktionsnamen wird bestimmt, dass die Funktion einen Typezeiger auf einen Eintrag der Type-Liste 'Name' zurück gibt.
Function NameFinden.Name(Wert$) Local N.Name,Chk Chk=Checksumme(Wert) For N = Each Name If Chk=N\ChkName Then ;nur bei gleicher Checksumme wird der String verglichen If Wert=N\DatName Then Exit ;bei passend Schleife verlassen Endif Next Return N ;wurde kein passender Eintrag gefunden ist N=Null End Function
Die Function NameNeu prüft erst, ob der String schon existiert, erst wenn nicht, wird ein neuer Eintrag angelegt
Function NameNeu.Name(Wert$) Local N.Name N=NameFinden(Wert) ;prüfen ob der gewünschte Eintrag schon existiert If N=Null Then ;wenn nicht ... N=New Name ;neu anlegen und Felder ausfüllen N\DatName=Wert N\ChkName=Checksumme(Wert) EndIf Return N ;existierenden oder neuen Eintrag zurück geben End Function
Die Checksumme muss irgendwie aus einem String einen Integerwert berechnen. Dafür gibt es viele verschiedene Möglichkeiten. Die hier verwendete ist sehr einfach, da sie nur jedes Ascii-Zeichen mit seiner Position im String multipliziert und die Werte addiert. Auf Überlauf der Checksumme wird nicht getestet, da der erst bei Srings mit mehr als 1 Million Zeichen möglich ist.
Function Checksumme%(Wert$) Local Count%,Chk% For Count=1 To Len(Wert) Chk=Chk + Count*Asc(Mid(Wert,Count,1)) Next Return Chk End Function