PureBasic: Zeiger
Viele Programmier bezeichnen Zeiger als eines der am schwierigsten zu verstehenden Themen im Bereich Programmierung. Dabei sind Zeiger ganz einfach zu verstehen, wenn man sich klarmacht, wie Variablen und andere Daten im Arbeitsspeicher liegen.
Jede Variable im Arbeitsspeicher hat eine Adresse. Wenn man sich den Arbeitspeicher bildlich wie eine Reihe von verschieden großen Kisten (je nachdem welchen Typ die Variable hat) vorstellt, dann liegen die Variablen in diesen, wobei jede dieser Kisten eine Adresse hat, wie eine Hausnummer. Der Computer arbeitet intern auf der Maschinensprachenebene mit diesen Adressen, um auf die Variablen zuzugeifen, er benutzt dafür nicht die Bezeichner. Man benutzt nun Zeiger um dies ebenfalls wie der Computer zu tun. Im Zeiger speichert man also die Adresse einer Variable, um über jenen auf diese zuzugreifen. Man nennt diesen Zugriff dann Dereferenzierung, denn der Zeiger stellt eine Referenz zur Variable dar.
; Listing 33: Zeiger Procedure change(*ptr2.l) PokeL(*ptr2, 6) EndProcedure x = 5 OpenConsole() PrintN(Str(x)) *ptr = @x change(*ptr) PrintN(Str(PeekL(*ptr))) Delay(2000)
Ausgabe: 5 6
Man definiert eine Funktion, die einen Zeiger auf eine Longvariable (.l) als Argument hat, d.h. sie erwartet die Adresse einer Longvariable. Man definiert die Variable x und initialisiert sie mit 5. Nachdem man sie ausgegeben hat, definiert man den Zeiger *ptr und initialisiert ihn mit der Adresse von x. Man erhält die Adresse über den Operator @. Das Sternchen gehört fest zum Bezeichner des Zeigers. In der Prozedur wird der Zeiger über PokeL() dereferenziert, sodass auf die eigentliche Variable x zugegriffen werden kann, mit dem Ziel in diese einen neuen Wert zu schreiben. Wenn man auf Variablen anderen Typs dereferenzieren will, muss man das L austauschen, genauso wie bei Str() und Val(). Man muss PokeL() dabei eine Adresse und einen neuen Wert übergeben. Mit PeekL() kann man ebenfalls einen Zeiger derefenzieren, erhält jedoch den Wert der Variable als Rückgabewert. Für das L von PeekL() gilt das Gleiche wie bei PokeL().