BlitzBasic: Type

Aus Wikibooks

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