Startsidan  ▸  Texter  ▸  Teknikblogg

Anders Hesselbom

Programmerare, skeptiker, sekulärhumanist, antirasist.
Författare till bok om C64 och senbliven lantis.
Röstar pirat.

Pekare

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

Leave a Reply

Your email address will not be published. Required fields are marked *



En kopp kaffe!

Bjud mig på en kopp kaffe (20:-) som tack för bra innehåll!

Bjud på en kopp kaffe!

Om...

Kontaktuppgifter, med mera, finns här.

Följ mig

Twitter Instagram
GitHub RSS

Public Service

Folkbildning om public service.

Hem   |   linktr.ee/hesselbom   |   winsoft.se   |   80tal.se   |   Filmtips