Startseite
Amiforce 2.1     Amiforce-News Amiforce-News Amiforce-Forum Amiforce-Forum Amiforce-Chat/IRC-Chat Amiforce-Chat/IRC-Chat Gästebuch Gästebuch Kontakt mit dem Webmaster aufnehmen Kontakt mit dem Webmaster aufnehmen

Amiblitz3
Amiblitz2(alt)
Storm Wizard
Abakus-Design
Helpguide
Toolsguide
Tipps&Tricks
Gamesfun
Links
Download
Musik

Bugfixes am Forum
Subdomains aktiviert
Counterscript entfernt
  Navigation:   Index /  Amiblitz /  Amiblitz Lesematerial /  Blitz2 Benutzerhandbuch (Index) /  Blitz2 Benutzerhandbuch (Kapitel 3) / 

Benutzerhandbuch


Kapitel 3




Datentypen, Felder und Listen

·Numerische Datentypen
·Der Default-Datentyp
·Die Data-Anweisung
·Wertüberlauf
·Der Datentyp String
·Sytemkonstanten
·Die NewType-Anweisung
·Felder innerhalb von NewTypes
·Die UsePath-Anweisung
·Felder
·Listen
·Der Datentyp Pointer




Index Numerische Datentypen


Blitz2 kennt 6 verschiedene Variablentypen. 5 davon sind numerische Datentypen, die dazu dienen, Zahlenwerte mit unterschiedlichen Wertebereichen und unterschiedlicher Genauigkeit zu speichern, der sechste Datentyp speichert Folgen von Buchstaben, also Strings (Text).

Die untenstehende Tabelle gibt den Wertebereich, die Genauigkeit und den Speicherbedarf für alle numerischen Datentypen an:

Typ Zusatz Bereich Genauigkeit Bytes
Byte .b +/- 128 ganzzahlig 1
Word .w +/- 32768 ganzzahlig 2
Long .l +/- 2147483648 ganzzahlig 4
Quick .q +/- 32768.0000 1/65536 2
Float .f +/- 9*10^18 1/10^18 4


Der Datentyp Quick ist eine Festkomma-Größe mit geringerer Genauigkeit als Fließkommatypen, dafür aber schneller.

Float ist eine Fließkomma-Größe, die von der 'Amiga Fast Floating Point Bibliothek` unterstützt wird.

Bei der Vereinbarung einer Variablen wird deren Datentyp durch den entsprechenden Zusatz (Suffix) bestimmt. Damit ist der Datentyp festgelegt und braucht bei allen weiteren Zugriffen nicht mehr angegeben zu werden, außer bei String-Variablen.

Es folgen einige Beispiele für numerische Variablen und deren Zusatz.

mychar.b=127
my_score.w=32000
chip.l=$dff000        ;$ bezeichnet einen Hexadezimal-Wert
speed3.q=500/7     ;Quick-Variablen haben eine Genauigkeit von 3 Dezimalpunkten
light_speed.f=3e8   ;e ist der Exponent, d.h. 3x10^8



Index Der Default-Datentyp


Wird bei der Vereinbarung einer Variablen kein Zusatz angegeben, so wird automatisch der Default-Datentyp (Vorbesetztung) zugewiesen. Ist nichts weiter angegeben, so ist dies Quick.

Um die Vorbesetzung zu ändern, benutzt man den Befehl DEFTYPE. Alle Variablen, die anschließend ohne ausdrückliche Angabe des Datentyps vereinbart werden, sind vom neuen Default-Typ.

Folgt dem Befehl DEFTYPE unmittelbar eine Liste von Variablennamen, dient er dazu, den Datentyp für diese Variablen zu bestimmen, die Vorbesetzung jedoch unverändert zu lassen. Der Befehl bekommt dadurch also eine andere Bedeutung.

Das nachfolgende Beispiel erläutert den Gebrauch der beiden Varianten von DEFTYPE.

a=20                    ;a ist vom Typ Quick
DEFTYPE .f          ;Der neue Default-Typ ist jetzt Float
b=20                    ;b ist vom Typ Float
DEFTYPE .w c,d   ;c & d sind vom Typ Word, Default ist immer noch Float


Anmerkung: die erste Form von DEFTYPE kann mit "ändere Default-Typ" übersetzt werden, die zweite Form bedeutet "Definiere Typ".

Als Default-Typ kann auch ein NewType festgelegt werden, näheres dazu im nächsten Abschnitt.

Es gibt noch weitere Blitz2-Strukturen, wie Data, Peek, Poke, sowie Funktionen, die ebenfalls den Default-Datentyp verwenden, sofern kein Zusatz angegeben ist.



Index Die Data-Anweisung


Die Data-Anweisung dient dazu, einer Reihe von Variablen eine Liste von Werten zuzuordnen. Die Restore-Anweisung dient dazu, den Datenzeiger auf eine bestimmte Data-Anweisung zeigen zu lassen.

Um zu bestimmen, von welchen Datentyp die Werteliste ist, wird der entsprechende Zusatz .typ angefügt.

Das folgende Beispiel erläutert den Gebrauch von Data in Blitz2:

Read a,b,c
Restore myfloats
Read d.f
Restore mystrings
Read e$,f$,g$
myquicks:
    Data 20,30,40
myfloats:
    Data .f20.345,10.7,90.111
mystrings:
    Data$ "Guten","Morgen","Simon"


Anmerkung: wenn der Datenzeiger auf einen anderen Datentyp zeigt als die Variable, die in der Read-Anweisung aufgeführt ist, tritt der Compilerfehler "Mismatched Types" ("Nicht-gleichwertige Datentypen") auf.



Index Wertüberlauf & vorzeichenlose Zahlen


Wird einer Variablen ein Wert zugewiesen, der außerhalb des Wertebereichs des Datentyps liegt (also zu groß ist), tritt ein Überlauf-Fehler auf. Das folgende Beispiel erzeugt einen solchen Überlauf-Fehler, wenn es ausgeführt wird:

a.w=32767    ;a ist ein Word mit dem Wert 32767
a=a+1          ;Überlauf, der Wert ist zu groß


Die Überprüfung von Überlauf-Fehlern kann in der Compiler-Konfiguration unter "Run Time Errors Options" ein- oder ausgeschaltet werden. Die Voreinstellung ist "aus", sodaß das obige Beispiel keine Fehlermeldung erzeugen würde.

Es kann vorkommen, daß eine ganzzahlige Variable (Integer) vorzeichenlos sein soll, also nur positive Werte annehmen kann. Byte-Variablen sollen z.B. häufig einen Wertebereich von 0 bis 255 haben statt -128 bis +127. Um dies zu ermöglichen, muß die Überprüfung von Überlauf-Fehlern in der Compiler-Option "Error Checking" ausgeschaltet werden



Index Der Datentyp String


Ein String ist eine Variable, die dazu dient, eine Zeichenkette zu speichern, also Text. Eine String-Variable wird mit dem Zusatz .s oder dem traditionellen $-Zeichen gekennzeichnet.

Anders als bei numerischen Variablen, muß dieser Zusatz grundsätzlich immer angegeben werden. Dies hängt damit zusammen, daß der Name einer String-Variablen gleichzeitig auch für eine numerische Variable verwendet werden kann.

Das folgende Beispiel ist also zulässig:

a$="Hallo"
a.w=20
NPrint a,a$



Index Systemkonstanten


Unter Systemkonstanten werden spezielle Variablen verstanden, die von Blitz2 dazu verwendet werden, bestimmte unveränderliche Werte zu speichern. Die folgenden Variablen-Namen sind also reserviert für die angeführten Werte:

Pi    3.1415
On    -1
Off    0
True    -1
False    0



Zusammenfassung der einfachen Datentypen

Blitz2 kennt 6 einfache Datentypen, die Typen Byte, Word und Long sind vorzeichenbehaftete 8-, 16- und 32-Bit-Größen.

Der Datentyp Quick ist eine Festkomma-Größe, die nicht so genau ist wie Fließkomma-Größen, aber schneller.

Der Datentyp Float ist die von der 'Amiga Fast Floating Bibliothek' unterstützte Fließkomma-Größe.

String ist die standardmäßige BASIC-Implementation für Zeichenketten.

Mit Hilfe der DefType-Anweisung, können Variablen eines bestimmten Typs vereinbart werden, ohne daß jeweils der Zusatz angegeben werden muß.

Ist eine Variable einmal vereinbart, kann der Zusatz für den Datentyp weggelassen werden, außer bei String-Variablen. Dort muß er grundsätzlich immer angegeben werden.

Der Datentyp einer Variable ist innerhalb eines Programms unveränderlich und es kann immer nur eine Variable eines Namens vereinbart werden. Eine Ausnahme bilden wiederum die Strings, bei denen der gleiche Name auch für eine numerische Variable vergeben werden kann.



Index Die NewType - Anweisung


Zusätzlich zu den 6 einfachen Datentypen, die in Blitz2 zur Verfügung stehen, haben Programmierer die Möglichkeit, eigene Datentypen zu entwerfen.

Der Befehl NewType ermöglicht es,verschiedene Datentypen,die inhaltlich zusammengehören, zu einem neuen Datentyp zusammenzufügen, ähnlich einem Datensatz in einer Datenbank oder einer Struktur in C. Das folgende Beispiel zeigt, wie Variablen, die den Namen, das Alter und die Größe einer Person enthalten, einem neuen Variablentyp zugeordnet werden.

NEWTYPE .Person
    name$
    alter.b
    groesse.q
End NEWTYPE

a.Person\name = "Harry",20,1.8
NPrint a\height


Ist ein NewType einmal definiert, können Variablen dieses Typs vereinbart werden, indem der Zusatz .NeuerTypname angefügt wird, z.B.: a.Person.

Auf einzelne Elemente innerhalb eines NewType kann durch das Zeichen "\" (Backslash) zugegriffen werden, z.B.: a\groesse=a\groesse+1.

Bei der Definition eines NewType erhalten Variablen, für die kein Suffix angegeben ist den Datentyp des vohergehenden Elementes. Es können auch mehrere Elemente in einer Zeile aufgeführt werden, wenn sie durch Doppelpunkte getrennt sind. Es folgt ein weiteres Beispiel eines NewType:

NewType .nme
    x.w:y:z        ;y & z sind auch von Typ Word (s.o.)
    wert.w
    speed.q
    name$
End NewType


Der Zugriff auf Strings innerhalb eines NewType benötigt keinen $ oder .s-Zusatz wie bei normalen Zeichenketten. Ist ein solcher Suffix angegeben, führt dies zur Compilermeldung "Garbage at End of Line"("Schrott am Ende der Zeile"). Bezogen auf das erste Beispiel heißt das:

a\name="Jimi Hendrix"    ;richtig
a\name$="Bob Dylan"     ;falsch


Zuvor definierte NewTypes können in darauffolgenden NewType-Definitionen weiterverwendet werden. Es folgt ein Beispiel für eine NewType-Definition, die einen anderen NewType enthält:

NewType .vektor
    x.q
    y.q
    z.q
End NewType

NewType .object
    position.vektor
    geschwindigkeit.vektor
    beschleunigung.vektor
End NewType

DefType .object meinschiff       ;s. nächster Absatz
meinschiff\position\x=100,0,0


Beachten Sie, daß jetzt zwei Backslashes nötig sind um auf Elemente des NewType "meinschiff" zuzugreifen. Das ganze sieht jetzt aus wie ein Pfadname unter DOS.

Ein einmal definierter NewType kann im Zusammenhang mit beiden Formen des DefType-Befehles verwendet werden, genauso wie jeder andere Datentyp.



Index Felder innerhalb von NewTypes


Außer einfachen Datentypen und anderen NewTypes können auch Felder als Bestandteile für NewTypes verwendet werden. Zu ihrer Kennzeichnung werden die eckigen Klammern [ und ] verwendet.

Im Gegensatz zu normalen Feldern sind Felder innerhalb von NewTypes begrenzt auf eine Dimension und ihre Größe muß durch eine Konstante definiert werden, nicht durch eine Variable. Ein Feld kann einen beliebigen Datentyp besitzen, auch Felder vom Typ eines NewType sind zulässig.

Ein weiterer Unterschied zu herkömmlichen Feldern besteht darin, daß die Angabe in den eckigen Klammern genau die Größe des Feldes angibt. (Bei herkömmlichen Feldern ist dies nicht der Fall, siehe nächster Abschnitt) Die Anweisung adresse.s[4] reserviert Speicherplatz für 4 Strings mit den Indizes 0 bis 3.

Das folgende Beispiel erläutert den Gebrauch von Feldern in NewTypes:

NewType .datensatz
    name$
    alter.w
    adresse.s[4]    ; dasselbe wie adresse$[4]
End NewType

DefType .datensatz p
p\adresse[0]="10 St Kevins Arcade"
p\adresse[1]="Karangahape Road"
p\adresse[2]="Auckland"
p\adresse[3]="New Zealand"
For i=0 TO 3
    NPrint p\adresse[i]
Next
MouseWait


Wenn kein [index] angegeben ist, wird das erste Feldelement (0) verwendet.

Wird ein Feld mit der Länge 0 innerhalb eines NewType vereinbart, so bildet dies eine 'Union' mit dem nachfolgenden Element, d.h. beide Elemente belegen den selben Speicherplatz.



Index Die UsePath-Anweisung


Bei der Verwendung von verschachtelten NewTypes können die Pfadnamen für den Zugriff auf Elemente innerhalb von Elementen sehr lang werden.

Wenn eine Routine nur auf ein Element zugreift, können lange Pfadnamen durch die Verwendung von UsePath vermieden werden. Wird auf ein Feld zugegriffen, das nicht mit dem Namen der Wurzel-Variablen beginnt, sondern mit einem Backslash, fügt der Compiler den Namen der Wurzel-Variablen ein, der in der UsePath-Anweisung definiert wurde.

Im folgenden Beispiel

UsePath Shapes (i)\pos
For i=0 To 9
    \x+10
    \y+20
    \z-10
Next


wird der Variablenname vom Compiler erweitert, sodaß sich folgendes ergibt:

For i=0 To 9
    shapes(i)\pos\x+10
    shapes(i)\pos\y+20
    shapes(i)\pos\z-10
Next


Durch die UsePath-Anweisung wird das Programm erheblich besser lesbar und es wird Schreibarbeit gespart.

Es sei darauf hingewiesen, daß UsePath eine Compiler-Direktive ist, d.h. die Anweisung wird bereits vom Compiler ausgewertet und nicht erst vom Prozessor zur Laufzeit. Dies hat Auswirkungen, wenn in dem Programm UsePath-Anweisungen übersprungen werden: der jeweils gültige UsePath ist trotzdem derjenige, der im Quellcode vor der entsprechenden Anweisung steht.



Index Felder


Felder in Blitz2 entsprechen den normalen BASIC-Konventionen. Alle Felder müssen dimensioniert werden, bevor sie verwendet werden können. Sie können aus beliebigen Datentypen bestehen (einfache oder NewType) und sie können beliebig viele Dimensionen besitzen.

Alle Felder besitzen einen Index von 0 bis n, wobei n die Größe des Feldes ist. Wie in anderen BASIC-Versionen auch, kann ein Feld eigentlich ein Element mehr als n aufnehmen, es wird nämlich von 0 bis n einschließlich gezählt. Das Feld a(50) besitzt also 51 Elemente, von 0 bis 50.

Bei der Vereinbarung eines Feldes wird, wie bei allen anderen Variablen auch, der Default-Datentyp angenommen, wenn nicht ausdrücklich ein .typ-Zusatz angegeben ist:

Dim a.w(50)    ;Ein Feld vom Typ Word


Durch die Möglichkeit, Felder aus NewType-Datentypen zu vereinbaren, verringert sich die Anzahl von Feldern, die ein BASIC-Programm benötigt.

Betrachten wir folgendes Beispiel:

Dim Alienflags(100),Alienx(100),Alieny(100)


Unter Verwendung von NewType-Datentypen könnte dasselbe auch erreicht werden durch:

NewType .Alien
    flags.w
    x.w
    y.w
End NewType

Dim Aliens.Alien(100)


Es wird jetzt nur ein Feld benötigt, um auf alle benötigten "Alien"-Daten zugreifen zu können. Sollen alle x- und y-Werte von Alien auf einmal mit Zufallszahlen belegt werden, so kann dies folgendermaßen geschehen:

For k=1 To 100
    Alien(k)\x=Rnd(320),Rnd(200)
Next


Sollen jetzt weitere Informationen über Aliens hinzugefügt werden, müssen diese lediglich in der Definition des NewType eingetragen werden, es brauchen keine neuen Felder angelegt zu werden.

Anmerkung: Im Gegensatz zu den meisten anderen BASIC-Compilern ERLAUBT Blitz2 die Vereinbarung von Feldern mit variablen Dimensionen, also Dim a(n). Außerdem muß für Strings in Feldern KEINE maximalen Länge angegeben werden, wie in einigen anderen Programmiersprachen.



Index Listen


In Blitz2 gibt es auch eine weiterentwickelte Form der Felder, die Listen. Listen sind grundsätzlich Felder, haben aber einige spezielle Eigenschaften.

Häufig wird jeweils nur ein bestimmter Abschnitt eines Feldes belegt und es wird eine gesonderte Variable mitgeführt, die Auskunft darüber gibt, wieviele Elemente des Feldes zur Zeit belegt sind. In einem solchen Fall sollte das Feld durch eine Liste ersetzt werden, die die Verwaltung erheblich vereinfacht und beschleunigt.


Dimensionierung einer Liste

Die Dimensionierung einer Liste erfolgt genau wie bei einem Feld, es wird lediglich das Wort List hinter Dim eingefügt. Listen sind z.Zt. auf eine Dimension begrenzt.

Hier ist ein Beispiel für die Definition einer Liste:

NewType .Alien
    flags.w x y
End NewType

Dim List Aliens.Alien(100)


Der Unterschied zu einem einfachen Feld besteht nun darin, daß Blitz2 einen internen Zähler über die Anzahl der Listenelemente sowie einen Zeiger auf das jeweils aktuelle Element mitführt. Beide werden durch die 'Dim List'-Anweisung auf 0 gesetzt.


Elemente zu einer Liste hinzufügen

Zu Beginn ist jede Liste leer, Listenelemente können durch die Funktionen AddItem und AddLast hinzugefügt werden. Da Listen irgendwann einmal voll sind, liefern diese beiden Funktionen den Wert Wahr oder Falsch zurück, je nachdem, ob das Element eingefügt werden konnte oder nicht.

Im folgenden Beispiel wird ein Alien zu der zuvor dimensionierten Liste hinzugefügt:

If AddItem(Aliens())
    Aliens()\x=Rnd(320),Rnd(200)
EndIf


In beiden Aufrufen von Aliens() wurde kein Index in den Klammern angegeben. Obwohl Blitz2 keine Fehlermeldung ausgeben würde, wenn ein solcher Index vorhanden wäre, sollten Listen NIEMALS mit einem Index aufgerufen werden. Die leeren Klammern verweisen auf das aktuelle Listenelement, in diesem Fall das gerade hinzugefügte.

Da AddItems den Wert Falsch zurückliefert, wenn die Liste voll ist, kann eine While...Wend-Schleife verwendet werden, um die gesamte Liste aufzufüllen:

While AddItem(Aliens())
    Aliens()\x=Rnd(320)
    Aliens()\y=Rnd(200)
Wend


Die Schleife wird solange durchlaufen, bis die Liste gefüllt ist. Wenn man eine feste Zahl (z.B. 20) von Einträgen in die Liste einfügen möchte, könnte man auch eine For...Next-Schleife verwenden, müßte aber trotzdem nach jedem Einfügen den Zustand der Liste prüfen:

For i=1 To 20
    If AddItems(Aliens())
        Aliens()\x=Rnd(320)
        Aliens()\y=Rnd(200)
    EndIf
Next


Listen können natürlich für jeden Datentyp angelegt werden, nicht nur für Aliens, d.h. sie sind nicht nur für Spiele zu gebrauchen.


Listenverarbeitung

Wie schon erwähnt, wird das Listenelement, das zuletzt eingefügt wurde, zum aktuellen Element. Auf dieses aktuelle Element kann zugegriffen werden, indem der Listenname mit leeren Klammern () angegeben wird.

Um die Liste von vorne bis hinten zu verarbeiten, wird zunächst der interne Listenzeiger mit ResetList zurückgesetzt, und dann wird in einer Schleife mit Hilfe von NextItem schrittweise von einem Eintrag zum nächsten gegangen. Der interne Zeiger zeigt dann jeweils auf das aktuelle Element.

Im folgenden werden alle Aliens in der Liste auf eine eher ineffektive Weise bewegt (wohl zur Bildschirmmitte):

USEPATH Alien()
ResetList Aliens()
While NextItem(Aliens())
    If \x>160 Then \x-1 Else \x+1
    If \y>100 Then \y-1 Els \y+1
Wend


Die While...Wend-Schleife wird solange durchlaufen, bis alle Listenelemente einmal das aktuelle Element waren und bearbeitet wurden, unabhängig davon, wieviele Elemente zuvor eingefügt wurden.

Da NextItem den Wert Falsch zurückliefert, wenn kein Listenelement mehr vorhanden ist, wird an dieser Stelle die Schleife abgebrochen. Das Beispiel macht klar, wieviel bequemer und sauberer es ist, Listen zu benutzen statt herkömmlicher Felder. Statt der "For i=1 To n"-Schleife wird einfach eine "While...Wend"-Struktur verwendet, und die Listenverwaltung ist obendrein auch noch schneller.


Listenelemente löschen

Oftmals ist es notwendig, ein Element aus der Liste zu entfernen, nachdem es bearbeitet wurde. Hierzu dient die Funktion KillItem. In diesem Beispiel wird wiederum die Alien-Liste verwendet:

ResetList Aliens()
While NextItem(Aliens())
    If Aliens()\flags=-1    ; wenn flag = -1
        KillItem Aliens()    ; Element löschen
    EndIf
Wend


Nach dem Aufruf von KillItem zeigt der Listenzeiger auf das vorhergehende Element und macht es damit zum aktuelle Element. Dadurch wird in der Schleife kein Element übersprungen, nachdem eines gelöscht wurde.


Listenstrukturen

Es ist zwar möglich, auf Listenelemente wie auf herkömmliche Feldelemente durch Angabe des Index zuzugreifen, dies sollte aber niemals gemacht werden.

Die logische Reihenfolge der Elemente in der Liste ist nicht notwendigerweise die selbe wie die Reihenfolge, in der die Elemente im Speicher abgelegt sind. Intern besitzt jedes Listenelement einen Zeiger auf den Vorgänger und den Nachfolger. Wenn Blitz2 auf das nächste Element zugreifen will, richtet es sich nur nach dem Zeiger auf den Nachfolger; an welcher Speicherstelle dieser sich befindet, ist völlig unerheblich.

Beim Hinzufügen eines Elementes wird dieses an einer beliebigen Stelle im Speicher untergebracht. Seine Speicheradresse wird im Nachfolger-Zeiger des vorhergehenden Elementes hinterlegt und dessen alter Wert wird in den Nachfolger-Zeiger des neuen Elementes übernommen.

Nicht so recht verstanden? Macht auch nichts, greifen Sie einfach nie auf Listenelemente über den Feldindex zu!



Index Der Datentyp Pointer


Der Datentyp Pointer (Zeiger) in Blitz2 ist eine komplizierte Angelegenheit. Wenn eine Variable als Zeiger definiert wird, wird gleichzeitig festgelegt, auf welchen Datentyp sie zeigt. Im folgenden Beispiel wird "groesster" als Zeiger auf den Typ "Kunde" definiert.

DefType *groesster.Kunde


Die Variable "groesster" ist einfach ein Doppelwort, das die Speicheradresse einer anderen Variablen vom Typ Kunde enthält.

Als Beispiel soll eine lange Liste "KundenListe()" des Typs "Kunde" dienen, die nach dem Kunden mit dem größten Umsatz durchsucht werden soll. Wenn der Umsatz eines Kunden (also eines Listenelements), größer ist als der, auf den die Variable "groesster" im Moment zeigt, wird diese so verändert, daß sie auf den aktuellen Kunden (also das aktuelle Listenelement) zeigt, wie in der folgenden Zeile:

*groesster=KundenListe()


Wenn in einer Schleife die ganze Liste durchlaufen ist, kann die Variable "groesster" ausgedruckt werden, so als ob sie selber vom Datentyp Kunde wäre, obwohl sie eigentlich nur ein Zeiger auf eine andere Variable diese Typs ist:

Print *groesster\name









Index



Impressum
Copyright © 2001-2007 by Cj-Stroker. Alle Rechte vorbehalten (Legal Info)
AMIGA und zugehörige Logos sind eingetragene Warenzeichen von Amiga, Inc.