1 Mart 2009 9031150 - Temel Bilgisayar Bilimleri Ders Notu #3 Referans: Bugün: 1. Ders Notları. Ders #2 Tekrar Seçme kontrol teknikleri - switch komutu C dilinde genel olarak kullanılan komutlar ve ifadeler Döngüler (Loops) 1. Tekrar Geçen ders If...Else ifadelerini gördük. If Else ifadeleri Kullanım şekli: if (boolean ifadesi) { ifade/blok; else { ifade/blok; If ifadesi doğru ise bir şey yap, değil ise başka bir şey yap. D If Y i bas i bas top
2 if (boolean ifade1){ blok1; else if (boolean ifade2){ blok2; else if (boolean ifade3){ blok3; else blok4; Eğer blok1 DOĞRU ise (TRUE) birinci blok yürütülür. Aksi taktirde tüm blok atlanır ve bir sonraki kontrol döngüsü kontrol edilir. blok4 her şart altında yürütülür. if (hiz > 100) { ceza = 500; printf( Tutukla ); else if (hiz > 75) { ceza = 200; printf( Uyari ); else if (hiz>55) { ceza = 50; printf( Rusvet ver bana ); else{ printf( Yoldan cekil ); NOT: Kalın gösterilen küme işaretleri tercihe bağlıdır. Olmamaları halinde de program aynı mantıkta çalışacaktır. NOT 2: Yukarıdaki örnekte else ifadeleri olmazsa ne olurdu? Seçme kontrol teknikleri 1. switch Kullanımı: switch(degisken){ olay değeri/etiket : s1; s2; s3; olay etiketi : s4; s5; s6;
3 default : s1; default (varsayılan) olayın sonuna break konmasına genelde gerek yoktur. Fakat, iyi programcılık gereği daha sonra altına başka olayların eklenebilme olasılığına karşı küme parantezi iyi tercih edilen uygulamadır. switch komutu da if else gibi davranış gösterecektir. Fakat if-else ifadeleri her zaman switch ile değiştiremezsiniz. Çünkü switch komutu spesifik değerler kullanımını gerektirir. switch (sekil) case u : case U : s1; s2; s3; case k : case K : s4; s5; NOT: switch ifadesinde kullanılan değişken ordinal değişken olmalıdır. Diğer bir deyişle değişken karakter ya da tamsayı olmalıdır. Float (gerçek sayı) tipindeki değişkenler switch ifadesinde kullanılmaz. switch (not) { /* notun icerigini control et */ case 'A': case 'a': ort = 4.0; /* A = 4 puan */ case 'B': /* B = 3 puan */ case 'b': ort = 3.0; case 'C': /* C = 2 puan */ case 'c': ort = 2.0; case 'D': /* D = 1 puan */ case 'd': ort = 1.0; case 'F': /* F = 0 puan */ case 'f': ort = 0.0; default : gecerli_girdi = FALSE; /* degerlerde not yoksa not gecersizdir. */
4 /* switch ifadesini sonlandir */ Bu bloğun ait olduğu main fonksiyonu aşağıdaki gibidir: int main(void) { /* main fonksiyonuna basla */ char not; /* harf not: A, B, C, D vs */ int gecerli_girdi = TRUE; /* boolean flag veya yanlis veri */ float ort; /* nota karsilik gelen sayi */ printf("ders notunu girin --> "); /* not girisi icin uyari */ not = getchar(); /* standart girdiden notu oku */ switch (not) { /* notun icerigini control et */ case 'A': case 'a': ort = 4.0; /* A = 4 puan */ case 'B': /* B = 3 puan */ case 'b': ort = 3.0; case 'C': /* C = 2 puan */ case 'c': ort = 2.0; case 'D': /* D = 1 puan */ case 'd': ort = 1.0; case 'F': /* F = 0 puan */ case 'f': ort = 0.0; default : gecerli_girdi = FALSE; /* degerlerde not yoksa not gecersizdir. */ /* switch ifadesini sonlandir */ Başlangıçta default değeri TRUE (DOĞRU) olarak tanımladığımızdan dolayı switch ifadesinde belirtilen değerlerden herhangi birisi doğru olduğu taktirde bloğun devamındaki ifadeler yürütülecektir. Aksi taktirde giriş yapılan değer geçersiz sayılacak ve programın yürütümü durdurulacaktır. if (gecerli deger) { if ifadesinde eğer DOĞRU ise kullanılmaz. Tanım gereği yukarıdaki ifade gecerli deger ise demektir. Her zaman girdinin doğruluğu kontrol edilmez. Bazı durumlarda YANLIŞ girdinin kontrol edilmesi daha uygundur ( YANLIŞ girdinin sayısının daha az olduğu durumlarda) YANLIŞ ı test etmek için: if (! Gecerli girdi) if (x!= 2)
5 Dosya sonuna (EOF end of file) ulaşılıp ulaşılmadığını test etmek için: c = getchar(); while (c!= EOF) { printf( %c, toupper(c)); c = getchar(); Visual Studio da EOF = Ctrl c dir. toupper(c) ctype kütüphanesinde yer alır ve girilen karakteri büyük harfe çevirir. Bu nedenle ifadeyi kullanmak için main fonksiyonundan önce programa #include <ctype.h> eklenmesi gereklidir. Aşağıdaki örnek yardımıyla bu uygulama döngünün daha kısa olabilir. while (c=getchar())!= EOF) printf( %c, toupper(c)); Bu ifadede atama daha önce meydana gelmelidir. Döngüler ve Kontrol Yapıları Genel olarak iki çeşit kontrol sahip döngü vardır. 1. Sayma döngüleri: Yürütümü sağlayacak bilinen bir sayı kullanılır. Sayı artırılıp/azaltılarak ya da başka bir çeşit işlemle değişikliğe uğratılarak durdurma şartını sağladığı taktirde döngüye son verilir. 2. Olay kontrollü döngüler: Bir ya da daha fazla sayıda yürütülür. Döngünün kaç adet olacağı bilinmez. Döngü durduğunda sayısı bulunur. Yalnızca döngünün durma şartının ne olduğu açıklanmıştır. C dilinde genel olarak 3 çeşit döngü ifadesi vardır 1. for döngüsü 2. while döngüsü 3. do while döngüsü Genel olarak for döngüsü sayma, while ve do while döngüleri kontrol döngülerinde kullanılmakta ise de kullanımda herhangi biri iki çeşit kontrol döngüsünde de kullanılabilirer. Hatırlatma: While ve do while döngüleri kullanılırken dikkat edilmesi gereken nokta döngüyü durduracak bir ya da birden fazla ifadenin gerçekleşeceğinden emin olmaktır. while döngüsü do while ifadesine göre daha esnek olduğundan en yaygın olarak kullanılan döngü çeşididir. while kullanım şekli: while (boolean ifade){ blok;
6 while (boolean ifade) { blok; şeklinde yazım da kabul edilir. while (deger <= 0) { printf( Lutfen sifirdan buyuk bir deger girin: ); scanf( %d,°er); Yukarıdaki örnekte kullanıcıdan deger adında bir değişken girişi bekleniyor. Bu girdinin değerinin sıfırdan büyük olduğunun garanti altına alınması için ifadeyi aşağıdaki şekilde değiştirebiliriz: printf( Lutfen sifirdan buyuk bir deger girin: ); scanf( %d,°er); while (deger <= 0) { printf( Sayinin sifirdan buyuk olmasi gerek: ); scanf( %d,°er); while dögüsüne test döngüsü adı da verilir. Döngünğn gövdesinden önce bir boolean ifade kontrol edilir. While döngüsünün hiç yürütülmemesi de olasıdır. Örneğin, yukarıdaki örnekte girilen deger degişkeni sıfırdan büyük ise while döngüsünün gövdesi yürütülmeyecektir. Programlama Ödevi: Araba satıcılığı örneğine bir varsayımla başlayacağız: satacağımız araba tek tiptir ve bir binek arabası olacaktır (sedan). Bu arabanın çeşitli seçenekleri olacaktır: 2 ya da 4 kapılı, güneşlikli ya da güneşliksiz (sunroof), renk seçeneği, otomatik pencereler ve kilitler ya da normal (manuel) pencere ve kilitler. Bu nedenle kullanıcıya toplam dört seçenek sunmalıyız. Satış elemanının potansiyel alıcıya sorabileceği soruları düşün. Yazacağınız program soruları soran satış elemanı olacaktır. Satın alıcı, müşteri ise klavyeden cevapları giren kimse olacaktır. Son seçimin yapılması için bazı temel kurallar vardır: 1. Sedan kırmızı, mavi ya da yeşil renkte üretilmektedir. 2. Yalnızca mavi ve kırmızı arabalarda güneşlik seçeneği vardır. Güneşlik yeşil renkteki sedanlarda mevcut değildir. 3. Yeşil ve kırmızı aralar hem 2-kapılı hem de 4-kapılı olabilir. Mavi arabalarda yalnızca 4- kapılı seçeneği vardır. 4. Tüm renklerde otomatik pencere ve kilit seçeneği vardır. Yazacağınız program kullanıcıya öncelikle ne renk araba istediğini sormalıdır. Rengin ilk harfini kullanın ( K, M, ya da Y). Bu seçimde kullanıcının büyük ya da küçük harfle yanıt girmesine olanak tanıyın. Bunu yapmanın en kolay yolu derste gördüğümüz
7 toupper(c)makrosunu kullanmaktır. Bu makro harfi büyük harfe çevirecektir. Harf halihazırda büyük harfse işlem yapmayacaktır. Makroyu aşağıdaki şekilde kullanın: printf(kullaniciyi girdi icin uyarin...); /* musteriye uyari goruntule */ scanf("%c\n",&renk); /* musterinin secimini oku */ renk = toupper(renk); /* buyuk harfe cevir */ Daha sonra (müşterinin geçerli bir renk girdiğini varsayarsak) güneşlik hakkında bilgi almanız gerekir. Müşteri yeşil renkte araba seçerse güneşlik için hemen 'H' değeri atayabilirsiniz (Hayır anlamında). Daha sonra üç numaralı adıma geçin. Aksi taktirde, yani müşteri mavi ya da kırmızı renkte bir araba seçmişse güneşlik için değişkeni okutup kullanıcın E ya da H girmesini sağlayın. Daha önceki gibi bu değerleri de büyük harfe çevirin. Üçüncü adım olarak (daha önceki girdilerin doğru olduğunu varsayacak olursak) kapı sayısı hakkındaki bilgiyi elde etmeniz gerekir. Kullanıcı mavi renkli bir araba seçmişse kapı sayısını otomatik olarak 4 e atayın ve dördüncü adıma geçin. Eğer seçim maviden farklı ise (yeşil ya da kırmızı) kullanıcıya kaç kapılı araba istediğini sorun. Bu değer 2 veya 4 olmalıdır. Bu nedenle büyük/küçük harf ile ilgilenmeniz gerekmez. Kullanıcı 2 veya 4 kapıdan farklı sayıda seçim yaparsa (aynı şey renk ve güneşlik seçenekleri için de geçerlidir) programda uyarı mesajı görüntülenmeli ve daha sonraki işlemlere geçilmemelidir. Dördüncü adım (tüm girişlerin doğru olduğunu varsayarsak) kullanıcıya otomatik kilit ve pencere ya da manuel kilit ve pencere tercihinin sorulmasıdır. Tüm renklerde bu seçenek olduğundan dolayı seçilen arabanın renginden bağımsız olarak tüm seçenekler için bu soruyu sorabilirsiniz. Bu seçenek için Evet/Hayır anlamında E/H kullanın. Son olarak siparişi konfirme etmek amacıyla bir mesaj görüntülemeniz gerekir. Bu mesaj aşağıdaki örneğe benzemelidir: Mavi renkte manuel kilit ve pencereli, 4 kapili ve gunesligi olan bir araba siparis ettiniz. ya da Yesil renkte otomatik kilit ve pencereli, 2 kapili ve gunesligi olmayan bir araba siparis ettiniz. Uyarı mesajındaki tek farkın arabanın rengi, otomatik ya da manuel kelimesi, 2 veya 4, olan ya da olmayan kelimeleri olduğuna dikkat edin. Herhangi bir tercihte kullanıcı yanlış bir seçim yaptığı taktirde program yürütümü durdurulmalı ve tekrar tercih sorulmalıdır. Kullanıcıya bir sonraki sorunun sorulmaması ve yapmış olduğu tercihi düzeltmesi amacıyla if-else ifadeleri kullanın ve ekrana Yanlis bir tercih girdiniz, lutfen tekrar girin (E(e)/H(h)) ya da (Y(y), M(m), K(k)) şeklinde uyarı görüntüleyin. Bunu aşağıdaki örnekteki gibi gerçekleştirebilirsiniz: printf(... kullaniciyi renk icin uyarin...); /* secenek goruntule */ scanf("%c\n",&renk); /* renk oku */ renk = toupper(renk); /* buyuk harfe cevir */ if (renk!= 'R' && renk!= 'B' && renk!= 'G') { /* dogruluk kontrolu */ printf("gecersiz bir renk girdiniz.\n"); /* hataliysa hata mesaji */ hata = TRUE; /* hata bayragi */ else /* else hata yok, devam */... ikinci adima devam et...
8 'hata' değişkeni bizim bayrak (flama) olarak adlandırdığımız ve özel bir durumu temsilen kullanılan bir değişkendir. Bu örnekte, hata değişkeni kullanıcın doğru bir seçim yapıp yapmadığının kontrolünde kullanılmaktadır. Bu yolla, konfirmasyon mesajı görüntülenirken hata değişkeni DOĞRU (TRUE) ise bu adımı atlayabilirsiniz. Tüm seçenekler güzel ve düzgün bir formatta görüntülenmelidir. Örneğin, kapı sayısı ile ilgili soru sorulurken, aşağıdaki gibi bir örnek düşünülebilir: Arabaniz 2 ya da 4 kapili olabilir. 2-kapili model icin 2 tusuna basin. 4-kapili model icin 4 tusuna basin. Seceneginizi girin ==> Program Ödevi hakkında bilinmesi gerekenler Ödevin içine Programlama Odevi 1 yazmayin Öğrenci Numaranız, Adınız, Soyadınız ve Tarih gereklidir. Bir değişken deklare ettiğinizde (bildirdiginizde) o değişkenin amacını dokümante edin. Anlaşılır değişken isimleri kullanın. Printf ve scanf gibi temel fonksiyonlar için fazla dokümantasyona gerek yoktur. Dikkat edilecek diğer bir noktada kendinizi tekrar etmekten kaçınmanızdır. İhtiyacınz olmayan ifadelerden kaçının. if (sekil == U sekil == u ){ printf uyari mesaji scanf ( %f,&yukseklik); alan = 0.5 * taban * yukseklik; printf ( Alan %f bulundu, alan); else { alan = kenar*kenar; printf ( Alan %f bulundu, alan); bloğu şeklin üçgen ya da kare olmasında bağımsız, atanan alan değerini basacaktır. Bu nedenle blok: if (sekil == T sekil == t ){ printf uyari mesaji scanf ( %f,&yukseklik); alan = 0.5 * taban * yukseklik; else { alan = kenar*kenar; printf ( Alan %f bulundu, alan);
9 şeklinde yazılmalıdır. /* Bu program girilen sekle gore */ /* Ucgen ya da karenin alanini hesaplar */ /* Sonucu ekranda goruntuler */ # include <stdio.h> # include <ctype.h> int main(void) { char c; float alan = 0, kenar = 0, yukseklik = 0, taban = 0; printf("lutfen kare alani hesabi icin \"K\" ucgen alani hesabi icin \"U\" giriniz\n"); c = toupper(getchar()); while ((c!= 'K') && (c!= 'U')){ printf("yanlis giris yaptiniz!\n"); printf("lutfen kare alani hesabi icin \"K\" ucgen alani hesabi icin \"U\" giriniz\n"); c = toupper(getchar()); switch(c){ case 'U': printf("yuksekligi girin:\n"); scanf("%f",&yukseklik); printf("tabani girin:\n"); scanf("%f",&taban); alan = (float) 0.5 * taban * yukseklik; case 'K': printf ("Kenari girin:\n"); scanf ("%f", &kenar); alan = kenar * kenar; default: //eklenmek zorunda degil, ileride case eklenebilmesi amaciyla printf("alan %f bulundu\n",alan); return 0;
10 /* Bu program girilen harf notu klavyeden okur */ /* Ve toplam harf not sayisini hesaplayarak */ /* Sonucu ekranda goruntuler */ # include <stdio.h> int main(void) { int not; int aadet = 0, badet = 0, cadet = 0, dadet = 0, fadet = 0; printf( Harf notu giriniz: \n ); printf( Baska not girilmeyecekse EOF karakterine basiniz ); while(( not = getchar() )!= EOF) { switch(not) { /* while dongusu icinde switch*/ case A : case a : /* not A ya da a ise */ ++aadet; /* aadet degisken 1 artar*/ /* case blogu break ile sonlanir */ case B : case b : /* not B ya da b ise */ ++badet; /* badet degisken 1 artar*/ /* case blogu break ile sonlanir */ case C : case c : /* not C ya da c ise */ ++cadet; /* cadet degisken 1 artar*/ /* case blogu break ile sonlanir */ case D : case d : /* not D ya da d ise */ ++dadet; /* dadet degisken 1 artar*/ /* case blogu break ile sonlanir */ case F : case f : /* not F ya da f ise */ ++fadet; /* fadet degisken 1 artar*/ /* case blogu break ile sonlanir */ case \n : case : /* enter ve bos gozardi */ /* case blogu break ile sonlanir */ default: /* tum diger karakterler */ printf( Yanlis harf girdiniz. ); printf( Yeniden harf girin: ); /* Uyari */ /* case blogu break ile sonlanir */ printf( \nher harfin toplami: \n); printf( A: %d\n, aadet); printf( B: %d\n, badet); printf( C: %d\n, cadet); printf( D: %d\n, dadet); printf( F: %d\n, fadet); return 0;