C
#’DA DÖNGÜLER
Programlamada bir
uygulama geliştirilirken kullanılan algoritma gereği, bazı kod bloklarının, defalarca
tekrar tekrar çalışması gerekebilir. Her defasında bu kod bloklarının yazılması
bir şeylerin ters gittiğinin habercisi demektir. Bu nedenle programlama
dillerinde “döngüler” kullanılır. Döngüler sayesinde, her defasında istenilen
değerlere göre, istenilen sayıda tekrar etmesi istenilen kod blokları,
zahmetsiz ve kod tekrarı yapılmadan çalıştırılabilir. Döngüsüz bir programlama dili düşünülemez.
Kullanılmaz ise uygulamanın algoritması gereği gereksiz yere kod tekrarı
yapılacaktır ki, kodlarınızın ne kadar tekrar etmesi gerektiğine göre ciddi bir
koddan söz edilebilir, bu durum da hiçbir yazılım geliştirici için kabul
edilebilir değildir.
Bu
yazımda c sharp programlama dilindeki döngüler ele alınacaktır. C sharp ‘da
kullanılan başlıca döngüler :
- FOR (için) Döngüsü
- FOREACH (her biri için) Döngüsü
- WHILE (iken) Döngüsü
- DO-WHILE (yap-iken) Döngüsü
For
döngüsünü diğer döngülerden ayıran en büyük özellik döngünün kaç kere döneceği
bellidir ya da önceden kestirilebilir. Günlük hayattan örnek vermek gerekirse
Formula araba yarışları güzel bir örnek olacaktır. Çünkü yarışın bitme koşulu
vardır. Örneğin arabalar 70 turu tamamladıktan sonra diye bir koşul mevcuttur.
Yani yarışın ne zaman biteceği bellidir.
For
döngüsünün çalışma prensibini hemen bir örnek üzerinde inceleyelim. Örneğin
tasarlanan bir kullanıcı formunda, kullanıcıdan doğum tarihi bilgisi
isteniliyor. Fakat programcının belirlediği yıl, ay ve gün aralığından,
kullanıcının bu bilgisini seçmesini bekleniyor. Yıl aralığının 1900-2012, ay
aralığının 0-12, gün aralığının 0-(28-29-30-31) olarak belirlendiğini
düşünelim.
“Visiual
Studio 2010” üzerinden bir “Windows Form Application” açalım. Kullanıcı arayüzünü aşağıdaki gibi
tasarlayalım.
Form
kontrolüne, Toolbox penceresinde standart kontroller sekmesi altından 3 adet
ComboBox kontrol eklendi. ComboBox ‘lara TextBox gibi değer girilmesini önlemek
amacıyla DropDownStyle özelliğini DropDownList yapıldı. Name özellikleri sırasıyla;
cmbYil, cmbAy, cmbGun olarak
değiştirildi.
Yine
Toolbox ‘dan 3 adet de Label kontrolü atıldı. Text özelliklerine görüldüğü gibi
değerleri girildi. Name özelliklerine de sırasıyla; lblYil, lblAy, lblGun değerleri verildi.
Bu
işlemi for döngüsü ile yapalım. Form ekrana geldiğinde ComboBox ‘lar dolu
olarak gelmesini istiyorsak Form ‘un Load event ‘ini Handle edelim.
private void
frmForDongusu_Load(object sender, EventArgs e)
{
for (int x = 1900; x
<= DateTime.Now.Year; x++)
{
cmbYil.Items.Add(x);
}
}
For döngüsü üç
bölümden oluşmaktadır. Bölümler noktalı virgüllerle ayrılır. Birinci bölüm declaration (tanımlama) ve setting (değer atama) bölümüdür. Burada
değişken tanımlanır ve o değişkene bir başlangıç değeri atılır. Bu bölüm döngü
ne kadar dönerse dönsün bir defa çalışacaktır ve döngünün ilk başladığı
bölümdür. Fakat istenirse tanımlama aşağıda örnekteki gibi bu bölümden önce
yani for döngüsünden önce yapılabilir.
int x=0;
for (x = 1900; x <= DateTime.Now.Year; x++)
{
cmbYil.Items.Add(x);
}
For
döngüsü içerisinde kullanılan değişkene for döngüsü değişkeni (for loop variable)
denir ve herhangi istenilen bir isim verilebilir.
İkinci bölüm
döngünün bitiş noktasını belirtir. Burada bir koşul yani geri dönüş tipi bool
olan bir criterian (kriter)
belirtmeliyiz. Bu kriter for döngümüzün bitiş kriteridir. Yani for değişkeni bu
kriterden geçtiği sürece yani bu koşuldan “true” sonucu döndüğü sürece, for
döngüsü çalışmasına devam edecektir. Burada verdiğimiz değer değişkenimizin for
döngüsünden çıkmadan önce alacağı son değerdir ve bu değişkenin ömrü sadece for
skoplarında geçerlidir.
Üçüncü bölüm “iteration” (öteleme-berileme)
bölümüdür. Ötelemeden kasıt döngü değişkeninin değerinin istenilen miktar kadar
arttırılması, berilemeden kasıt ise döngü değişkeninin değerinin istenilen
miktar kadar azaltılmasıdır. Değişkenin bir dahaki for düngü adımında ne kadar arttırılacağını ya
da ne kadar azaltılacağını belirler. Örneğin ikişer ikişer arttırmak istersek;
aşağıda da görüldüğü gibi, bu bölüme x+=2 ya da x=x+2 şeklinde yazmamız yeterli
olacaktır.
for (int
x = 1900; x <= DateTime.Now.Year; x+=2)
{
cmbYil.Items.Add(x);
}
Iteration
bölümünde döngü değişkenin değerinin arttırılması şart değildir. Uygulamanızdaki
senaryoya göre bu değişkeni azaltmanızda gerekebilir. Örneğin aşağıdaki gibi
ComboBox ‘a yılları tersten sıralamamız daha mantıklı olacaktır.
for (int
x = DateTime.Now.Year; x >=1900; x--)
{
cmbYil.Items.Add(x);
}
Örneğimiz
geri kalan kısmına devam etmek gerekirse, ayları da cmbAd adlı ComboBox ‘a
sıralamalıyız. Bunun için aylar adında string bir dizi tanımlayalım ve
dizilerin indexer yapısı sayesinde bu dizinin elemanlarını teker teker okuyalım.
private void
frmForDongusu_Load(object sender, EventArgs e)
{
for (int x = DateTime.Now.Year;
x >=1900; x--)
{
cmbYil.Items.Add(x);
}
string[] aylar = { "Ocak",
"Şubat", "Mart",
"Nisan", "Mayıs",
"Haziran", "Temmuz", "Ağustos",
"Eylül", "Ekim",
"Kasım", "Aralık"
};
for (int index = 0;
index < aylar.Length; index++)
{
cmbAy.Items.Add(aylar[index]);
}
}
Görüldüğü üzere
iki tane for döngüsü ile 2iki ComboBox kontrolünü verilerle doldurdu. For
döngüsüne “breakpoint” atarak, uygulamamızı debug modda çalıştırdığımızda,
program akışı öncelikle declaration-setting bölümüne (1.bölüm), daha sonra
koşul bölümüne (2.Bölüm) ve daha sonra ise iteration bölümüne uğramadan for
döngüsünün içerisindeki kodlardan devam edecektir. Yani döngü değişkeninin ilk
değeri için döngü içerisindeki kodlar bir defaya mahsus olmak üzere
çalışacaktır. Bu kodlar çalıştıktan sonra, program akışı iteration bölümüne
uğrar. Burada döngü değişkeni yeni değerini aldıktan sonra tekrardan değişkenin
yeni değerine göre ikinci bölümdeki koşul kontrol edilir. Koşuldan true sonucu
dönerse döngü dönmeye devam edecektir. False dönerse de döngü içerisindeki
kodlar çalışmadan döngüden çıkılır.
Ay bilgisi
seçilmeden gün bilgisinin seçilmesini istemiyorsak yine Formun Load event ‘inde
“cmbGun” ve “lblGun” kontrollerinin “Enable” özelliklerine “false” değerini
verelim.
cmbGun.Enabled =
lblGun.Enabled = false;
Ay bilgisi girildikten
sonra lblGun ve cmbGun kontrollerinin aktif olmasını istiyorsak bu kontrolü
cmbAy kontrolünün SelectedIndexChange eventinde yapmamız gerekiyor.
private void
cmbAy_SelectedIndexChanged(object sender, EventArgs e)
{
GunDoldur();
}
private void GunDoldur()
{
if (cmbAy.SelectedIndex == -1) return;
if (cmbYil.SelectedIndex == -1) return;
cmbGun.Items.Clear();
cmbGun.Enabled = lblGun.Enabled = true;
switch
(cmbAy.SelectedItem.ToString())
{
case "Şubat":
if (DateTime.IsLeapYear((int)cmbYil.SelectedItem))
{
for (int i = 1; i <= 29; i++)
{
cmbGun.Items.Add(i);
}
}
else
{
for (int i = 1; i <= 28; i++)
{
cmbGun.Items.Add(i);
}
}
break;
case "Ocak":
case "Mart":
case "Mayıs":
case "Temmuz":
case "Ağustos":
case "Ekim":
case "Aralık":
for (int
i = 1; i <= 31; i++)
{
cmbGun.Items.Add(i);
}
break;
case "Nisan":
case "Haziran":
case "Eylül":
case "Kasım":
for (int
i = 1; i <= 30; i++)
{
cmbGun.Items.Add(i);
}
break;
default:
break;
}
}
Bu kontrolü de switch
karar yapısıyla gerçekledik. Bilindiği üzere bazı aylar 31, bazı aylar 30, Şubat ayı ise 4 ile bölünebilen yıllarda
(artık yıl denir) 29, değer yıllarda 28 çeker. 29 çeken yılları DateTime sınıfı
altındaki, geriye bool tipinde değer dönen isLeapYear metodu ile bulabiliriz.
Eğer bu metoda verilen parametre artık yıl ise metottan geriye “true” sonucu
dönecektir. “True” dönmesi halinde for döngüsünün bitiş kriterini: 29 ‘dan
küçük yada 29 ‘a eşit olduğu sürece dön diye belirtebilirim.
Bu kontrollerin, cmbYil
adlı ComboBox ‘ın değerinin değişmesi ile de yapılmasını istiyorsak; aşağıdaki
gibi cmbYil kontrolünün SelectedIndexChanged event ‘inde de GunDoldur metodunu
çağırmamız gerekmektedir.
private void
cmbYil_SelectedIndexChanged(object sender, EventArgs e)
{
GunDoldur();
}
Aşağıdaki diğer bir
örnekte alfabe yazdırıldı. Fakat burada dikkat edilmesi gereken nokta: for
döngüsü içerisinde char tipindeki herhangi bir değişkeni for döngüsünün
iteration bölümünde kullanırken o char ‘ın ascii değerlerine göre bir iteleme
yada öteleme yapacağı unutulmamalıdır. Yani iteration ‘da char ‘dan int tipine
“implicit converting” (kapalı tip dönüşümü) yapar. Bu yüzden ekrana yazarken bu
ascii değerlerini (int tipinde) tekrar char tipine dönüştürmek gerekir. Bu da “explicit
converting” (açıktan tip dönüşümü) yapılması gerek demektir.
for (int
i = 'A'; i <= 'Z';
i++)
{
cmbYil.Items.Add(Convert.ToChar(i));
}
Sonsuz
Döngü Mantığı
For düngüsünün mantığı
iyi kurgulanmalıdır. Bir mantık hatası for düngüsünü sonsuz bir döngüye
sokabilir ve bu istenmeyen bir durumdur. Aşağıdaki örnekte for içindeki
değişken 2013 ‘den başlamış ve 2012 ‘den büyük olana dek dönmeye devam et demiş
bulunuyoruz. Bu deyim de sonsuza dek dön demek oluyor. Bu işlemi formun Load
event ‘inde yaptığımız için program akışı bu for döngüsünde takılıp kalacak ve
formum ekrana hiç gelmeyecektir.
Başka bir yazıda görüşmek dileğiyle, hoşçakalın...
Hiç yorum yok:
Yorum Gönder