C’de while Deyimi

Daha önceki bölümde bahsettiğimiz yinelemeli deyimler (iterartion statement, repetition statement) ile bir koşul doğru olduğu sürece belli bir kod parçasını tekrar tekrar çalıştırabileceğimizi söylemiştik. Biz şu andan itibaren yinelemeli deyimleri döngü deyimi (loop statement) olarak isimlendireceğiz.

Döngüler programların vazgeçilmez elemanlarıdır. Birden fazla kez çalıştırmamız gereken kod parçalarını ard arda yazmak yerine döngüleri kullanarak yazmak inanılmaz derecede esneklik ve kolaylık sağlamaktadır. C dilinde 3 adet döngü deyiminin bulunduğunu söylemiştik. Bunlar:

  • while
  • do…while
  • for

while Deyimi

Yapısı ve kullanımı oldukça basit olan while döngü deyimini hızlıca anlatıp hemen örneklere geçmeyi planlamaktayım. Öncelikle while deyiminin söz dizimine bir göz atalım:

while(<koşul_ifadesi>) {<deyimler>}

Söz dizimi olarak if deyiminin aynısı olduğunu söyleyebiliriz. Yine normal parantezler içerisine sonucu 0 veya sıfır dışı bir sayı üreten bir ifade yazıyoruz. "<deyimler>" kısmına ise bu koşul doğru olduğu sürece (yani sonucu 0 gelmediği sürece) çalışacak olan kodları yazıyoruz. Bu bloğu da Döngü Gövdesi (Loop Body) olarak isimlendiriyoruz. Olay bu kadar basit… Şimdi geçen bölümde verdiğimiz sözde kod örneğine bakalım:

WHILE sayac < 6
    sayac ← sayac + 1

Bunu C koduna şu şekilde geçirebiliriz:

int sayac = 0;

while(sayac < 6)
{
    sayac = sayac +1;
}

Peki bu döngü kaç kere dönecektir. Programcıların döngü deyimlerini kullanırken yaptıkları sık hatalardan biri, bu döngünün kaç kez döneceğini yanlış ele almalarıdır. Örneğin yukarıdaki koşul ifadesinde sayac < 6 yerine sayac <= 6 yazmak arasında fark vardır. Öncelikle yukarıda yazdığımız kodu analiz edelim: sayac değişkenine 0 ilk değerini verdikten sonra döngü deyimimize geliyoruz. Burada öncelikle sayac değişkeninin 6’dan küçük olup olmadığı kontrol ediliyor ve küçük olduğu için de döngü gövdesinde yer alan kod çalıştırılarak bu değişkenin değeri 1 artırılıyor.

Daha sonra tekrar koşul ifadesi kontrol ediliyor. Değeri o anda 1 olan sayac değişkeninin yine 6’dan küçük olup olmadığı kontrol ediliyor ve küçük olduğu için yine döngü gövdesi çalıştırılarak sayac değişkeni 1 artırılıyor. Bu şekilde devam eden çalıştırmalar sonucu sayac değişkeninin değeri son kez 1 artırılıp 6 olduğunda, koşul ifadesi artık doğru olmayıp 0 değerini üretiyor ve döngü deyimi sonlanıyor. Daha sonra tıpkı if deyiminde olduğu gibi program döngü deyiminden sonraki satırdan çalışmaya devam ediyor. Böylelikle döngümüz 6 kez dönmüş, yani döngü gövdesindeki kod 6 kez çalıştırılmış oluyor.

Peki bu ne işimize yarayacak? Diyelim ki ekrana 1’den 100’e kadar olan (100 dahil değil) tamsayıları basmak istiyoruz. Bu deyimi bilmeden ilk yapacağımız şey alt alta 100 tane printf fonksiyonu çağırmak olacaktır değil mi? Fakat döngü deyimleri ile buna gerek kalmıyor:

int sayi = 1;

while(sayi < 100)
{
    printf("%d\n", sayi);
    sayi = sayi + 1;
}

Sonsuz Döngü

Peki döngünün koşul kısmı asla 0 olmazsa ne olur? Az önce yaptığımız iki örnekte de koşul kısmında yer alan değişkenin değerini döngü gövdesinde değiştirerek, koşulun belli bir değerde yanlış olmasını, yani 0 değerini üretmesini sağlıyorduk. Diyelim ki bu değişkenin değerini döngü gövdesinde değiştirmeyi unuttuk. Hemen ne olacağını inceleyelim:

int sayi = 1;

while(sayi < 100)
{
    printf("%d\n", sayi);
}

Bu programı çalıştırdığınızda ekrana sürekli 1 değerini basar. Çünkü sayi değişkeninin değerini değiştirecek bir deyim yoktur ve bu değişken sürekli 1 değerine sahip olduğu için sayi < 100 ifadesi hep doğru olacaktır. Bu tip döngülere programlama dünyasında Sonsuz Döngü (Infinite Loop) adı verilmektedir. Bilgisayar dünyasında belli durumlar haricinde bu döngüler genellikle bir hata olarak ele alınır. Yukarıdaki programda bir süre sonra muhetemelen program ekrana 1 yazmayı bırakıp kapanacaktır (bu durum sistemden sisteme değişiklik gösterebilir). Başka bir sonsuz döngü örneği de şu şekildedir:

while(1)
{
    //...
}

Burada bir konuya daha değinmekte yarar vardır. C dilinin büyük-küçük harf duyarlılığı olan (case-sensitive) bir dil olduğunu daha önce söylemiştim. Bu kural anahtar kelimelerin kullanımında da geçerlidir. Örneğin if kelimesi yerine IF yazmak veya while kelimesi yerine While yazmak derleme aşamasında hata oluşmasına sebep olacaktır. C anahtar kelimeleri genellikle tamamı küçük harf olacak şekilde yazılmaktadır.

Yine değineceğim bir başka konu da if bloğunda tek deyim olduğundaki yazım biçimi, aynen while bloğu için de geçerlidir. Yani ilk örneği şu şekilde de yazabilirdik:

while(sayac < 6)
    sayac = sayac +1;

Kontrol Deyimlerinin İç İçe Kullanılması

Fakat ben kişisel olarak bu kullanımı pek kullanmıyorum. Kod okunabilirliğinde karmaşaya sebep olabiliyor. Eğer size sıkıntı yaratmayacağını düşünüyorsanız kullanabilirsiniz. Şimdi bir başka konumuza geçelim. Bildiğiniz gibi blokların içerisine birçok deyim yazabilmekteyiz. if, if...else ve while da birer deyim olduğundan, while bloğunun içerisine if deyimi, else bloğunun içerisine while deyimi vs. yerleştirebiliriz. İşte asıl programlama burada başlıyor! Hemen birkaç örnek yapalım:

int sayi;
scanf("%d", &sayi);

int i = 0;
while(i < 10)
{
    if((i % 2) == 0)
    {
        printf("%d ", i * sayi);
    }
    i = i + 1;
}

Burada öncelikle kullanıcıdan bir sayı alıp bunu sayi değişkeninde depoluyoruz. Daha sonra da döngü koşulunu kontrol edecek olan i isimli bir değişken tanımlıyoruz. Sayaç vb. durumlar için kullanabileceğimiz değişkenleri i, j ve k gibi tek harfler ile isimlendirmek çoğu programcının alışkanlığıdır. Bu değişkeni her döngünün sonunda 1 artırıyor ve 10 oluncaya kadar döngü bloğunu çalıştırıyoruz. Döngü bloğunda ise bir if deyimi görmekteyiz.

Döngü bloğunda yer alan if deyimi bize i değişkeninin o anki değerinin 2 ile bölümünden kalan 0 ise (yani i değeri bir çift sayı ise) if bloğuna girileceğini söylüyor. Bu durumda 0 ile 10 arasındaki (10 dahil değil) bütün çift sayılarda bu koşul sağlanacak ve if bloğundaki printf fonksiyonu çağrılacaktır. printf fonksiyonu ise o anki i değeri ve girilen sayi değerinin çarpımı olan sayıyı ekrana basacaktır. Böylece girilen sayının sırasıyla 0, 2, 4, 6 ve 8 sayıları ile çarpımı aralarda bir boşluk olacak şekilde ekrana basılacaktır. Örneğin 15 sayısını girdiğimizde bize şöyle bir çıktı gelecektir:

ÇIKTI
15
0 30 60 90 120

Hemen küçük bir örnek daha yapalım. Diyelim ki şifresi 123456 (sakın böyle bir şifre kullanmayın) olan bir sistemimiz olsun ve bu sisteme kullanıcıyı giriş yaptırtmak istiyorsunuz. Fakat kullanıcı şifreyi yanlış girdiğinde kullanıcıyı uyarmak ve şifre bilgisini tekrar kullanıcıdan almak istiyorsunuz. Şifrenin sadece int veri türünde tutulduğu bir sistem düşünüp bunu hemen while deyimini kullanarak tasarlamaya çalışalım:

int sifre;

printf("Lutfen sifrenizi girin: ");
scanf("%d", &sifre);

// Şifre yanlışsa sürekli kullanıcıdan istiyoruz:
while(sifre != 123456)
{
    printf("Sifre yanlis! Sifrenizi tekrar girin: ");
    scanf("%d", &sifre);
}

// Döngüden çıkarsak başarı mesajı yazdırıyoruz:
puts("Basariyla giris yaptiniz!");

Gördüğünüz gibi while deyiminin koşul kısmına girilen şifrenin 123456 değerine eşit olmadığı durumunu koyuyoruz. Böylelikle kullanıcı şifreyi yanlış girdiği takdirde sürekli ekrana uyarı mesajı verilip şifre tekrar istenecektir. Yani şuna benzer bir çıktı almış olacağız:

ÇIKTI
Lutfen sifrenizi girin: 67
Sifre yanlis! Sifrenizi tekrar girin: 89
Sifre yanlis! Sifrenizi tekrar girin: 12345
Sifre yanlis! Sifrenizi tekrar girin: 123456
Basariyla giris yaptiniz!

Bu örnekten de anlayabileceğiniz gibi, while döngü deyimini illaki sabit miktarda dönecek şekilde tanımlamamız gerekmez. Tamamen kullanıcıdan gelen girdiye göre yineleme sayısı değişen döngüler tasarlayabiliriz. Bu pek çok uygulamada bizim işimizi kolaylaştırmaktadır.

while Deyimi Kullanarak Basit Bir Hesap Makinesi Yapmak

Bunca şey öğrendikten sonra bir hesap makinesi yapmadan olmaz değil mi? Fakat bu biraz daha ilkel bir hesap makinesi olacak. Öncelikle bu hesap makinesi programımız 2 sayı girdisi ve sonunda da bir işlem girdisi alacak. Eğer işlem girdisi 0 ise program sonlandırılacak. Eğer işlem girdisi "+", "-" veya "*" karakterlerinden biriyse toplama, çıkarma veya çarpma yapılacak.

Biz 0 değerini işlem kısmına verene kadar program çalışmaya ve bize hizmet etmeye devam edecek. Bu uygulamayı bildiğimiz yöntemlerle biraz garip bir şekilde yazacak olsak da ileride göreceğimiz do...while deyimi ile bunun üstesinden geleceğiz. Şimdi kodumuza bakalım:

#include <stdio.h>

int main()
{
    int sayi1, sayi2;
    char islem;
    int sonuc;

    printf("Islem yapilacak sayilari girin: ");
    scanf("%d %d", &sayi1, &sayi2);

    printf("Islemi girin (+, -, *): ");
    scanf(" %c", &islem);

    while(islem != '0')
    {
        if(islem == '+')
        {
            sonuc = sayi1 + sayi2;
            printf("%d + %d = %d", sayi1, sayi2, sonuc);
        }
        else if(islem == '-')
        {
            sonuc = sayi1 - sayi2;
            printf("%d - %d = %d", sayi1, sayi2, sonuc);
        }
        else if(islem == '*')
        {
            sonuc = sayi1 * sayi2;
            printf("%d * %d = %d", sayi1, sayi2, sonuc);
        }

        printf("\nIslem yapilacak sayilari girin: ");
        scanf("%d %d", &sayi1, &sayi2);

        printf("Islemi girin (+, -, *): ");
        scanf(" %c", &islem);
    }

    puts("PROGRAM SONLANDIRILDI");
    return 0;
}
ÇIKTI
Islem yapilacak sayilari girin: 23 23
Islemi girin (+, -, *): +
23 + 23 = 46
Islem yapilacak sayilari girin: 12 9
Islemi girin (+, -, *):
12 – 9 = 3
Islem yapilacak sayilari girin: 7 7
Islemi girin (+, -, *): *
7 * 7 = 49
Islem yapilacak sayilari girin: 4 5
Islemi girin (+, -, *): 0
PROGRAM SONLANDIRILDI

Bu koddda öncelikle programımız için gerekli olacak değişkenleri bildiriyoruz. sayi1 ve sayi2 değişkenleri girdiğimiz sayıları tutacakken, islem değişkeni işlemi belirten karakteri tutacak, sonuc değişkeni ise hesaplanan sonucu tutacaktır. Daha sonra döngüye girmeden hemen önce bu sayıları aralarında bir boşluk kalacak şekilde alıyoruz. Sonrasında ise işlem karakterini alıyoruz. Döngü kısmında karakterin "0" olup olmadığını kontrol ediyoruz. Burada karakter olarak yazacağınız "0" ile sayı olarak yazacağımız 0 arasında fark vardır. Bu farkı anlamak için veri türleri ile ilgili yazmış olduğum önceki yazıları inceleyebilirsiniz.

Döngü içerisinde işlemin "+" olup olmadığını kontrol ediyor ve eğer "+" ise iki sayıyı toplayıp toplamı sonuc değişkenine atıp en son ekrana çıktı veriyoruz. Benzer şeyleri "-" ve "" işlemleri için de yapıyoruz. Eğer girilen karakter "+", "-" veya "" değilse program hiçbir hesap yapmadan ve çıktı vermeden bir sonraki iki sayıyı sizden isteyecektir. Döngü sonunda eğer islem değişkenine "0" değeri atamazsak while döngü deyimi iş yapmaya devam edecek ve sürekli size aynı soruları soracaktır.

Aslında burada sürekli çalışan programların basit de olsa bir örneğini görüyoruz. Kullanıcı programı "0" girmeden veya anormal yollara başvurmadan (komut istemcisini kapatmak gibi) sonlandıramadığı için program sürekli çalışacaktır. Kullanıcı "0" değerini girdiğinde ise program sonlanacak ve ekrana PROGRAM SONLANDIRILDI yazısı yazılacaktır. Bu durumda girilen 2 sayının da bir önemi kalmayacaktır.

Bu bölümde yinelemeli deyimlere giriş yapıp bunların ilki olan while döngü deyimini inceledik. Bu döngü deyiminin çeşitli özelliklerini inceledik ve bu özelliklerle ilgili küçük örnekler yaptık. En son ise çok ilkel bir hesap makinesi yaparak konuyu sonlandırdık. İleride artık daha işlevsel kodlar yazmaya başlayacağız. Bir sonraki yazıda, kağıt üstünde oluşturduğumuz çeşitli algoritmaları C koduna nasıl dökeceğimizle alakalı çeşitli örnekler görecek ve bu örnekler ile gördüğümüz konuları pekiştireceğiz.

5 2 votes
Article Rating
Subscribe
Bildir
guest

0 Yorum
Eskiler
En Yeniler Beğenilenler
Inline Feedbacks
View all comments