3 Eylül 2012 Pazartesi

C#' da Döngüler Giriş - FOR Döngüsü


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 :
  1.  FOR (için) Döngüsü
  2. FOREACH (her biri için) Döngüsü
  3. WHILE (iken) Döngüsü
  4. DO-WHILE (yap-iken) Döngüsü

FOR 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