Programmerare, skeptiker, sekulärhumanist, antirasist.
Författare till bok om C64 och senbliven lantis.
Röstar pirat.
2014-03-07
En pekare håller reda på ett objekts plats i minnet. Otypade pekare deklareras med typen Pointer, medan typade pekare deklareras med inledande caret (^) vid typnamnet. I detta exempel är a en integer och b en integer-pekare.
var a : integer; b : ^integer;
Värdet som lagras i en pekare är minnesadressen till ett objekt. Variabeln b kan alltså hålla minnesadressen till en integer. För att få minnesadressen till ett objekt, används @. Detta exempel tilldelar adressen av a till b.
a := 10; b := @a;
Om man försöker läsa av b, får man adressen till a. Syftet med att läsa av b kan t.ex. vara att låta en ny pekare peka på a. Om man istället vill läsa av värdet som finns i variabeln som b pekar på, används caret som postfix. Detta ger svaret 10, eftersom b hänvisar till a som innehåller värdet 10.
writeln(b^);
Om ett värde tilldelas till b^ lagras det i a, eftersom b pekar på a.
b^ := 50; writeln(a);
Funktionspekare benämns procedural types. Variabeln måste vara deklarerad med exakt samma signatur (parametrar och retur) som funktionen den pekar på. Följande exempel använder funktionen sum i en unit som heter Unit1.
unit Unit1; interface function sum(a, b: integer): integer; implementation function sum(a, b: integer): integer; begin result := a + b; end; end.
En pekare som kan peka på funktionen sum måste ta två integers och ge en integer. Detta exempel deklarerar en kompatibel pekare (s), samt anropar funktionen sum direkt, och via pekaren.
var s : function(x, y : integer) : integer; begin writeln(sum(10, 20)); s := sum; writeln(s(20, 30));
För tydlighetens skull, kan man uttryckligen skriva att man läser av adressen till sum, genom att använda prefixet @.
s := @sum;
Om funktionen sum istället vore en medlemsfunktion, behöver pekaren både hålla adressen till objektet och till medlemsfunktionen. Denna förändring i Unit1 placerar funktionen sum i klassen test.
unit Unit1; interface type test = class public function sum(a, b: integer): integer; end; implementation { test } function test.sum(a, b: integer): integer; begin result := a + b; end; end.
Nu deklareras pekaren med tillägget of object.
var t : test; s : function(x, y : integer) : integer of object; begin writeln(t.sum(10, 20)); s := t.sum; writeln(s(20, 30));
För att skicka en funktion som parameter, måste funktionen deklareras som en typ. Så här ser en typ som beskriver funktionen sum ut:
type sumtype = function(a, b : integer): integer of object;
Med denna typ på plats, kan deklarationen av pekaren kortas ner från detta:
s : function(x, y : integer) : integer of object;
…till detta:
s : sumtype;
Typen sumtype kan användas som parametertyp, så att funktionen sum kan skickas som parameter.
function call_sum(x: sumtype): integer; begin result := x(10, 20) + x(30, 40); end;
Ett anrop kan se ut så här:
var t : test; s : sumtype; begin s := t.sum; writeln(call_sum(s));
Categories: Delphi
Bjud mig på en kopp kaffe (20:-) som tack för bra innehåll!
Leave a Reply