Referenz - Pointer
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": der Pointer "zeigt" auf die Speicherstelle, welche die Pointer-Adresse besitzt. Auf diese Speicherstelle kann über besondere Syntax-Regeln zugegriffen werden. Mit Hilfe von Pointern kann man direkt auf den Speicher zugreifen und ihn so einfacher, flexibler verwalten, als es mit PEEK und POKE möglich ist. PEEK und POKE sind nur aus Kompatibilitätsgründen zu QB vorhanden und sollten nicht verwendet werden.
Im Zusammenhang mit Pointern treten folgende Sprachkonstrukte auf:
PTR oder POINTER
Die beiden Schlüsselwörter PTR und POINTER sind gleichbedeutend. Sie werden im Zusammenhang mit Datentypen verwendet und geben 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 Ihre Größe beträgt, je nachdem, ob ein 32bit- oder 64bit-Compiler verwendet wird, 32 bzw. 64 Bit.
DIM a AS BYTE PTR
DIM z AS BYTE
z = 120
a = VARPTR(z)
PRINT z, a
' mögliche Ausgabe (32bit-Compiler): 120 4210692
' Also ist a mindestens 32bit
a = -1
PRINT a
' Ausgabe (32bit-Compiler): 4294967295
' Also ist jeder Pointer ein UInteger-Typ. Ist auch logisch,
' negative Adressen gibt es nicht.
SLEEP
Da eine direkte Zuweisung konstanter Werte an einen Pointer, abgesehen vom Nullsetzen (myPointer = 0), unüblich und möglicherweise vom Programmierer nicht beabsichtigt ist, gibt der Compiler in solchen Fällen die Warnung aus:
Suspicious pointer assignment
Es ist zu beachten, dass hierbei 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 werden im folgenden aufgeführt.
@Variable
Der Operator @ 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
' Adresse von myValue und die Adresse des Pointers ausgeben
PRINT myPointer, @myPointer
SLEEP
*Pointer
Der Operator * (Stern) 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 Programms oder sogar des Betriebssystems!
Beispiel:
DIM myValue AS INTEGER
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]
Bei der Pointerindizierung wird zum Pointer index hinzugezählt, bevor weitere Operationen mit ihm durchgeführt werden. Der Pointer wird also dereferenziert.
Pointer[index]
hat dieselbe 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
DEALLOCATE 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 erzeugt dagegen zehn leere Speicherstellen.
UdtPtr->Attribut
Der Pfeiloperator dereferenziert einen Pointer, der auf einen UDT zeigt, sodass er auf das entsprechende Attribut verweist. Die Pointer-Variable zeigt also auf eine Variable im Speicher vom angegebenen UDT. So kommt man leicht an die im UDT enthaltenen Daten.
Beispiel:
TYPE myType
a AS INTEGER
b AS SHORT
c AS INTEGER PTR
END TYPE
DIM udtPtr AS myType PTR = NEW myType
PRINT udtPtr->b
DELETE udtPtr
SLEEP
Im Vergleich dazu die Nicht-Pointer-Version:
TYPE myType
a AS INTEGER
b AS SHORT
c AS INTEGER PTR
END TYPE
DIM udt AS myType
PRINT udt.b
SLEEP
Zusätzliche Informationen und Funktionen | ||||
---|---|---|---|---|
|