Zeigeroperationen
In OWBasic ist es möglich, Zeigervariablen zu deklarieren und zu verwenden. Vor Version 4.2 existierten Zeiger ausschließlich als VAR-Parameter in Prozeduren und konnten nicht verändert werden. Um die Abwärtskompatibilität zu gewährleisten, werden Zeiger bei ihrer Verwendung automatisch dereferenziert (d.h., es wird auf das, worauf der Zeiger zeigt, zugegriffen); um ihren Wert abzufragen oder zu verändern, muß die spezielle Zeigersyntax verwendet werden. Es ist auch möglich, Arrays von Zeigern zu deklarieren, für deren Benutzung wiederum eine spezielle Syntax existiert.
Um eine Zeigervariable zu deklarieren, weisen Sie ihr einen Wert zu:
&<pointer><type-suffix> = <int-expression> |
Wenn Sie einer Zeigervariablen noch keine bestimmte Adresse zuweisen wollen, ist es ratsam, den Zeiger auf die symbolische Konstante NULL zeigen zu lassen:
&<pointer><type-suffix> = #NULL:end
$$$
Normalerweise weist man einem Zeiger die Adresse einer anderen Variable zu.
Um die Adresse zu erhalten, wird der &-Operator angewendet:
:pre
&<pointer><type-suffix> = &<variable> |
Ein Zeiger kann auch auf ein Element eines Arrays zeigen:
&<pointer><type-suffix> = &<variable>[<int-expression>] |
Um die Adresse einer Variable, auf die bereits ein anderer Zeiger zeigt, zu übernehmen, kann diese wie bei einer normalen Variable abgefragt werden:
&<pointer2><type-suffix> = &<pointer> |
Um die flexible Handhabung von Arrays zu ermöglichen, ist es erlaubt, Pointer zu indizieren:
<variable> = <pointer>[<int-expression>] |
Dieser Code setzt <variable> auf den Wert der Variablen, die im Speicher um <int-expression> Einheiten weiter als die Variable, auf die <pointer> zeigt, steht. Das Ergebnis ist nur definiert, wenn <pointer> auf ein Element eines Arrays zeigt und das Array größer ist als <pointer> + <int-expression> .
Zeigerarrays lassen sich mit DIM deklarieren:
DIM &<pointer-array><type-suffix>[<constant expression>] |
Um auf ihre Elemente zuzugreifen, muß wieder eine spezielle Syntax verwendet werden:
&~<pointer-array>[<int-expression>] = <int-expression> |
oder alternativ in der vereinfachten, aber inkonsequenten Syntax:
&<pointer-array>[<int-expression>] = <int-expression> |
Dementsprechend wird auch auf ein Pointer-Array zugegriffen:
&<pointer> = &~<pointer-array>[<int-expression>] |
Um auf den von einem Element eines Zeiger-Arrays bezeigten Wert zuzugreifen, bedarf es folgender Syntax:
~<pointer>[<int-expression>] = <expression>
<variable> = ~<pointer>[<int-expression>] |
Bei Bedarf kann auch ein solcher Pointer indiziert werden:
~<pointer>[<int-expression>][<int-expression2>] = <expression>
<variable> = ~<pointer>[<int-expression>][<int-expression2>] |
In einigen Fällen möchte an auf die Adresse eines Pointers zugreifen. Beispielsweise kann das nützlich sein, wenn man einen Pointer über ein Array iteritieren läßt:
INC &&<pointer>
INC &&<pointer>[<int-expression>] |
ACHTUNG: Dies funktioniert nicht bei Zeigern auf Float-Arrays, da Float-Zahlen mehr Speicherplatz benötigen als Integerzahlen (bei den anderen Datentypen ergeben sich keine Probleme, da Char- und Bool-Variablen intern als Integervariablen dargestellt und bei Strings wiederum nur Integer-große Zeiger verwaltet werden). Um über ein Float-Array zu iteritieren, sollte die folgende Vorgehensweise angewandt werden:
INC &&<float-pointer>,#FLOATSIZE
INC &&<float-pointer>[<int-expression>],#FLOATSIZE |
FLOATSIZE ist eine globale Konstante und gibt die Größe von Float in Einheiten von Integer an.
Um einem Zeiger einen Integerwert zuzuweisen, kann man einen solchen mittels POINTER@(i%) in einen Zeiger beliebigen Typs umwandeln (das @ steht hier für das Typ-Suffix bzw. die Angabe eines eigenen Typs).
Ein Zeiger, der nicht automatisch dereferenziert wird (z.B., wenn er von einer Funktion zurückgeliefert wird oder Ergebnis eines komplexen Ausdrucks ist), kann mit dem Operator '*' explizit dereferenziert werden:
i=*(&array+2) !: äquivalent zu i=array[2] |
Pointer und Pointer-Arrays können nur eindimensional indiziert werden.
Zeiger sind bei unachtsamer Verwendung sehr gefährlich; z.B. findet bei der Indizierung von Zeigern keine Bereichsüberprüfung statt. Auch kann nicht überprüft werden, ob ein Zeiger auf die korrekte Speicherstelle zeigt; dies kann vor allem im Zusammenhang mit der String-Verwaltung in OWBasic fatale Folgen haben. Aus diesem Grunde wird empfohlen, die Zeiger wenn überhaupt unter äußerster Vorsicht anzuwenden.
|