Delphi’de Pointer ve Referans

Çok çok seyrek yazar oldum, biliyorum 🙂 Euro 2016’da işler pek iyi gitmeyince bugün oturup bir şeyler yazmak istedim. Bu yazıda işin teorisinde fazla boğulmadan, sözel anlatımlara, şematik gösterimlere girmeden Delphi tarafında konuyu incelemek istiyorum.

Önce adresin ne olduğunu tanımlayıp başlayım: Ram’in her baytının bir adresi (sıra nosu/indisi) var. Bir değişkenin Ram’deki yerinin başlangıç baytının adresi de o değişkenin adresidir. Yani her değişkenin bir adresi var.

Bu adresleri tutan değişkenlere de işaretçi(Pointer) denir. Sözlük tanımını yaptık, pointer tanımlamayla başlayalım.

Pointer tanımlama:

var
  genelIsaretci   : Pointer;  //Her hangi bir şeyi işaret eder.
  integerIsaretci : ^Integer; //integer bir veriyi işaret eder.
  formIsaretci    : ^TForm;   //TForm nesnesi işaret eder.

Pointer tanımlarken işaretçimiz için tip önemsizse “Pointer” tipinden tanımlayabiliriz. ancak bir tipten değişken işaret edecekse ^tip şeklinde yani tipin başına ^ koyarak tanımlarız.

Değişkenin adresini almak, pointer’a atamak:
Bir değişkenin adresini almak için Addr(); metodunu kullanırız. Bu metod ile işaretçiye adresi atarız. Bu metodun alternatifi @ operatörüdür.

var
  genelIsaretci: Pointer;
  integerIsaretci: ^Integer;
  i: Integer;
begin
  //Addr metodu değişkenin adresini söyler.
  integerIsaretci:=Addr(i);

  //Adres almak için alternatif operatör. 
  integerIsaretci:=@i;

  //Genel işaretçiye her türden değişken adresini atayabiliriz.
  genelIsaretci:=Addr(i);

  //bir işaretçiden diğerine adres atamak.
  integerIsaretci:=genelIsaretci;
end;

Pointer’ın gösterdiği adresteki değer:
Operatör olarak yine ^ kullanırız. Fakat bu sefer işaretçi adının sonuna koyuyoruz. Bu operatör ile adresteki değere ulaşabiliriz. Ona atama yapabiliriz.

  //işaretçinin gösterdiği adresteki değeri değiştirmek için ^operatörünü işaretçi adının sonuna koyarak atama yaparız.
  integerIsaretci^:=10; 

Şimdi de TForm nesnesi ile bir örnek;

var
  genelIsaretci: Pointer;
  formIsaretci: ^TForm;
begin
  genelIsaretci:=Addr(Self); 
  formIsaretci:=genelIsaretci;
  formIsaretci^.Caption:='Ahmet Kürşat ÇAKIR';

  //Nesne pointerlarında bu operatörü kullanmak zorunda değiliz.
  formIsaretci.Caption:='Ahmet Kürşat ÇAKIR';
end;  

Nesne ile örnek verdim çünkü konunun “ve Referanslar” kısmını buradan bağlamak istedim. ^ operatörünü kullansak da, kullanmasak da oluyor kısmını referanstan sonra açıklayacağım.

Referans:

var
  formReferans: TForm;
begin
  formReferans:=Self;
  formReferans.Caption:='Ahmet Kürşat ÇAKIR';
end;  

E yine aynısı, evet. Aslına bakarsanız böyle bir dilde her şeye pointer kullanmanıza lüzum yoktur. Referans işleminde de arka planda pointer mantığı işler. Nesne değişkenleri içinde nesneyi değil, bir pointer gibi adresini tutuyor da diyebiliriz.
Şimdi yukarıda açıklayacağım dediğim kısma gelirsek. Referansları da pointer’a benzettik. Dolayısıyla referanslarla çalışırken de sürekli ^ gibi operatörler kullanmamız gerekirdi. Bu hem gereksiz operatör kalabalığına neden olurdu, hem de kod yazarken kafa karıştırıcı ve yorucu olurdu. Bu nedenle referanslar tasarlanırken bu işlemleri programcı değil arkaplanda derleyici takımı yapacak şekilde tasarlanmıştır. Referansların bu tasarımından sonra da pointerlarda da bu operatör zorunlu tutulmamıştır.

Bir dahaki yazılarda görüşmek üzere, hoşçakalın..

Tags: , , , , , , , ,

No comments yet.

Leave a Reply

*