Ein Pointer ist eine positive Ganzzahl. Diese Zahl ist aber nicht nur ein simpler Wert, sondern gibt eine Adresse (Nummer des Bytes) im Speicher an. Pointer heißen auf deutsch auch "Zeiger". Das ist so, weil der Pointer auf die Speicherstelle "zeigt", die die Pointer-Adresse besitzt. Auf diese Speicherstelle kann über besondere Syntax-Regeln zugegriffen werden. Mit Hilfe von Pointern kann direkt auf den Speicher zugegriffen werden und ihn so einfacherer, flexiblerer verwalten, als es mit PEEK und POKE möglich ist. PEEK und POKE sind nur aus Kompabilitätsgründen zu QB vorhanden und sollten nicht verwendet werden.
Im Zusammenhang mit Pointern treten folgende Sprachkonstrukte auf:
PTR oder POINTER
Wird im Zusammenhang mit Datentypen verwendet. Es gibt an, dass eine Variable ein Pointer, also ein Zeiger auf eine Variable des angegebenen Typs ist.
DIM a AS BYTE PTR
Im Programm kann auf die als Pointer deklarierte Variable ganz normal zugegriffen werden; sie verhält sich immer wie eine Variable des Typs UINTEGER.
DIM a AS BYTE PTR
DIM z AS BYTE
z = 120
a = VARPTR(z)
PRINT z, a
' Ausgabe: 120 4210692
' Also ist a mindestens 32bit
a = -1
PRINT a
' Ausgabe: 4294967295
' Also ist jeder Pointer ein UInteger-Typ. Ist auch logisch,
' negative Adressen gibt es nicht.
SLEEP
Wertezuweisungen (myPointer = 5), Operationen (myValue = (myPointer * 5) AND 3) und alle sonstigen Befehle werden genauso ausgeführt, wie an jeder skalaren, ('normalen') Variable auch. Dabei ist zu beachten, dass die Adresse verändert wird, die der Pointer repräsentiert, nicht aber der Wert, der sich an dieser Stelle im Speicher befindet.
Es existieren auch einige Pointeroperatoren, die nur mit Pointern funktionieren, darunter auch welche, womit gezielt der Wert im Speicher geändert wird. Diese sind hier unten aufgeführt:
@Variable
Gibt die Adresse einer normalen Variablen zurück, also einen Pointer, der auf die Variable zeigt. Es ist eine Kurzform für VARPTR. Dies kann auch an nicht-Pointer-Variablen angewandt werden; zurückgegeben wird dann einfach die Adresse als UINTEGER-Wert.
Beispiel:
DIM myValue AS INTEGER
DIM myPointer AS INTEGER PTR
myPointer = @myValue
PRINT myPointer, @myPointer
SLEEP
(Gibt die Adresse von myValue und die Adresse des Pointers selbst aus.)
*(Pointer)
Gibt den Wert zurück, der an der Speicherstelle steht, auf die der Pointer zeigt (Dereferenzierung). Auch komplexe Pointerausdrücke können dereferenziert werden, d.h. in der Klammer kann ein ganzer Ausdruck stehen, der dann als Pointer behandelt wird. Vorsicht: Wenn Sie auf Speicherstellen zugreifen, die nicht von Variablen Ihres Programms verwendet werden, riskieren Sie einen Absturz Ihres Programmes oder sogar des Betriebssystems!
Beispiel:
DIM myValue
DIM myPointer AS INTEGER PTR
myValue = 5
myPointer = @myValue
PRINT *myPointer
' Gibt den Wert von myValue aus, da myPointer
' auf die Adresse von myValue zeigt.
PRINT *(myPointer + 1)
' Gibt einen anderen Wert aus, der i.d.R. nicht
' genau bestimmt werden kann, da auf der
' Speicherstelle, die ein Byte hinter myValue liegt,
' bereits ein anderer Wert gespeichert ist.
SLEEP
Pointer[index]
Zählt zum Pointer index hinzu, bevor weitere Operationen mit ihm durchgeführt werden. Der Pointer wird also dereferenziert.
Pointer[index]
hat die selbe Funktion wie
*(Pointer + index)
Diese Art der Dereferenzierung wird oft mit ALLOCATE verwendet.
Beispiel:
DIM a AS BYTE PTR
a = ALLOCATE(10)
a[3] = 20
PRINT a[3]
PRINT a[4]
PRINT a
SLEEP
(Wenn a[4] ungleich 0 ist, liegt das daran, dass sich vor der Reservierung des Speicherbereichs noch Daten auf dieser Stelle befanden, die jetzt nicht mehr gebraucht werden; eine Initialisierung mit CALLOCATE sollte zehn leere Speicherstellen erzeugen.
->
Dereferenziert einen Pointer, der auf einen TYPE zeigt, sodass er auf den entsprechenden Record verweist. Die Pointer-Variable zeigt also auf eine Variable im Speicher vom angegebenen Typ. So kommt man leicht an die im Typ enthaltenen Daten.
Beispiel:
TYPE myType
a AS INTEGER
b AS SHORT
c AS INTEGER PTR
END TYPE
DIM d AS myType PTR
PRINT d->b
SLEEP
Im Vergleich dazu die Nicht-Pointer-Version:
TYPE myType
a AS INTEGER
b AS SHORT
c AS INTEGER PTR
END TYPE
DIM d AS myType
PRINT d.b
SLEEP