C# Yapılar (Struct)

Nesne tabanlı programlama beş veri tipini destekler. Bunlar Class, Struct, Enum, Interface ve Delegate tipleridir. Bu öğrenme faaliyetinde Yapı (struct) veri tipini ele alacağız.
Aralarında mantıksal bir ilişki bulunan ama farklı türdeki verilerin bir arada bulunması gereken durumlarla karşılaşılabilir. İşte bu durumlarda belli bir grup verinin bir arada tutulması için oluşturulan yeni birime yapı (struct) denir.
Yapılar değer türündedir. Dolayısıyla belleğin yığın (stack) bölümünde tutulurlar.
Bellek kullanım bakımından yığın (stack) ve öbek (heap) olmak üzere ikiye ayrılır.
Yığın bölümünde veriler üst üste gelecek şekilde depolanırlar. Yeni bir veri eklendiğinde bu belleğin en üst bölgesine yerleştirilir. LIFO (Last In First Out) mantığına göre çalışır. Yani son giren ilk çıkar. Verilere erişim basit olduğu için hızlıdır.
Öbek kısmında ise boş bir alan oluşturulur ve veriler rastgele yerleştirilir. Verilere erişim karmaşık olduğundan daha yavaştır.
Değer türleri belleğin yığın (stack) bölümünde tutulurken;referans türler belleğin öbek (heap) bölümünde tutulur. Örneğin sınıflar(class) referans türünde olduklarından dolayı belleğin öbek (heap) bölümünde tutulur.

 

Yapı (Struct) Tanımlama

Yapıları tanımlamak için ‘struct’ anahtar sözcüğünü kullanırız. Bir yapının genel tanımlanma şekli aşağıdaki gibidir.

[csharp]struct yapi-ismi
{
yapi-elemanlari-listesi;
}[/csharp]

Örnek :

[csharp]struct Ogrenci
{
int okulNo;
string ad, soyad;
}[/csharp]

Örnek :

[csharp]struct Ogrenci
{
public int okulNo;
public string ad, soyad;
}[/csharp]

1. bölümde içerisinde integer ve string tipinde üç tane değişken bulunduran bir yapı(struct) tanımladık.

[csharp]class Program
{
static void Main(string[] args)
{
Ogrenci yeniOgrenci = new Ogrenci();
[/csharp]

2. bölümde Ogrenci isimli yapıdan yeniOgrenci isimli yeni bir nesne oluşturduk.

[csharp] Console.Write(“Okul No giriniz : “);
yeniOgrenci.okulNo = Convert.ToInt16(Console.ReadLine().ToString());
Console.Write(“Ad Giriniz :”);
yeniOgrenci.ad = Console.ReadLine().ToString();
Console.Write(“Soyad Giriniz :”);
yeniOgrenci.soyad = Console.ReadLine().ToString();
Console.WriteLine(“——————–“);
Console.WriteLine(“Yeni Öğrenci Bilgileri”);[/csharp]

3. bölümde yeni oluşturduğumuz nesneye klavyeden değerler atadık.

[csharp] Console.WriteLine(“Okul No : {0}”, yeniOgrenci.okulNo);
Console.WriteLine(“Adı : {0}”, yeniOgrenci.ad);
Console.WriteLine(“Soyadı : {0}”, yeniOgrenci.soyad);
Console.ReadKey();
}
}[/csharp]

4. bölümde ise nesneye atadığımız değerleri ekrana yazdırdık.

Yapılar da sınıflar gibi metotlar, değişkenler, özellikler, yapıcılar vb. içerebilir.

[csharp] struct Dikdortgen
{
public int alanHesapla(int kisaKenar, int uzunKenar)
{
int alan = kisaKenar*uzunKenar;
return alan;
}
}
struct Kare
{
public int alanHesapla(int kenar)
{
int alan = kenar * kenar;
return alan;
}
}
class Program
{
static void Main(string[] args)
{
Dikdortgen dikdortgenAlan = new Dikdortgen();
Console.WriteLine(“Dikdortgenin Alanı : {0}”, dikdortgenAlan.alanHesapla(4, 5));
Kare kareAlan = new Kare();
Console.WriteLine(“Karenin Alanı : {0}”, kareAlan.alanHesapla(5));
Console.ReadKey();
}
}[/csharp]

Diktortgen ve Kare adında iki tane yapı (struct) tanımladık ve yapılar içinde alan hesabı yapan metot oluşturduk. Program içinde bu oluşturduğumuz yapılardan yeni nesneler türettiğimiz zaman bu yeni nesneler üzerinden metotlara erişim sağlayabiliyoruz. Şunu unutmamak gerekir ki metotlara erişim sağlayabilmemiz için public türünde tanımlanmaları gerekir.

Yapı ve Sınıf Arasındaki Farklar

Yapılar değer türünde olduklarından belleğin yığın (stack) bölümünde, sınıflar ise referans türünde oldukları için belleğin öbek (heap) bölümünde depolanırlar.

 

Değişken ve sınıfların bellek bölgesinde tutulma biçimleri

Değişken ve sınıfların bellek bölgesinde tutulma biçimleri

Sınıflar için varsayılan (default) yapıcı (constructor) metotlar yazılabiliyorken yapılarda bunu yapamayız. Fakat yapılarda parametreli yapıcılar tanımlayabiliriz. Burada dikkat edilmesi gereken nokta ise yapılarda tanımladığımız parametreli yapıcılara ilk değer ataması yapmak zorundayız. Sınıflarda ise buna gerek yoktur. Çünkü derleyici bizim yerimize ilk değer atamasını yapacaktır.

Örnek :

[csharp]class Dikdortgen
{
public int kisaKenar;
public int uzunKenar;

public Dikdortgen()//Varsayılan yapıcı metot
{
kisaKenar = 4;
uzunKenar = 5;
}
public int alanHesap()
{
int alan;
alan = kisaKenar * uzunKenar;
return alan;
}
}
class Program
{
static void Main(string[] args)
{
Dikdortgen dortgen = new Dikdortgen();
Console.WriteLine(dortgen.alanHesap());
Console.ReadKey();
}
}[/csharp]

Ekran çıktısı:
Alan Hesabı : 20

Yukarıdaki örnekte Diktorgen adında bir tane sınıf tanımladık. Bu sınıfa varsayılan yapıcı metot aracılığıyla kisaKenar ve uzunKenar değişkenlerine varsayılan bir değer atadık. Program içerisinde bu sınıftan yeni bir nesne türettiğimiz zaman bu değerler varsayılan olarak atanacaktır. Dikkat ettiyseniz alanHesap() metodumuza bir değer ataması yapmadığımız halde program doğru bir şekilde çalışmıştır.

[csharp]struct Dikdortgen
{
public int kisaKenar;
public int uzunKenar;
public Dikdortgen()
{
kisaKenar = 4;
uzunKenar = 5;
}
public int alanHesap()
{
int alan;
alan = kisaKenar * uzunKenar;
return alan;
}
}
class Program
{
static void Main(string[] args)
{
Dikdortgen dortgen = new Dikdortgen();
Console.WriteLine(“Alan Hesabı : {0}”, dortgen.alanHesap());
Console.ReadKey();
}
}[/csharp]

Aynı işlemi yapı (struct) kullanarak yapmaya çalışırsak aşağıdaki resimde görünen hatayı alırız. Hatanın sebebi,yapılarda parametresiz varsayılan yapıcı tanımlanamamasıdır.

Hata Penceresi

Hata Penceresi

Fakat yapılarda parametre alan yapıcı metotlar tanımlayabildiğimizi söylemiştik.

[csharp]struct Dikdortgen
{
public int kisaKenar;
public int uzunKenar;
public Dikdortgen(int m_kisaKenar, int m_uzunKenar)
{
}
}[/csharp]

Yukarıdaki tanımlamada yapıcı metoda ilk değer ataması yapmadığımız için yine hata ile karşılaşılacaktır.

[csharp]struct Dikdortgen
{
public int kisaKenar;
public int uzunKenar;
public Dikdortgen(int m_kisaKenar, int m_uzunKenar)
{
kisaKenar = m_kisaKenar;
uzunKenar = m_uzunKenar;
}
public int alanHesap()
{
int alan;
alan = kisaKenar * uzunKenar;
return alan;
}
}
class Program
{
static void Main(string[] args)
{
Dikdortgen dortgen = new Dikdortgen(4,5);
Console.WriteLine(“Alan Hesabı : {0}”, dortgen.alanHesap());
Console.ReadKey();
}
}[/csharp]

Ekran çıktısı:
Alan Hesabı : 20

  • Yapılarda sınıflar gibi türetme yapamayız. Bir sınıf tanımlarken bir başka sınıfı temel alan yani kalıtım yoluyla oluşturabiliyoruz fakat bir yapıyı bir başka yapıyı temel alarak oluşturamayız.
  • Yapılar işleri bittikleri zaman bellekten otomatik olarak silindikleri için yıkıcı metotları tanımlayamayız.

 

Kaynak: Megep Modülleri

Ahmet Şenlik

Kocaeli Üniversitesinde Bilgisayar Programcılığı okudum DGS ile 2016 yılında Sakarya Üniversitesi Bilgisayar mühendisliğini kazandım. Yazılımla uğraşmayı çok seviyorum bu alanda kendimi daha da geliştirmeyi düşünüyorum. Eğer siz de seviyorsanız bu işi devam edin başlamadıysanız başlayın başaracağınıza inanın. :)

You may also like...

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.