Yapý(Struct) Türünden Göstericiler

int,char,double gibi veri türleri aslýnda birer yapýdýr. Bu konun baþýnda bütün deðer tipleri ile gösterici tanýmlayabileceðimizi söylemiþtik. C# temel veri türlerinin yanýsýra kendi bildirdiðimiz yapýlar da deðer türündendir. O halde bir yapý göstericisi tanýmlayabilmemiz doðal bir durumdur. Yapý göstericilerinin tanýmlanmasý temel veri türlerinden gösterici tanýmlama ile aynýdýr. Ordaki kurallarýn tamamý yapýlar içinde geçerlidir. Fakat yapý göstericisi tanýmlamanýn bir þartý vardýr, oda yapýnýn üye elemanlarýnýn tamamýnýn deðer tipi olma zorunluluðudur. Örneðin aþaðýdaki yapý göstericisi tanýmlamasý geçersizdir.

using System;

struct Yapi
{
  
 int x;
  
 char c;
  
 string s;

   public Yapi(int x,char c, string str)
  
 {
  
    this.x = x;
  
    this.c = c;
  
    this.s = str;
  
 }
}

class StackAlloc
{
   unsafe static void Main()
  
 {
  
    Yapi yapi = new Yapi(2,'a',"Deneme");

      Yapi* pYapi = &yapi;
  
 }
}

Yukarýda 'Yapi' türünden göstericinin tanýmlanamamasýnýn sebebi yapýnýn yönetilen türden(managed type) bir üye elemanýnýn bulunmasýdýr. Bu üye elemaný da doðal olaral string türüdür. Yapý bildiriminden string türünü çýkarýp aþaðýdaki gibi ilgili deðiþiklikleri yaptýðýmýzda 'Yapi' türünden göstericileri tanýmlayabiliriz.

using System;

struct Yapi
{
  
 int x;
  
 char c;

   public Yapi(int x,char c)
  
 {
  
    this.x = x;
  
    this.c = c;
  
 }
}

class StackAlloc
{
   unsafe static void Main()
  
 {
  
    Yapi yapi = new Yapi(2,'a');

      Yapi* pYapi = &yapi;
  
 }
}

Yapý göstericileri üzerinden yapý göstericisinin adresine iliþkin nesnelerin elemanlarýna özel bir operatör olan -> operatörü ile eriþebiliriz. Örneðin yukarýdaki programýn Main() metodunu asaðýdaki gibi deðiþtirdiðinizde ekrana yapý nesnesinin x ve c elemanlarý yazdýrýlacaktýr. Tabi Yapi'nýn üye alamanlarýný public olarak deðiþtirmeniz gerekecektir. Çünkü ok operatörü ilede olsa ancak public olan elemanlara ulaþabiliriz.

unsafe static void Main()
{
   Yapi yapi = new Yapi(2,'a');

   Yapi* pYapi = &yapi;

   Console.WriteLine("yapi.x= " + pYapi->x);
   Console.WriteLine("yapi.c= " + pYapi->c);
}

Not: ' -> ' operatörüne ok operatörü de denilmektedir.

Yapýnýn public olan elemanlarýna ok operatörü yerine yapý nesnesinin içeriðini * operatörü ile elde edip nokta operatörü ile de ulaþabiliriz. Buna göre yukarýdaki Main() metodu ile asagidaki Main() metodu eþdeðerdir.

unsafe static void Main()
{
   Yapi yapi = new Yapi(2,'a');

   Yapi* pYapi = &yapi;

   Console.WriteLine("yapi.x= " + (*pYapi).x);
   Console.WriteLine("yapi.c= " + (*pYapi).c);
}

Her iki Main() metodunun ürettiði çýktý aynýdýr.

Göstericilerin en çok kullanýldýðý diðer bir uygulama alaný da karakter iþlemleridir. Bir yazýyý karekter dizisi olarak temsil edip yazýlar ile ilgili iþlemler yapýlabilir. C#' taki string türünün altýnda geçekleþen olaylarda zaten bundan ibarettir. Karakter dizileri ile ilgili en önemli nokta bir yazýyý char türden bir göstericiye atayabilmemizdir. Karekter dizileri olan stringlerdeki her bir karakter bellekte ardýþýl bulunmaktadýr. Dolayýsýyla yazýdaki ilk karakterin adresini bildiðimizde yazýdaki bütün karakterlere eriþebiliriz. C#'taki string türü yönetilen tip(managed type) oldugu için char türden bir göstericiye bir yazýnýn ilk karekterinin adresini atamak için fixed anahtar sözcüðünü kullanmalýyýz. Aþaðýdaki programda bir yazýnýn char türden göstericiye nasýl atandýðýný ve bu gösterici ile yazýdaki her karaktere ne þekilde eriþildiðini görüyorsunuz.

using System;

   class KarakterDizisi
   {
      
unsafe static void Main()
      {
        
 fixed(char* ptr = "Sefer Algan")
         {
            
for(int i=0; ptr[i] != '\0'; ++i)
               Console.Write(ptr[i]);
         }
      }
}

Buradaki en önemli nokta ptr[i]' nin '\0' karakteri ile karþýlaþtýrýldýðý yerdir. Göstericiler ile bellekte char türünün büyüklügü kadar ilerlerken yazýnýn nerede sonlandýgýný bilemeyiz. Bunun için

char* ptr = "Sefer Algan"

deyimi ile belleðe yerlestirilen 'n' karakterinden sonra null deðerini ifade eden '\0' karekter yerleþtirilir. Bu karektere rastlanýldýðý zaman yazýnýn sonuna gelmiþ bulunuyoruz.

Not: Göstericilerle ilgili yayýnlanan bu makale dizisi yazmýþ olduðum ve yakýnda Pusula yayýncýlýktan çýkacak olan C# kitabýndan alýnmýþtýr.