write etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
write etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

26 Aralık 2010 Pazar

Decimal Veri Tipi

Untitled Document
Bazı programlama dillerinde değişkenlerin kullanımı veri tiplerine bağlı olmayabilir. Basic dili böyle idi. Bazı dillerde ise türlerin tanımlanması ve doğru karar verilmiş olması gerekir. Bir türün diğer bir türe dönüştürülmesi bizzat programcı tarafından açık olarak yapılmalıdır. Bu yüzden, Basic programlama dilinde veri tipleri üzerindeki kontrollerin artması en önemli gelişmelerden birisi olmuştur.

Programcılarının değişkenler için veri tiplerini seçmesi gerekir. Tamsayı olmayan sayılar için C# programlama dili floating point ve decimal olmak üzere iki ayrı alternatif sunar. Decimal veri tipi diğer dillerde olmayan farklı bir veri tipidir.

Gerçek sayılar için decimal veya floating point türünde değişken kullanmamız gerekir. Bilimsel veya mühendislik uygulamaları için tanımlanacak değişkenler için floating point veri tipi kullanılır. Floating point veri tipi çok büyük ve çok küçük sayılar için kullanılır. Bazı durumlarda, floating point türü kullanıldığında çok küçük hatalı sonuçlar oluşabilir. Decimal veri tipi kesin sonuçlar verdiği için floating point kadar esnek değildir.

Decimal veri tipi, System.Desimal sınıfından türetilir. Kullanımı:

decimal cebimdekiPara;

Eğer cebinizde bozuk para yok ise decimal tipinde değişken kullanabilirsiniz.

cebimdekiPara = 70;

E?er bozuk paranız da varsa, şu şekilde kullanmak isterseniz:

cebimdekiPara = 70.25; //Problem olabilir.

Karışıklığa mahal vermemek için sonuna M veya m eklemeniz gerekir.

cebimdekiPara = 70.25m; //Düzgün çalışacaktır

Aşağıdaki programı inceleyelim.

//--------------------------------------------------

//biletHesabi.cs

//--------------------------------------------------

using System;

class biletHesabi

{

static void Main()

{

const decimal yuksekFiyat = 12.50m, dusukFiyat = 8.25m;

Console.Write(""Pahaly bilet fiyatını giriniz: "");

int pahaliBiletSayisi = Int32.Parse(Console.ReadLine());

Console.Write(""Ucuz bilet fiyatını giriniz: "");

int ucuzBiletSayisi = Int32.Parse(Console.ReadLine());

decimal toplamFiyat = pahaliBiletSayisi * yuksekFiyat + ucuzBiletSayisi * dusukFiyat;

Console.WriteLine(""Toplam fiyat:"" + toplamFiyat + "" YTL"");

}

}

Gördüğünüz gibi, decimal sayıları ve tamsayıları aynı ifade içinde kullanabiliyoruz. C# herhangi bir tamsayı değişkeni decimal türüne çevirebilir. Decimal değerler ve tamsayı değerler arasındaki hesaplama sonucu decimal değerdir. Fakat C#, decimal tipleri tamsayı tipine dönüştürmez.

decimal toplamPara = 54.25m;

int para = toplamPara; //Derleme Hatası

C# derleyicisi bu şekildeki çevirmeyi önlemektedir. Decimal veri tipinden tamsayı veri tipine çevirmede kayıp oluşabilir.

casting işlemi yaparak decimal tipte bir sayıyı kayıplarla birlikte tamsayı türüne dönüştürmek mümkündür.

int para = (int)toplamPara;

Bir bilme işlemin sonucunun decimal olabilmesi için işlem yapılacak sayılardan en az birisinin decimal olması gerekir, ya da decimal türüne dönüştürülmesi gerekir.

int a = 25, b = 10;

decimal c = a/b; //sonuc 2 çykacaktyr.

Çünkü bir tamsayının diğer bir tamsayıya bölünmesi sonucu bölüm yine bir tamsayıdır. İşleme giren sayılardan birisini açık dönüştürme ile decimal sayıya dönüştürelim.

int a = 25, b = 10;

decimal c = (decimal) a/b; //sonuc 2.5

Çıkan sonucu yuvarlamak isteyebiliriz. Bunu da kaç basamak yuvarlayacağımızı belirterek yapabiliriz.

decimal x = 25.77m;

decimal y = .05m;

decimal sonuc = x * y; // sonuc 1.2885

decimal yuvarlanmis = decimal.Round(sonuc, 2); //yuvarlanmis = 1.29 olur.


Sabitler

Şimdi bir sinema bileti programı yazalım. Normal bilet ve öğrenci bileti için ayrı ayrı fiyat seçenekleri olsun. Program sinemaya gidince ödeyeceğimiz toplam tutarı bulsun.

using System;
class SinemaBileti
{
static void Main()
{
int TamBilet = 10, OgrenciBileti = 7;
Console.Write("Kaç tane tam bilet: ");
int TamBiletSayisi = Int32.Parse(Console.ReadLine());
Console.Write("Kaç tane öðrenci bileti: ");
int OgrenciBiletiSayisi = Int32.Parse(Console.ReadLine());
int ToplamTutar = TamBiletSayisi * TamBilet +
OgrenciBiletiSayisi * OgrenciBileti;
Console.WriteLine("Toplam tutar (YTL)" + ToplamTutar);
Console.ReadLine();
}
}

Yukarıdaki programda 5 tane değişken var. 2 tanesi ilk değer almış ve 2 tanesi kullanıcıdan isteniyor ve 1 tanesi de hesaplama sonucu oluşuyor.

İlk değer ataması yaptığımız 2 değişkene bir de başka açıdan bakalım.

Bu 2 değişkeni hiç kullanmasak ve programı aşağıdaki gibi değiştirsek yine aynı işlevi yerine getirir.

using System;
Class SinemaBileti
{
static void Main()
{
//int TamBilet = 10, OgrenciBileti = 7;
Console.Write("Kaç tane tam bilet: ");
int TamBiletSayisi = Int32.Parse(Console.ReadLine());
Console.Write("Kaç tane öðrenci bileti: ");
int OgrenciBiletiSayisi = Int32.Parse(Console.ReadLine());
//int ToplamTutar = TamBiletSayisi * TamBilet +
// OgrenciBiletiSayisi * OgrenciBileti;

int ToplamTutar = TamBiletSayisi * 10 + OgrenciBiletiSayisi * 7;
Console.WriteLine("Toplam tutar (YTL)" + ToplamTutar);
Console.ReadLine();
}
}

Aralarında bir fark yok ama bu yeni şekilde 10 ve 7 değerleri birer sayı ve isimleri yok. Belki yorum satırları eklesek yardımcı olur. Eğer yorumlar olmazsa bir vakit sonra birisi sizin yazdığınız koda bakar ve “bu sayılar da ne?” der. Hatta bu kişi siz bile olabilirsiniz. Yazdığımız kodun okunurluğunu ve anlaşılırlığını kaybetmesi çok kötü bir durumdur.

Diğer yandan, kullanıcının bilet fiyatlarını kendisinin girmesine izin de vermek istemiyoruz. Aslında aşağıdaki gibi yapabilirdik.

Console.Write("Tam bilet fiyatýný gir: ");
int TamBilet = Int32.Parse(Console.ReadLine());

Bilet fiyatlarının programın kaynak kodunda bulunmasını istiyoruz. Pogramın kodlarının içerisine değerleri yazmak en iyi çözüm değil. Bilet fiyatları değiştikçe kodu açıp değiştirip tekrar derlememiz lazım. Eğer sadece kendimiz kullanacaksak problem yok. Ama kodu değiştirip tekrar derledikten sonra yeni programı bütün kullanıcılara tekrar göndermek, yüklemek büyük problemler.

Kodu yeniden derlemektense, diskte bir dosyada tutmak ve gerektiğinde yeniden programı derlemeden sadece o dosyayı değiştirmek güzel bir çözüm. Bu işlerin nasıl yapılabileceğini başka yazılarda anlatacağız. Şimdilik bu değişkenleri kodun en üstüne koyalım, program açılır açılmaz değiştirilmesi kolay olsun.

Program kodlarının en üstünde aşağıdaki gibi iki ücret tanımlaması var.

int TamBilet = 10, OgrenciBileti = 7;

Ama programın sonlarına doğru aşağıdaki gibi bir kod bloğu gördüğünüz düşünün.

TamBilet = 12;
OgrenciBileti = 9;

Bilet fiyatları değişmiş. Muhtemelen siz değiştirdiniz ama yorum cümlesi eklemeyi unuttunuz.

Bunun gibi bir programda TamBilet ve OgrenciBileti fiyatlarının değişken olmaması gerekiyor. Sadece bir tek değere sahip olmaları ve program boyunca da değiştirilememeleri gerekiyor. Diğer bir deyişleTamBilet ve OgrenciBileti değişken değil de sabit olmalıdır.

Sabitleri başlarına const yazarak tanımlarız.

const int TamBilet = 10;

Const int OgrenciBileti = 7;

Bir tanımlama ifadesinde const kullandıktan sonra artık TamBilet ve OgrenciBileti için değişken değil de sabit ifadesini kullanmak daha doğru olacaktır, TamBilet ve OgrenciBileti sabitleri.

Sabitlerin değişkenlerden ne farkı olduğunu inceleyelim. Tanımlama işlemini yaptıktan sonra değerini değiştirmeye çalıştığınız zaman derleme hatası ile karşılaşırsınız.

TamBilet = 12;

Eğer programın bir yerlerinde yukarıdaki gibi bir ifade kullanırsanız C# derleyicisi size aşağıdaki hata mesajını verecektir.

The left-hand side of an assignment must be a variable, property, or indexer.

(Bir atama ifadesinin sol tarafında bir değişken, özellik ya da indeksleyici bulunmalıdır.)

Ve TamBilet yukarıda sayılanlardan hiç birisi değildir. Gerçekte bir değişken değil, sabittir. Böyle bir derleme hatası aldığınız durumda, kendinize sormalısınız: “Acaba programın ilerleyen bölümlerinde değiştirmek isteyeceğim bir şeyi sabit olarak mı tanımladım?” ya da bu örnekte olduğu gibi “Acaba bir sabit tanımladım ama programın ilerleyen bölümlerinde yanlışlıkla değerini mi değiştirmeye çalıştım?” diye.

Bir sabit tanımladığınız zaman ona bir değer ataması da yapmalısınız.

const int TamBilet; // Derleme hatasý!

Eğer yapmazsanız aşağıdaki hata mesajını görürsünüz.

A const field requires a value to be provided.

(Sabit bir alan için bir değer tanımlamanız gerekiyor.)

Program boyunca değeri değişmeyecek olan bir değişken sabit olmaya adaydır. Sabit tanımlamak sadece programcının değer değiştirmek suretiyle hata yapmasını önlemez, aynı zamanda programın performansını da artırır. Derleyici sabitlerin sakladığı değerleri stack bölgesinde oluşturmak durumunda kalmaz. Eğer TamBilet ve OgrenciBileti değerlerini saklamak için sabit tanımlarsanız, derleyici ToplamTutar değerini ilk yaptığımz örnekte olduğu gibi değil de ikinci örnekteki gibi hesaplar.

Sabitleri tanımlarken sadece literaller değil ifadeler de kullanabilirsiniz.

const int TamBilet = 10;
const int OgrenciBileti = 3 * TamBilet / 4;

OgrenciBileti, TamBilet değeri ile yapılan bir takım matematiksel hesaplamalardan sonra ortaya çıktı. TamBilet değerini değiştirerek OgrenciBileti değerini de değiştirebilirsiniz. Bu durumda TamBilet, OgrenciBileti’nden önce tanımlanmış olmalıdır. Yukarıdaki örnekte de olduğu gibi, bir sabite değer ataması yaparken başka bir sabitin değeri kullanılabilir ama değişken kullanılmaz.

Yorum Cümleleri adlı yazımızda geçen örneği hatırlarsak eğer, aşağıdaki gibi bir ifade vardı.

haftalikUcret = 80 * GunSayisi;

Bu örnekteki 80 sayısının ne için orada bulunduğunu kestirmek zor. Açıklayıcı bir isimle değiştirilse daha iyi olur. Yorum Cümleleri adlı yazımızda bir değişkenle değiştirmiştik. Fakat sabir kullanmak daha doğru bir karardır.

const int GunlukUcret = 80;

haftalikUcret = GunlukUcret * GunSayisi;

Sabit kullanmak ifadeyi daha anlaşılır yaptı, ama daha da anlaşılır yapabiliriz.

Sabit ifadeyi değerini açık hesaplamalar şeklinde yazarak da tanımlayabiliriz.

const int GunlukUcret = 8 * 10; //Günde 8 saat çalýþýldýðýný varsaydýk.

Yukarıdaki çarma işlemi derleme esnasında yapıalcağı için programnı çalışmasında da bir performans kaybı olmayacaktır.

Bir sabitin değeri program derlenirken belli olmak zorundadır. Meselâ,

const string Prompt = "Adýnýzý giriniz: ";

Promt bir sabit olduğu için başka bir string ifade ataması yapılamaz. Fakat şu şekilde bir stringi bir sabite atayamazsınız.

const string Response = Console.ReadLine();// Olmaz.

ReadLine çağrısı çalışma esnasında oluşur, derleme esnasında değil. Derleme esnasında değeri belirli olan bir şeyi ancak bir sabite atayabilirsiniz.

23 Aralık 2010 Perşembe

Konsol Ekranında Veri Girme

KONSOLDAN VERİ GİRMEK

Programlar çoğu zaman bizim girdiğimiz verilere göre işlemlerini yürütürler. Daha önce, görsel programlarda fare hareketleri ile, butonlara tıklamalarla veya yazı kutularına klavyeden bir şeyler yazarak veri girişi yaptık. Veri girişlerinin klavye veya fare ile yapıldığını bu nedenle biliyoruz zaten.

C# konsol uygulamalarında veri girişi daima klavyeden yazı yazma ile gerçekleşir. Genellikle konsol uygulamalarında program kullanıcıdan bir şeyler girmesini ister ve kullanıcının verdiği yanıta göre kullanıcının ne demek istediğini anlamaya çalışır.

İşte bizim konsolda klavyeden giriş yapmamızı sağlayan Console sınıfının Read ve ReadLine yöntemleridir. Console.WriteLine ve Console.Write yöntemlerini kullanırken giriş argümanlarını yazmamız gerekiyordu. Ve bu yöntemlerden dönen bir argüman yoktu. Console.Read ve Console.ReadLine yöntemlerinde ise giriş argümanı yok ama bu yöntemlerden dönen dönüş argümanları mevcut. Biz bu iki yöntemi içeren bir program yazdığımızda ve bu yöntemleri çağırdığımızda kontrol biz Enter tuşuna basana kadar programa tekrar geçmeyecektir. Buradan da bu iki yöntemin ve dolayısı ile programın çalışmaya devam edebilmesi için bu yöntemlerin çağrıları yapıldıktan sonra Enter tuşuna basmamız gerektiğini anlıyoruz. Bu arada Console.ReadLine yönteminin bu iki yöntem içinde kullanımı kolay olan yöntem olduğunu söyleyebiliriz. Şimdi konsoldan string girişi yapan ilk programı yazalım.

1string yazi;
2yazi = Console.ReadLine();

Yukarıda görüldüğü gibi 1. satırda string tipinde bir değişken tanımlandı ve ikinci satırda Console.ReadLine() yöntemi çağrılarak yazı adlı stirng değişkene bu yöntemden dönen ( kullanıcının konsol ekranında yazdıkları ) değerler atandı. Burada dikkati çeken bir noktada Console.ReadLine yönteminden dönen değerin string bir değişken herhangi bir işleme tabi tutulmadan direkt olarak atanabildiğidir.

Burada iki satırda yaptığımız işlemi tek satırda da gerçekleştirebilmemizin mümkün olduğunu biliyoruz.

1string yazi = Console.ReadLine();

Şimdi kullanıcıdan bir şeyler alan bir program yazalım.

1using System;
2class KonsoldanVeriGirisi
3{
4static void Main()
5{
6Console.Write("Bir şeyler yaz ve Enter tuşuna bas:");
7string yazi = Console.ReadLine();
8Console.WriteLine("Klavyeden yazdığınız yazı:" + yazi );
9}
10}

Yukarıdaki programda kullanıcıdan bir şeyler yazmasını istedik ve bu yazdıklarını bir string değişkene Console.ReadLine yöntemi ile atayarak daha sonra bu değişkeni Console.WriteLine yöntemi ile konsolda görüntüledik. Burada dikkat edilirse ilk satırda Write yöntemi kullanıldı çünkü kullanıcının yazdıklarının bizim Console.Write yöntemi ile konsola yazdırdığımız yazıların yanına yazılmasını istedik. Kullanıcı bir şeyler yazıp Enter tuşuna bastığında Console.ReadLine yöntemi imlecin aşağı satıra düşmesini sağlıyor. Tam bu sırada Console.ReadLine yöntemi değer döndürme işlemini gerçekleştiriyor.

Console.WriteLine ve Console.Write yöntemleri bir integer değişkeni kapalı bir şekilde string tipine dönüştürerek konsola yazdırıyordu. Ama Console.ReadLine yönteminin böyle bir özelliği mevcut değil. Yani biz klavyeden bir integer okumak istediğimizde bunu Int32.Parse yöntemini kullanarak integer tipine çevirmemiz gerkiyor.

1using System;
2class KonsoldanVeriGirisi
3{
4static void Main()
5{
6string S;
7int I;
8Console.Write("Bir sayı yaz ve Enter tuşuna bas:");
9S = Console.ReadLine();
10I = Int32.Parse( S );
11Console.WriteLine(“Girdiğin numara:” + I );
12}
13}

Yukarıdaki programda iki durumdan söz edebiliriz. Birincisi; Console.ReadLine yönteminden dönen değerin bir string olması ve string değişkene doğrudan atanabilmesi. İkincisi ise; bu string değişkenin Int32.Parse yöntemi ile integer bir değişkene aktarılması.

Ayrıca buradaki S string değişkenini Console.ReadLine ve Int32.Parse yöntemlerini birleştirerek ortadan kaldırabiliriz.

1I = Int32.Parse(Console.ReadLine());

Bu satırda ilk olarak Console.ReadLine yöntemi çağrılıyor ve konsoldan girilen yazıları okuyor. Daha sonra okuduğu değerleri Int32.Parse yöntemine aktarıyor.

Şimdi kullanıcıdan sayı almayı bildiğimize göre gerçek hayata yakın bir program yazabiliriz.

1using System;
2class Bilet
3{
4static void Main()
5{
6int YetiskinUcreti = 10 , CocukUcreti =7 ;
7
8Console.Write("Yetişkin bilet adedini giriniz:");
9int YetiskinBiletSayisi = Int32.Parse(Console.ReadLine());
10
11Console.Write("Cocuk bilet adedini giriniz:");
12int CocukBiletSayisi = Int32.Parse(Console.ReadLine());
13
14int ToplamMaliyet = YetiskinUcreti * YetiskinBilet

Değer Tip & Referans Tip

Değer-Tip & Referans-Tip (Value-Type & reference-Type)

Yüksek seviye dillerin bir iyi tarafı da, bilgisayarın arka planda nasıl çalıştığı konusunda programcının bilgi sahibi olmasına gerek kalmamasıdır. Ama bazen bilmekte de yarar var. Mesela bellekte değişkenlerin nasıl saklandığını bilmek isteyebilirsiniz. Program çalışırken değişken için bellekte değişkenin türüne göre yer ayrılır ve değişkene ihtiyacımız kalmadığında ise belleğin o bölgesi serbest bırakılır.

Bir yöntem çalışmaya başladığı zaman, içerisindeki bütün değişkenler için bellekte yer ayrılır. Bu yere stack denir. Yöntemin kullanımı sona erdiği zaman ise belleğin o bölgesi serbest bırakılır.

Şöyle bir örnek düşünelim :

int A,B;

long C;

string D;

Stack bölgesinde A ve B için 4’er byte, C için 8 byte yer ayrıldı. Peki D için ne kadar yer lazım? Bu miktar, string türündeki D değişkeninin ne kadar uzun olacağına bağlıdır. Bir string ifade çok kısa da olabilir, çok uzun da. Bu yüzden string değişkenlerin boyutu değişkendir.

Eğer string türü bir değişkene sabit bir ifade atanmışsa, boyut sabit olarak düşünülebilir. Eğer değişkenin içeriği kullanıcıdan istenen bir değer ise, veya dosyadan okunan ya da internetten alınan bir ifade ise boyutunu program çalışana kadar bilemeyiz.

Bu yüzden, string ifadeler, stack bölgesinde saklanmaz. Program çalışırken, string ifade için gereken yer heap adı verilen bölgede oluşturulur. Heap bölgesi, program çalışırken, ayırma ve serbest bırakma işlemleri yapmayı olanaklı kılan genel amaçlı bir bölgedir.

Yalnız stack ve heap bölgeleri hakkında bilinmesi gereken diğer bir gerçek var. Yukarıdaki kod bloğundaki D değişkeninin kendisi stack bölgesinde saklanır, heap bölgesinde bir alana referans içerir. D değişkeninde tutacağımız string ifadenin kendisi ise ilgili referansın gösterdiği heap bölgesindedir. Heap bölgesindeki string ifade programın akışı sırasında küçülebilir ya da büyüyeblir ama stack bölgesindeki referansı barındıran alan sabittir.

Referans derken neyi kastettiğimize biraz bakalım. Belleğin her bir hücresi numaralandırılımıştır ve bu numaralara bellek adresi denir. Program, bir bellek bölgesine erişmek isterse bu numaralardan yararlanır. Bir bellek bölgesine referans içermek demek o bölgenin adresini tutumak demektir. Yapısal programlama ile uğraşmış olanlar bunun işaretçi (pointer) demek olduğunu bilirler. Peki, içinde referans tutan bir değişken stack bölgesinde ne kadar yer kaplar? Günümüz yaygın işletim sistemleri 32-bit olduğuna göre 32 bit yani 4 byte yer kaplar.

Şimdi string ifade tutan bir değişken bellekte ne kadar yer kaplar sorusunun cevabını da bulmuş olduk. Değişkenin kendisi stack bölgesinde 4 byte yer kaplar ama string ifadenin kendisi heap bölgesinde değişken bir yere sahiptir. Kapladığı alan içeridği ifadenin boyutuna göre değişir.

Değer-Tip & Referans-Tip (Value-Type & Reference-Type)

Yeri gelmişken referans-tip nedir, değer-tip nedir sorusuna da cevap arayalım. C#’ta yapılar değer-tiptirler. Sınıflar ise referans-tip. Bunun ne anlama geldğini anlamak için, biraz açalım.

Aslında bir çok değer tipi daha önce kullandık. Bütün tamsayı türler .Net Framework içerisindeki yapıların aliaslarıdır. Tamsayı türdeki bir sayının gerçek değeri stack bölgesinde saklanır.

Sınıflar ise referans-tiplerdir. string veri tipi, Syste.String sınıfının bir aliasıdır. Yani bir sınıftır. Sınıf da referans-tiptir. Bir referans tip, heap bölgesinde bir alanı gösteren bir referans olarak stack bölgesinde saklanır.

Yapılar değer-tiptirler. Sınıflar referans-tiptirler. Bir yöntemin aşağıdaki tanımlamayı içerdiğini düşünün şimdi.

string Ad;

Yöntem çalışmaya başladığında, stack bölgesinden 4 byte’lık yer ayrılır. Bu yerde, heap bölgesinden bir alana referans barındırılabilir. Ama Ad değişkenine bir değer ataması yapılmadığı müddetçe heap bölgesinden bir alan tahsisi yapılmaz.

Şimdi bir değer atayalım.

Ad = "Ali";

Heap bölgesinde string ifade sığacak kadar yer ayrıldı ve artık stack bölgesindeki yerimiz heap bölgesinde string ifadeyi barındıran alanın adresini tutuyor, yani o bölgeye referans tutuyor.

Bir string değişkene aşağıdaki gibi hiçbir şey atamak istemezsek ne olur, inceleyelim.

Ad = " ";

Şu anda hiçbir karakter içermiyor ama bir atama işlemi söz konusu olduğu için heap bölgesinden yer tahsisi yapılır.

Ad.Length ifadesinin değerini ekrana yazdırırsak 0 göreceksiniz. bu da heap bölgesinde yer içeriği boş olan bir yer ayrıldığını gösteriyor.

Çöp Toplama (Garbage Collection)

Bir string türü değişkenin değerini değiştirip heap bölgesinde bir yere referans içermemesini sağlayabiliriz. Bunu da

Ad = null;

atamasıya yaparız. Biz bunu yaptığımız zaman ya da

Ad = "Veli";

gibi başka bir değer ataması yaptığımız zaman, ilk atadığımız “Ali” ifadesi hala heap bölgesinde mevcuttur ama hiçbir referans onu göstermediği için ulaşılamaz haldedir. Bu şekilde artık kullanımı biten verileri heap bölgesinden temizleyen ve o bölgeleri kullanılabilir hale getiren çok güzel bir yapı barındırır C# ve CLR (Ortak Dil Çalışma Zamanı) : Çöp toplama (Garbage Collection). Programcı işi biten bölgeleri temizleme derdinden kurtulmuştur. Çöp Toplayıcı bunu programcının yerine yapar.

Heap bölgesinde hiçbir yere referans içermeyen yani null bir string değişkenin uzunluğunu bulmak için

Ad.Length

ifadesinin değerini öğrenmeye çalışırsak aşağıdaki istisna oluşur.

1

Yukarıda anlatıldığı gibi, null string ile boş bir string aynı gibi görünse de aynı değildir. Bir string null’a eşitse, stack bölgesinde saklanan değer 0’a eşittir ve heap bölgesinde hiçbir yere referans içermez. Eğer bir string, boş bir string’e eşitse stack bölgesinde saklanan değer heap bölgesinde bir bölgeye referans ifade eder. Heap bölgesinde de uzunluğu 0 olan bir string için yer ayırma işlemi yapılmıştır.


19 Aralık 2010 Pazar

Ekrana Yazı Yazdırma

Untitled Document

Ekranda Yazı Yazdırmak

19 Şubat 2007

Program yazmanın iki boyutundan bahsedebiliriz, bunlar ise programcı açısından program ve kullanıcı açısından programdır. Program geliştiriciler olarak başlangıçta her iki kişi de biziz. Rolümüz programcıdan kullanıcıya değişince ya da kullanıcıdan programcıya değişince, bakış açımız da değişecektir. Mesela, programımızın verdiği çıktı, kullanıcı açısından girdidir. Kullanıcının programa girdiği veriler program açısından girdi, kullanıcı açısından çıktıdır.

Burada bahsedilen girdi ve çıktı kavramları üzerinde durmak istiyorum. Programın dış dünyaya verdiği bilgiler, gösterdiği tepkiler çıktı olarak tanımlanırken, dış dünyadan aldığı bilgiler ise girdi olarak tanımlanır. Bir bilgisayar programı da aldığı girdileri yorumlar, saklar, bu bilgilere dayanarak dış dünyaya bir takım sonuçlar gönderir. Bu modele I/O modeli denir.

I/O Modelleri

Windows ortamında çalışan bir program kullanıcıdan girdileri klavye, mouse, buton ya da kaydırma çubukları gibi çeşitli kontroller yardımı ile alır. Bir Windows programı çıktıyı kullanıcıya yazı veya grafik olarak gösterir. Bir fırını çalıştıran program ise farklı bir kullanıcı I/O modeline sahiptir. Burada girdiler fırınını ön panelindeki butonlarla yapılır. Çıktılar ise fırının açılması, fırının kapanması, tepsinin döndürülmesi, ışığın yakılması şeklinde olacaktır. C ve C# gibi dillerde kullanıcı girdi ve çıktısı için özel bir model yoktur. Bu bir eksiklik gibi görünüyor fakat değil. Bunu şöyle söylemek daha doğru olacaktır: C#, kullanıcıyı herhangi bir girdi ve çıktı modelini kullanmaya zorlamaz. Siz yazdığınız programın nerede kullanılacağına göre girdi ve çıktı modelinizi kendiniz seçersiniz.

Bu bölümde konsol ekranı yardımıyla kullanıcıya çıktı verebilen bir program yazmaya çalışacağız. Bunu yapmadan önce bazı kavramları açıklamakta yarar var. Ekranda yazı göstermeye yarayan System.Console.WriteLine() ve System.Console.Write komutlarıdır. Bu komutlar neden üç parçadan oluşuyor? Bu parçaların adları nelerdir?

System bir isimuzayıdır. İsimuzayları C#’a C++ dilinden miras kalmıştır. İsimuzayları birbiri ile alakalı yöntemleri bir paket içinde toplamaya yarayan bir paketleme sistemidir. Bir isimuzayının içindeki bir yöntemin adı diğer bir isimuzayı içinde de bulunabilir. Bu da isimuzayının bir diğer işlevidir.

System isimuzayı; kullanıcı ile iletişim kurmaya yarayan I/O modeli olan Console, matematiksel işlemlerin bir araya toplandığı Math gibi temel sınıfları içinde barındırır. Burada sınıf terimi geçti. Bir önceki bölümde de anlattığımız gibi, C# programının temel birimi sınıftır. Bunu daha doğrusu şöyle söylemek lazım: Nesne yönelimli dillerin temel birimi sınıftır. Sınıfların özellikleri ve yöntemleri vardır. Bir arabayı örnek alalım. Rengi, modeli fiyatı gibi özellikleri vardır. Hareket etmek, korna çalmak, durmak gibi yöntemleri vardır. Daha sonra bu temel araba sınıfından bir takım farklı özellik ve yöntemlere sahip olan otobüs, kamyon, minibüs gibi sınıflar türetiriz. Bu sınıfların örnekleri olan nesneler ise araba sınıfının niteliklerini taşırlar. Türetilmiş sınıftan oluşturulan nesne de türetilmiş sınıfın özelliklerini ve temel sınıfın özelliklerini taşır.

Yöntemler ise sınıfın dış dünya ile etkileşimini sağlayan eylemleridir. Mesela Console sınıfının WriteLine yöntemi ekranda bir satır yazı gösterir. Write yöntemi ise ekranda yazı gösterir ama alt satıra geçmez işini bitirince.

WriteLine yöntemini kullanan bir program bu yönteme bir argüman yollar:

1System.Console.WriteLine(ToplamMeyve);

Bazı programcılar parantez ile argümanı ayırmak için argümanın sağına ve soluna boşluk koymayı tercih ederler.

1System.Console.WriteLine( Toplam );

WriteLine yöntemine bir değişkeni argüman olarak geçebildiğimiz gibi, bir sayısal ifadeyi de geçebiliriz.

1System.Console.WriteLine( Elma + Armut );

Yukarıdaki iki satırı incelersek ilkinde bir işlemin sonucunu tutan değişkenin değerini yazdırıyoruz. İkincisinde ise işlemin kendisini direkt parantezlerin içine yazıyoruz. Sonucu hesaplayıp ekrana yazıyor.

Eğer amacımız sadece 2 ve 3 sayılarının toplamını ekrana yazdırmak ise

1System.Console.WriteLine( 2+3 );

yazabiliriz.

using Direktifi

Eğer programda birden fazla System.Console.WriteLine yöntem çağrısı yapıyorsak System isimuzayınu using direktifini sınıf tanımı yapmadan önce programımızın başına ekleriz. using direktifi ile tanımladığımız herhangi bir isimuzayına dahil sınıfların yöntemlerini çağırırken artık isimuzayı ismini yazmadan sadece sınf.yöntem() şeklinde yöntemi yazarız. Bu bize zaman kazandırır. using direktifine direktif denmesinin sebebi programın çalışma zamanında hiçbir işlevinin olmamasındandır.

1Console.WriteLine(Toplam);

Şimdi artık çalışan ve ekrana yazı yazan bir program yazalım.

1using System;
2class BirProgram
3{
4 static void Main()
5 {
6 int Elma, Armut, Toplam;
7
8 Elma = 2;
9 Armut = 3;
10 Toplam = Elma + Armut;
11 Console.WriteLine ( Toplam );
12 }
13}