Bölüm 08 Program Akışının Yönlendirilmesi blok if yönlendirmesi switch yönlendirmesi for döngüsü while döngüsü do ... while döngüsü Bir program komutların yazıldığı sırada akar. Ama çoğunlukla, bu akışı yönlendirmek gerekir. Bu iş için denetim yapılarını kullanırız. Bunlar başlıca üç gruba ayrılabilir: Bloklar, Yönlendiriciler ve Döngüler. Bu yapılardan birisine girince, program o yapı içinde istenen her işi yapar. Bilgisayarın karmaşık işleri yapmasını sağlayan bu yapılar altı tanedir. Bu yapılardan her birisi tek bir varlık olarak düşünülür, ama gerçekte her birisi birden çok deyim içeren birer yapıdır. Bunların her birisini örneklerle açıklayacağız. Blok Bir arada yürütülmesi istenen deyimleri içeren bir yapıdır. Bir blok içine giren program, aksi söylenmedikçe,o blok içindeki bütün deyimleri çalıştırır. Blok yapısının sözdizimi şöyledir: { deyimler } { } bloku içindeki deyimler istenildiği sayıda Java deyimlerinden oluşur. Hiç deyim içermeyen bloklara boş blok denir. Đç-içe bloklar olabilir. Deyimler, basit Java deyimleri olabileceği gibi, yapısal deyimler de olabilir. Bölüm 06: Operatörler 1 Örnekler { System.out.println("Ankara başkenttir. "); System.out.println(x); } { // Bu blok x ile y değişkenlerinin yerlerini değiştirir int yedek; // blok içinde kullanılacak geçici değişken yedek = x; // x değerini yedek adresine al x = y; // y değerini x adresine al y = yedek; // yedek değerini y nin adresine al } Blok içinde bildirimi yapılan bir değişken, o blok için bir yerel değişkendir. Bir blokun yerel değişkenine blok dışından erişilemez. Blok içinden dış bloka erişilebilir. Başka bir deyişle, blok içindeki bir operatör ya da metot, dış bloktaki değişkenleri ve metotları çağırabilir. Blokun işi bitince, yerel değişkene ayrılan adres yok olur. Bu nedenle, bir değişkenin erişilebirlik bölgesi (scope) o değişkenin tanımlandığı bloktur. Yönlendiriciler Program akışını, belli mantıksal koşullara göre istenen yöne saptıran denetim yapılarıdır. Bunlar da kendi içinde üçe ayrılır: if, if-else ve case yapıları. if deyimleri Program akışını, mantıksal koşullara (boolean) göre istenen yöne saptıran denetim yapılarıdır. Bu yapının üç türü vardır: tek seçenekli if, if-else ve çok seçenekli if. 1. Tek seçenekli if 2. if-else seçeneği 3. çoklu-durum seçeneği Şimdi bunların her birisini örneklerle açıklayacağız. Tek Seçenekli if Bazı deyimlerin işlemesini, ancak belirli koşulların sağlanması durumunda isteyebiliriz. Bu durumda if yönlendirmesini kullanırız. Bu yönlendirmenin sözdizimi yapısı aşağıdaki iki durumdan birisi gibidir. a. Eğer if denetiminden sonra bir tek deyim işleyecekse, if ( mantıksal_deyim ) deyim ; biçimindedir. b. Eğer if denetiminden sonra birden çok deyim işleyecekse, onlar bir blok ( { } ) içine alınır. if ( mantıksal_deyim ) { deyimler; } Eğer mantıksal_deyim true değerini alıyorsa deyim(ler) işlenir ve program if yapısından sonraki deyime geçer. Eğer mantıksal_deyim false değerini alıyorsa deyim(ler) işlenmeden atlanır ve program if yapısından sonraki deyimi işlemeye başlar. 2 t.karaçay : Java ile Nesne Programlama IfYapısı01.java package DenetimYapıları; import java.util.Scanner; class IfYapısı01 { public static void main(String[] args) { int n; Scanner in = new Scanner(System.in); System.out.println("Bir tamsayı giriniz: "); n = in.nextInt(); in.close(); // if yönlendirmesi if (n > 0) System.out.printf("Girdiğiniz %d sayısı pozitiftir. ", n); } } Çıktı Bir tamsayı giriniz: 45 Girdiğiniz 45 sayısı pozitiftir. Bu program koşarken, ekrana önce “Bir tamsayı giriniz: “ iletisi gelir. Bu iletiye karşılık, pozitif bir tamsayı girerseniz, örneğin 45, ekrana “Girdiğiniz 45 sayısı pozitiftir.” iletisi gelir. Eğer 0 ya da negatif bir tamsayı girerseniz, sayı pozitif olmadığı için, denetim if blokuna girmez. If blokundan sonraki deyime geçer. Ama if blokundan sonra başka deyim olmadığı için başka bir iş yapmadan program sona erer. Eğer kullanıcı int tipinden başka bir değer girerse, NextInt() metodu, girilen int tipi olmadığı için derleme hatası doğar ve aşağıdaki uyarıyı verir: Exception in thread "main" java.util.InputMismatchException Aşağıdaki program, if denetiminin bir mantıksal deyimi denetlediğini ve deyim true değerini alıyorsa if yapısına girildiğini göstermektedir. GeçersizIf.java /* if denetimi için mutlaka bir mantıksal deyim (boolean) gereklidir. */ package DenetimYapıları; class GeçersizIf{ public static void main(String[] args) { if (1) System.out.println("The if statement executed"); } } Bu program derleme anında şu hata mesajını verir: Exception in thread "main" java.lang.Error: Unresolved compilation problem: Type mismatch: cannot convert from int to boolean Bu ileti bize şunu söylüyor: Kaynak programdaki if(1) satırında sözdizimi hatası vardır. if anahtar Bölüm 06: Operatörler 3 sözcüğünden sonra mutlaka bir boolean deyim gelmelidir. Oysa, programda if sözcüğünden sonra yazılan (1) ifadesi bir boolean değildir. '1' boolean’a dönüştürülemez. [C dilinde program yazanlar, bu biçimin o dilde geçerli olduğunu anımsayacaklardır. Java dili C dili üzerine kurulmuş olmakla birlikte, onun bazı niteliklerini değiştirmiş, iyileştirmiştir. Dolayısıyla, C dilinde geçerli olan her şey Java dilinde geçerli değildir.] if-else yönlendirmesi Bazı durumlarda önümüze iki seçenek çıkar. Belirli bir koşulun sağlanması durumunda seçeneklerden birinin, aksi halde ötekinin işlemesi istenebilir. Başka bir deyişle, bir koşulun sağlanıp sağlanmamasına bağlı olarak, iki seçenekten birisini mutlaka yaptırmak gerekir. Bu durumda, if-else yapısını kullanırız. Bu yapının sözdizimi şöyledir: if ( mantıksal_deyim ) deyim-1 else deyim-2 Eğer deyim-1 ve deyim-2 yerinde işlenecek birden çok deyim varsa, onlar bir blok içine alınabilir: if ( mantıksal_deyim ) { deyimler-1 } else { deyimler-2 } Eğer mantıksal_deyim true değerini alıyorsa deyim(ler)-1 işlenir ve program if denetim yapısından sonraki deyimi işlemeye başlar. Eğer mantıksal_deyim false değerini alıyorsa deyim(ler)-1 işlenmeden atlanır ve deyim(ler)-2 işlenir. Sonra, program if denetim yapısından sonraki deyimi işlemeye başlar. Bu yapıda program ya deyim(ler)-1 ya da deyim(ler)-2 'yi işler. Aşağıdaki programları satır satır inceleyiniz. Her satırın işlevini algılayınız. IfElseYapısı.java package DenetimYapıları; import java.util.Scanner; class IfElseYapısı { public static void main(String[] args) { int i; Scanner scan = new Scanner(System.in); System.out.println("Bir tamsayı giriniz: "); i = scan.nextInt(); if (i > 0) System.out.printf("Girdiğiniz %d sayısı pozitiftir ", i); else System.out.printf("Girdiğiniz %d sayısı pozitif değildir ", i); } } 4 t.karaçay : Java ile Nesne Programlama Aşağıdaki program verilen bir yılın artık yıl olup olmadığını bulur. ArtıkYıl .java package DenetimYapıları; import java.util.Scanner; class ArtıkYıl { public static void main(String[] args) { int yıl; Scanner scan = new Scanner(System.in); System.out.println("Hangi yıl? (yyyy) :"); yıl = scan.nextInt(); if ((yıl % 4 == 0 && yıl % 100 != 0) || yıl % 400 == 0) System.out.printf(" %d yılı artık yıldır. Şubat ayı 29 çeker. ", yıl); else System.out.printf(" %d yılı artık değildir. Şubat ayı 28 çeker. ",yıl); } } Çıktılar Hangi yıl? (yyyy) : 2011 2011 yılı artık değildir. Şubat ayı 28 çeker. Hangi yıl? (yyyy) : 2012 2012 yılı artık yıldır. Şubat ayı 29 çeker. c. Çoklu-durum seçeneği Bazan ikiden çok seçenek ortaya çıkabilir. Bu durumlarda else-if denen çoklu-durum yapısını kullanırız: if (Koşul_1) Deyim_1; else if (Koşul_2) Deyim_2; else if (Koşul_3) Deyim_3; ... else Deyim_n; Bölüm 06: Operatörler 5 ElseIfYapısı01.java package DenetimYapıları; import java.util.Scanner; class ElseIfYapısı01 { public static void main(String[] args) { int i; Scanner scan = new Scanner(System.in); System.out.println("Bugün ısı kaç derecedir? "); i = scan.nextInt(); if (i < 10) System.out.println("Bugün hava soğuktur. "); else if (i < 20) System.out.println("Bugün hava serindir. "); else System.out.println("Bugün hava sıcaktır. "); } } Çıktı ElseifYapısı02.java package DenetimYapıları; import java.util.Scanner; class ElseifYapısı02 { public static void main(String[] args) { int i; Scanner scan = new Scanner(System.in); System.out.println("Bir tamsayı giriniz "); i = scan.nextInt(); if (i % 3 == 0) System.out.printf("%d tamsayısı 3 ile tam bölünür. ", i); else if (i % 2 == 0) System.out.printf("%d tamsayısı çitf sayıdır. ", i); else System.out.printf( "%d tamsayısı tek sayıdır, ama 3 ile tam bölünmez. ", i); } } Çıktı Bir tamsayı giriniz : 56 56 tamsayısı çitf sayıdır. Aşağıdaki programlar else if yapılarının istenildiği kadar iç-içe konulabileceğini göstermektedir. 6 t.karaçay : Java ile Nesne Programlama ElseifYapısı03.java package DenetimYapıları; import java.util.Scanner; class ElseifYapısı03 { public static void main(String[] args) { int i; Scanner scan = new Scanner(System.in); System.out.println("Not ortalamanızı giriniz : "); i = scan.nextInt(); if (i > 90) System.out.printf("Puanınız else if (i > 75) System.out.printf("Puanınız else if (i > 60) System.out.printf("Puanınız else if (i > 50) System.out.printf("Puanınız else System.out.printf("Puanınız %d ise notunuz A olur. ", i); %d ise notunuz B olur. ", i); %d ise notunuz C olur. ", i); %d ise notunuz D olur. ", i); %d ise notunuz F olur. ", i); } } Çıktı Not ortalamanızı giriniz : 85 Puanınız 85 ise notunuz B olur. ElseifYapısı04.java package operators; import java.io.IOException; public class ElseifYapısı04 { public static void main(String[] args) { char c; int inChar = 0; System.out.println("Bir tuşa basınız :"); try { inChar = System.in.read(); } catch (IOException e) { System.out.println("Giriş hatası"); } c = (char) inChar; if (Character.isUpperCase(c)) Bölüm 06: Operatörler 7 System.out.println("Büyük harf girdiniz."); else if (Character.isLowerCase(c)) System.out.println("Küçük harf girdiniz."); else if (Character.isDigit(c)) System.out.println("Bir rakam girdiniz."); else System.out.println("Alfasayısal olmayan bir karakter girdiniz."); } } Çıktı Programın farklı koşmalarında, girilen karaktere bağlı olarak çıktılar şöyle olabilir. Bir tuşa basınız: R Büyük harf girdiniz. Bir tuşa basınız: g Küçük harf girdiniz. Bir tuşa basınız: 8 Bir rakam girdiniz. Bir tuşa basınız: & Alfasayısal olmayan bir karakter girdiniz. switch denetim yapısı Program akışı bir yerde çok sayıda seçenekle karşılaşırsa, iç-içe else if denetimi yerine switch denetimi daha kolay olur. Sözdizimi şöyledir: Sözdizimi (syntax) switch (seçici) { case seçki-1: deyim-1; sıçrama-1; case seçki-2: deyim-2; sıçrama-2 ... 8 t.karaçay : Java ile Nesne Programlama [default: deyim sıçrama] } Çıktı Bu yapıda case ifadelerinin sayısı için bir kısıt yoktur, gerektiği kadar case ifadesi konulabilir. Bu sözdiziminde geçen terimlerin açıklanması: seçici Seçici bir değişken veya bir ifade olabilir. Seçici değişken olduğunda byte,short, int, char,enum ya da String tiplerinden herhangi birisinden bir literal (sabit değer) almalıdır. Seçici bir ifade ise bu türlerden literal bir değer veren formüldür. Burada formül, matematiksel formüllerde olduğu gibi, bir sonuç veren deyim olarak algılanmalıdır. String tipi, Java SE 7 sürümünden sonra kullanılabilir olmuştur. Önceki sürümlerde String tipi secici tip olarak kullanılamaz. seçki Seçici değişkenin veya seçici ifadenin aldığı bir değerdir. Bu değer seçicinin alabildiği yukarıdaki veri tiplerinden her hangi birisi olabilir; tabii, bu değer bir literal (sabit değer) olmalıdır. deyim Seçici-değerine bağlı olarak yönlenilen bir seçenekte yapılacak iş(ler)i belirleyen deyim veya deyimlerden oluşan bir bloktur. sıçrama Bir seçeneğe yönlenen program, o seçenekteki işleri yapınca ya switch yapısının dışına çıkar ya da başka bir seçeneğe yönlendirilebilir. switch yapısından çıkmak için break; deyimi kullanılır. break deyimi, akışı switch yapısından çıkarır ve switch yapısından sonraki ilk deyime gönderir. Bazan bir seçenekteki işler bitince, akışı switch yapısından sonraki ilk deyime göndermek yerine başka bir seçeneğe göndermek gerekebilir. Bunun için goto deyimi kullanılır. default Đsteğe bağlı bir seçenektir. Seçicinin değeri case ile belirlenen hiçbir seçki ile uyuşmadığı zaman, yapılmasını istediğimiz işler için gerekli deyim(ler)i bu seçeneğe yazarız. Hiçbir case yönlendirmesi gerçekleşemediğinde default seçenek çalışır. Seçicinin değeri mutlaka case'lerdeki seçkilerden birisine eşit olacağı garanti edilen durumlarda, default seçeneğini yazmanın gereği yoktur. switch yapısının nasıl kullanıldığını aşağıdaki örnekte göreceğiz. Switch01.java package DenetimYapısı; import java.util.Scanner; class Switch01 { Bölüm 06: Operatörler 9 public static void main(String[] args) { int ay; int yıl; int günSayısı = 0; Scanner scan = new Scanner(System.in); System.out.println("Hangi yıl ? "); yıl = scan.nextInt(); System.out.println("Hangi ay ? ay = scan.nextInt(); "); switch (ay) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: günSayısı = 31; break; case 4: case 6: case 9: case 11: günSayısı = 30; break; case 2: if (((yıl % 4 == 0) && !(yıl % 100 == 0)) || (yıl % 400 == 0)) günSayısı = 29; else günSayısı = 28; break; default: System.out.println("Geçersiz ay"); break; } System.out.println("Gün sayısı = " + günSayısı); } Çıktı Hangi yıl ? 2009 Hangi ay ? 2 Gün sayısı = 28 Đpucu Unutmayınız, seçici için byte, short, int, long, char, enum ya da String tiplerinden bir değişken kullanılır. float ve double tipinden seçici kullanılamaz. Seçici değişkenin alacağı sabit değerlere göre program akışı istenen seçeneğe sapar. Burada herhangi bir deyim-k birden çok deyim içeriyorsa, onlar blok içine alınır ve tek deyimmiş gibi işlenir. 10 t.karaçay : Java ile Nesne Programlama Switch02.java package DenetimYapıları; public class Switch02 { public static void main(String[] args) { int ay = 7; String monthString; switch (ay) { case 1: System.out.println("Ocak"); break; case 2: System.out.println("Şubat"); break; case 3: System.out.println("Mart"); break; case 4: System.out.println("Nisan"); break; case 5: System.out.println("Mayıs"); break; case 6: System.out.println("Haziran"); break; case 7: System.out.println("Temmuz"); break; case 8: System.out.println("Ağustos"); break; case 9: System.out.println("Eylül"); break; case 10: System.out.println("Ekim"); break; case 11: System.out.println("Kasım"); break; case 12: System.out.println("Aralık"); break; } } } Çıktı Temmuz Switch03.java package DenetimYapıları; Bölüm 06: Operatörler 11 import java.util.Scanner; class Switch03 { public static void main(String[] args) { int puan; Scanner scan = new Scanner(System.in); System.out.println("Karne notunuz nedir?"); puan = scan.nextInt(); switch (puan) { case 'A': System.out.println("Pekiyi"); break; case 'B': System.out.println("Đyi"); break; case 'C': System.out.println("Orta"); break; case 'D': System.out.println("Hmmmm...."); break; case 'F': System.out.println("Daha iyisini başarabilirsin!"); break; default: System.out.println("Başarı notun ne?"); break; } } } Çıktı Karne notunuz nedir? 67 Orta Switch04.java package DenetimYapıları; import java.util.Scanner; class Switch04 { public static void main(String[] args) { int puan; Scanner scan = new Scanner(System.in); System.out.println("Not ortalamanız nedir?"); 12 t.karaçay : Java ile Nesne Programlama puan = scan.nextInt(); switch (puan / 10) { case 9: System.out.println("Notunuz break; case 8: System.out.println("Notunuz break; case 7: System.out.println("Notunuz break; case 6: System.out.println("Notunuz break; case 5: System.out.println("Notunuz break; default: System.out.println("Notunuz break; } A dır. "); B+ dir. "); B- dir. "); C dir. "); D dir. "); F dir. "); } } Çıktı Not ortalamanız nedir? 89 Notunuz B+ dir. Aşağıdaki program bir otomatik çikolata makinasının çalışmasını sağlamaktadır. Makinaya 3 boy çikolata konulmaktadır: küçük, orta, büyük. Bunların fiyatları, sırasıyla 250, 500 ve 750 YTL dir. switch-case yapısını kullanan programda sıçrama goto deyimi ile yapılmaktadır. Programı inceleyiniz ve goto deyimlerinin oynadığı rolü algılayınız. Switch05.java package DenetimYapıları; import java.util.Scanner; class Switch05 { public static void main(String[] args) { int n; Scanner scan = new Scanner(System.in); System.out.println("Hangi çikolata : 1=Küçük 2=Orta 3=Büyük"); n = scan.nextInt(); int bedel = 0; switch (n) { case 1: bedel += 250; break; Bölüm 06: Operatörler 13 case 2: bedel += 500; break; case 3: bedel += 750; break; default: System.out .println("Geçersiz seçim yaptınız. Lütfen 1, 2, 3 sayılarından birisini seçiniz."); break; } if (bedel != 0) System.out.printf("Lütfen %d YTL atınız. %n", bedel); System.out.println("Afiyet olsun! Gene bekleriz!"); } } Çıktılar Program 3. seçenek için koşturulursa, aşağıdaki çıktı görülecektir. Deneyiniz. Hangi çikolata : 1=Küçük 2=Orta 3=Büyük 3 Lütfen 752 YTL atınız. Afiyet olsun! Gene bekleriz! Switch06.java package operators; import java.util.Scanner; public class Switch06 { public static void main(String[] args) { int a, b, c; int durum = -1; Scanner scan = new Scanner(System.in); System.out.println("Üç tamsayı giriniz :"); a = scan.nextInt(); b = scan.nextInt(); c = scan.nextInt(); if (a > b && a > c) { durum = 1; } else if (b > c) { durum = 2; } else { durum = 3; } switch (durum) { case 1: System.out.println("Sayıların en büyüğü = " + a); break; 14 t.karaçay : Java ile Nesne Programlama case 2: System.out.println("Sayıların en büyüğü = " + b); break; case 3: System.out.println("Sayıların en büyüğü = " + c); break; default: System.out.println("Belirlenemedi!"); } } } Çıktı Üç tamsayı giriniz : 34 -67 23 Sayıların en büyüğü = 34 Bölüm 06: Operatörler 15