C’de Döngü Kontrolü ve do…while Deyimi

Şimdiye kadar gördüğümüz döngü yapılarında önce koşul kontrolü yapılır ve daha sonra döngü gövdesindeki deyimler çalıştırılırdı. Bu sebepten dolayı eğer başta döngü koşulu yanlışsa hiçbir zaman döngüye girilmeyecek ve programın çalışması döngüden sonraki deyimlerden devam edecekti. Bu durum çoğu zaman işimize yarasa da her zaman en doğru kullanımı sağlamaz. Bazen de önce birtakım işlemlerin yapılıp daha sonra koşulun kontrol edilmesi gerekebilir. Bu da en çok kullanıcıdan değer alınan ve döngünün sonlanması için bir nöbetçi değerin beklendiği döngü yapılarında olur. Şimdi şu örneğe bakalım:

int sayi;
printf("Bir sayi girin: ");
scanf("%d", &sayi);

int toplam = 0;

while(sayi != -1)
{
    toplam += sayi;
    printf("Bir sayi girin: ");
    scanf("%d", &sayi);
}

Bu kod parçasında basitçe kullanıcıdan tamsayı değerleri alınıp toplanmakta ve sonuç toplam isimli değişkende tutulmaktadır. Eğer kullanıcı -1 değerini girerse döngü yapısından çıkılacaktır. Fakat böyle bir kontrol yapmak için kullanıcıdan değer alma işlemini hem döngüden önce, hem de döngü gövdesinin içinde ve en sonda yapmak zorunda kalıyoruz. Yani aynı printf ve scanf fonksiyonlarını 2 defa çağırmış oluyoruz. C dilinde bu durumu çok güzel bir şekilde çözecek olan ve göreceğimiz son döngü yapısı olan do…while isimli bir döngü yapısı bulunmaktadır. Bu yapı ile önce işlemi yapıp sonra döngü koşulunu kontrol ederiz. Hepsi bundan ibarettir. Şimdi aynı kod parçasını do…while ile yeniden yazalım:

int sayi = 0;
int toplam = 0;

do{
    toplam += sayi;

    printf("Bir sayi girin: ");
    scanf("%d", &sayi);
} while(sayi != -1);

Burada ilk önce do anahtar kelimesinden sonra açılan blok içerisindeki ifadeler çalıştırılmakta ve daha sonra while parantezi içerisindeki döngü koşulu kontrol edilmektedir. Böylelikle döngünün dışında kullanıcıdan ayrıca bir sayı istemek zorunda kalmadan programımızı yazabiliyoruz. Burada toplam += sayi satırı ilk durumda iki değişkenin değeri de 0 olduğundan problem oluşturmayacaktır. do…while döngü yapısının genel biçim şu şekildedir:

do {
// Çalıştırılacak deyimler
} while(<Döngü Koşulu>);

Burada en sık yapılan hata while anahtar kelimesinden sonraki koşul parantezlerinden sonra “;” koymayı unutmaktır. while deyiminde herhangi bir “;” bulunmadığından böyle bir hata yapılmaktadır. do anahtar kelimesi sadece bu yapı için kullanılan bir anahtar kelimedir ve bu anahtar kelimeden sonra gelen blok döngü gövdesini belirtir. Buradaki akış önce döngü gövdesinin çalıştırılması, en son ise döngü koşulunun kontrol edilmesidir. Böylece koşul yanlış olsa bile döngü gövdesi 1 kez çalıştırılacaktır. Bunu bir akış şemasında şöyle belirtebiliriz:

Figür 1: do…while Deyiminin Akış Şemasında Gösterimi

Bu döngü deyimi ile ilgili söyleyeceğimiz çok fazla bir şey yoktur. Hemen bir örnek yapıp bir sonraki konumuza geçebiliriz. Öncelikle kodu ve çıktıyı görelim:

// Code 4.4.1: Code4_4_1.c
// C'de do...while deyimi ile fatura hesaplama

#include <stdio.h>

int main()
{
    int toplam = 0;
    int fiyat = 0;
    const float kdv = 0.08f;

    do {
        toplam += fiyat;

        printf("Lutfen urun fiyatini girin (TL): ");
        scanf("%d", &fiyat);
    }while(fiyat != -1);

    toplam = toplam + (int)(toplam * kdv);

    printf("Toplam fiyat (+KDV): %d TL\n", toplam);

    return 0;
}
ÇIKTI
Lutfen urun fiyatini girin (TL): 100
Lutfen urun fiyatini girin (TL): 200
Lutfen urun fiyatini girin (TL): 300
Lutfen urun fiyatini girin (TL): 400
Lutfen urun fiyatini girin (TL): -1
Toplam fiyat (+KDV): 1080 TL

Bu programda çeşitli ürün fiyatlarını girerek KDV ile beraber toplam fiyatını ekrana basıyoruz. KDV değerini bir sabit olarak 10. satırda float türünde tanımladık. 0.08 değerinden anlayabileceğiniz gibi burada KDV’yi %8 olarak aldık. Siz istediğiniz gibi değiştirebilirsiniz. Daha sonra do…while döngü deyimi ile daha önce yaptığımızdan çok da farkı olmayan kullanıcıdan girdi alıp toplama ve sonucu toplam değişkenine yazma işlemini gerçekleştirdik. Burada nöbetçi değer olarak -1 değerini aldık. Daha sonra çıkan toplama KDV değerini de ekleyip sonucu ekrana yazdırdık. Burada yaptığımız int tür dönüşümü ile derleycinin vereceği çeşitli uyarılardan kurtulmuş oluyor ve daha düzgün bir tamsayı hesabı yapmış oluyoruz.

C dilinde döngü yapılarının tamamını öğrendik. Şimdi döngüler ile iligli son bir önemli konudan bahsedeceğim. Bildiğiniz gibi döngü yapılarında kullanılan koşul ifadeleri yanlış olana kadar döngü dönmektedir. Ancak bazı durumlarda koşul doğru olsa bile o döngü adımını atlamak veya o adımda döngüden çıkmak durumları gerekebilir. Bu durumlar için C bize break ve continue isimli iki adet anahtar kelime sunmaktadır.

break anahtar kelimesini switch yapısını incelerken görmüştük. Bildiğiniz gibi bu anahtar kelime ile gerektiğinde switch yapısından çıkabiliyorduk. Eğer çıkmazsak diğer case ifadeleri de işlem görüyordu. Benzer şekilde bu anahtar kelimeyi döngü yapılarında da kullanabiliriz. break anahtar kelimesi (“;” ile onu bir deyim olarak anabiliriz) bir döngü yapısından o satırda çıkmayı ve döngüden sonraki deyimleri çalıştırmayı amaçlar. Şimdi şu örneğe bakalım:

for(int i = 0; i < 50; i++) {
    if(i == 10) {
        break;
    }
    printf("%d\n", i);
}

Bu kod parçası ile normalde 0’dan 49’a kadar olan sayıları ekrana basabiliriz. Fakat döngü gövdesinde bir “if” deyimi görmekteyiz. Bu durumda i değişkenşnin değeri 10 olduğunda döngüden çıkılması gerektiği söylenmiştir. Yani bu kod parçasının ekran çıktısına baktığımızda aslında 0’dan 9’a kadar olan sayıların ekrana basıldığını görürüz. i = 10 durumunda döngüden çıkılır ve program akışına diğer deyimerden devam edilir. break deyimi genellikle döngü gövdesinde bu tip if deyimleri ile beraber kullanılmaktadır.

Şimdi de continue anahtar kelimesine veya deyimine bakalım. Bu deyim ise adı üstünde bir döngü adımının atlanıp bir sonraki adımdan devam edilmesini anlatır. Yani döngü gövdesinde bu deyim ile karşılaşıldığı anda, artık bu deyimden sonra gelen kısımlar çalıştırılmaz ve bir sonraki adıma atlanır. Burada bu deyimin for döngüsü ile kullanımı ile while ve do…while döngüleri ile kullanımı arasında çeşitli farklar mevcuttur. Önce for döngsündeki kullanımına bakalım:

for(int i=0; i < 10; i++) {
    if(i == 5) {
        continue;
    }

    printf("%d ", i);
}

Burada daha önceki yazılarda bahsettiğim şekilde for döngüsü işlemeye başlar. i sayaç değişkeninin değeri 5 olduğunda ise if deyimine girilerek continue deyimi çalıştırılır. Bu durumda bir alttaki printf fonksiyonu çalıştırılmadan tekrar sayaç değişkenini değiştirme kısmı olan i++ ifadesi çalıştırılır. i değerinin değeri 6 olduktan sonra her şey normal bir şekilde işlemeye devam eder. Bu durumda çıktı aşağıdaki gibi olacaktır:

ÇIKTI
0 1 2 3 4 6 7 8 9

Gördüğünüz gibi 5 sayısını ekrana basmadık ama break deyimindeki gibi döngüden de çıkmadık. İşte bu anahtar kelimenin tam olarak kullanımı budur; belli koşullarda döngü adımını atlamak. Fakat bu deyimi while ve do…while gibi deyimlerde kullanırken dikkat etmek gerekir. Örneğin şu koda bakalım:

int i = 0;

while(i < 10) {
    if(i == 5) {
        continue;
    }

    printf("%d ", i);
    i++;
}

Yukarıda for döngüsü ile yazdığımız kodun aynısı gibi görünen bu kodda, aslında küçük bir fark vardır. Bu kodu çalıştırdığınızda ekrana 4’e kadar sayıların yazıldığını ve daha sonra programın öylece durduğunu gözlemlersiniz. Bunun nedeni continue deyiminden sonra i sayaç değişkenini arttıran i++ satırına hiç gidilememesi ve sürekli aynı sayaç değişkeninde kalındığı için continue deyimi ve döngü koşulu arasında bir sonsuz döngü oluşmasıdır. for deyiminde continue görüldükten sonra sayaç değişkenini değiştirme ifadesine gidildiğinden bu problem oluşmamıştı. Aslında bu problemi while döngüsü kullanarak şu şekilde çözebiliriz:

int i = -1;

while(i < 9) {
    i++;

    if(i == 5) {
        continue;
    }

    printf("%d ", i);
}

Koşul ifadesindeki sınır değerini ve sayaç değişkeninin değerini 1 azaltıp i++ arttırma ifadesini continue satırının üstünde bulundurarak bu sorunu çözebiliriz. Ancak continue deyimi genellikle for döngüsü ile kullanılır ve öyle olması daha düzgün sonuçlar elde etmenizi ve kod sırası ile daha az oynamanızı sağlar. Bazı programcılar break ve continue deyimlerinin yapısal programlama yaklaşımını tehlikeye attığı görüşündedirler. Bu nedenle bu deyimleri kullanmadan farklı şekillerde işlerini halletmeye çalışırlar. Ancak şuan bu konuya girmeyeceğiz.

Son olarak break ile ilgili bir örnek yaparak hem yazımızı hem de bölümümüzü sonlandıralım. Bu programda kullanıcıdan (sayısal) bir şifre değeri alacak ve bunu sistemde tanımlı olan şifre ile karşılaştıracağız. Eğer şifre eşleşiyorsa programa giriş yaptığını belirten bir mesaj gönderecek, eğer şifre eşleşmiyorsa tekrar şifre soracağız. Şimdi kodumuza ve çıktımıza bakalım:

// Code 4.4.2: Code4_4_2.c
// C'de şifre ile giriş yapmak

#include <stdio.h>

int main()
{
    int tanimliSifre = 123987;
    int sifre = 0;

    do{
        printf("Lutfen bir sifre girin: ");
        scanf("%d", &sifre);

        if(tanimliSifre == sifre)
        {
            break;
        }
        else
        {
            puts("Hatali sifre! Lutfen tekrar deneyin!");
        }
    }while(1);

    puts("Sisteme basari ile giris yaptiniz!");

    return 0;
}
ÇIKTI
Lutfen bir sifre girin: 123456
Hatali sifre! Lutfen tekrar deneyin!
Lutfen bir sifre girin: 34567
Hatali sifre! Lutfen tekrar deneyin!
Lutfen bir sifre girin: 76543
Hatali sifre! Lutfen tekrar deneyin!
Lutfen bir sifre girin: 987654
Hatali sifre! Lutfen tekrar deneyin!
Lutfen bir sifre girin: 123987
Sisteme basari ile giris yaptiniz!

Gördüğünüz gibi en ilkel şekilde bir kullanıcının sisteme giriş yapmasını simüle ettik. Burada yine ilk önce belli işleri yerine getirmek ve daha sonra koşulu kontrol etmek istediğimizden do…while deyimini kullandık. 15. satırdaki kontrol ile eğer şifre önceden tanımlanmış şifre ile aynı ise döngüden o anda çıkmamız gerektiğini 17. satırdaki break deyimi ile programa bildirdik. 23. satırda gördüğünüz gibi bu bir sonsuz döngüdür. Bu tip döngülerin sonlandırılmasında break deyimi sıklıkla kullanılmaktadır. Burada da güzel bir örneğini gördünüz.

Bu yazı ile beraber bölümün sonuna gelmiş bulunmaktayız. Şimdiye kadar öğrendiklerimiz C’nin yapısal programlama ile ilgili temel söz dizimini oluşturmakla beraber aslında C++ dilinin de temellerini oluşturmaktadır. Eğer bu temelleri düzgün bir şekilde kavrarsanız, ilerideki konularda oldukça rahatlayacaksınız. Artık yavaş yavaş fonksiyonlara ve modüler program tasarımına geçebiliriz.

5 3 votes
Article Rating
Subscribe
Bildir
guest

4 Yorum
Eskiler
En Yeniler Beğenilenler
ipek

do while kdv örneği toplam değeri int tanımlarsanız çalışmaz

ipek

int toplamın içine float kdv yi ekleyip nasıl ekrana bastımayı düşünüyosunuz acaba?????