Java ile Nesne Yönelimli Programlama · Ders Notu
Bölüm 1.4: Akış Diyagramları
Bir program yazılmadan önce çözümün kâğıt üzerinde planlanması gerekir. Akış diyagramı bu planı kutular ve oklarla çizer. Not, akış diyagramlarının sembollerini ve çizim kurallarını tanıtır; her sembolün Java'daki karşılığını gösterir. Ardından bütün algoritmaların yapı taşı olan üç akış türü gelir: sıralı, koşullu ve tekrarlı akış. Her tür bir diyagram, o diyagramdan yazılmış bir Java programı ve programın adım adım izlenmesiyle anlatılır. Döngülerde sık kullanılan sayaç, biriktirici, bayrak ve nöbetçi değer kalıpları, erken çıkış ve iç içe döngüler ayrıca ele alınır. Son kesimler alt programı, yani Java'daki metodu, diyagramın masa başında izlenmesini ve test durumlarının seçimini işler. Örneklerdeki bütün Java programları JDK 21 ile derlenip çalıştırılmıştır; izleme tablolarındaki değerler bu çalıştırmalarla denetlenmiştir.
Öğrenme çıktıları
- Kavram
- Algoritma ile akış diyagramı arasındaki ilişkiyi açıklamak; akış diyagramının ne işe yaradığını ve nerede yetersiz kaldığını söylemek.
- Semboller
- Başla/Bitir, giriş, işlem, karar, döngü, yazdır, bağlantı noktası ve alt program sembollerini tanımak; her adım için doğru sembolü seçmek; çizim kurallarını uygulamak.
- Kontrol yapıları
- Sıralı, koşullu ve tekrarlı akışı ayırt etmek; her biri için diyagram çizmek; yapısal diyagramı yapısal olmayandan ayırmak.
- İzleme
- Bir diyagramı ya da programı verilen girdiyle izleme tablosu kurarak adım adım yürütmek; sınır hatalarını ve sonsuz döngüleri fark etmek.
- Diyagramdan Java'ya
- Her sembolü Java karşılığına çevirmek:
nextInt(), atama,if/else,while,for,println, metot çağrısı; derleyicinin yakaladığı ve yakalayamadığı hataları ayırmak. - Tasarım ve sınama
- Basit bir problemi önce diyagramla planlayıp sonra programa dönüştürmek; her yolu ve sınır değerlerini deneyen test durumları seçmek.
1.4.1Algoritma ve akış diyagramı
Bir Java programı, bilgisayarın sırayla yürüttüğü deyimlerden oluşur. Ancak program yazmaya doğrudan klavyenin başında başlamak çoğu zaman hatalı bir sonuç verir. Önce problemin nasıl çözüleceği düşünülür, çözümün adımları belirlenir, sonra bu adımlar programlama diline çevrilir. Akış diyagramı, adımları belirleme aşamasında kullanılan en eski ve en yaygın araçlardan biridir.
1.4.1.1Algoritmadan çizime
Algoritma (algorithm), bir problemi çözmek ya da bir görevi yerine getirmek için izlenecek adımların sıralı ve sonlu bir planıdır. Her adım açıktır; aynı girdiyle her seferinde aynı sonuca ulaşılır.
Akış diyagramı (flowchart), bir algoritmanın adımlarını, adımlar arasındaki bağlantıları ve kontrol mekanizmalarını görsel olarak gösteren çizimdir. Her adım bir sembolle çizilir. Adımların çalışma sırası oklarla, yani akış çizgileriyle gösterilir.
İki tanım arasındaki ilişki bir yemek tarifiyle açıklanabilir. Tarif bir algoritmadır: malzemeleri hazırla, suyu kaynat, çayı demle. Aynı tarifin kutular ve oklarla çizilmiş hâli ise akış diyagramıdır. Tarifi yazıyla anlatmak da mümkündür. Ama “su kaynamadıysa bekle, kaynadıysa demle” gibi bir karar ya da “kaynayana kadar bekle” gibi bir tekrar yazıda kolayca gözden kaçar. Çizimde ise karar bir eşkenar dörtgen, tekrar da geriye dönen bir ok olarak hemen göze çarpar. Şekil 1.4.1 bu tarifin diyagramıdır.
Diyagram yukarıdan aşağıya okunur. Yürütme yuvarlak uçlu Başla kutusunda başlar ve oklar boyunca ilerler. “Çaydanlığa su koy” bir işlemdir ve dikdörtgenle çizilir. “Su kaynadı mı?” bir sorudur; cevabı Evet ya da Hayır olduğu için eşkenar dörtgenle çizilir ve iki çıkışı vardır. Hayır çıkışı “Bekle” kutusuna, oradan da geriye, sorunun kendisine döner. Böylece soru, cevap Evet olana kadar tekrar tekrar sorulur. Bu küçük çizimde üç akış türünün üçü de vardır: arka arkaya gelen adımlar, bir karar ve bir tekrar.
Akış diyagramı bir programlama diline bağlı değildir. Aynı diyagramdan Java, C ya da Python programı yazılabilir. Bu yüzden diyagram, programın kendisi değil, programın planıdır. Planın doğru olduğu kâğıt üzerinde denetlenir; ancak ondan sonra kod yazılır.
1.4.1.2Faydaları ve sınırları
Akış diyagramının en önemli faydası, karmaşık bir süreci tek bakışta görülebilir hâle getirmesidir. Bir programda hangi adımın hangisinden sonra geldiği, hangi durumda bir adımın atlandığı ya da tekrarlandığı oklarla açıkça görünür. Bu görünürlük hataların kod yazılmadan önce bulunmasını sağlar. Örneğin bir karar kutusunun yalnızca Evet çıkışı çizilmişse, Hayır durumunda ne olacağının düşünülmediği hemen anlaşılır.
Diyagramın ikinci faydası belgelemedir. Bir süreç, örneğin bir kayıt işlemi ya da bir makinenin çalışma adımları, raporlarda ve teknik belgelerde akış diyagramıyla anlatılır. Üçüncü faydası ortak bir dil sağlamasıdır. Bir ekipte herkes aynı programlama dilini bilmeyebilir, ama akış diyagramını herkes okuyabilir.
Diyagramın sınırları da vardır. Büyük bir programın diyagramı birkaç sayfaya taşar ve okunması zorlaşır. Algoritma değiştiğinde diyagramın yeniden çizilmesi gerekir; bu da zaman alır. Ayrıntı arttıkça sembol sayısı da artar. Bu durumda algoritmayı yarı doğal dille yazan sözde kod (pseudocode) daha pratiktir. Uygulamada akış diyagramı küçük ve orta büyüklükteki algoritmalar için, ya da büyük bir programın ana hatlarını göstermek için kullanılır.
Bir programın geliştirilmesi genellikle Şekil 1.4.2 sırasıyla ilerler. Problem tanımlanır, çözüm adımları yani algoritma belirlenir, algoritma akış diyagramına dökülür, diyagram Java programına çevrilir ve program çalıştırılıp sınanır. Sınama yanlış bir sonuç verirse geri dönülür ve algoritma düzeltilir.
1.4.2Semboller ve çizim kuralları
Akış diyagramındaki her sembolün biçimi, o adımın türünü söyler. Okuyucu kutunun içindeki yazıyı okumadan önce bile bir adımın okuma mı, hesaplama mı, karar mı olduğunu biçiminden anlar. Bu yüzden sembollerin doğru seçilmesi diyagramın anlaşılır olmasının ilk koşuludur.
1.4.2.1Temel semboller
Sembollerin biçimleri uluslararası bir standarda, ISO 5807'ye dayanır. Şekil 1.4.3 en sık kullanılan sekiz sembolü gösterir.
Başlangıç/Bitiş sembolü kenarları yuvarlatılmış bir dikdörtgen, yani ovaldir. Her diyagramda bir Başla sembolü bulunur; yürütme oradan başlar. Bitir sembolü algoritmanın sona erdiği yerdir.
Giriş sembolü paralelkenardır ve dışarıdan veri alınan adımı gösterir. “Oku sayı” yazılı bir paralelkenar, kullanıcının klavyeden bir sayı gireceği ve bu sayının sayı adlı değişkene konacağı anlamına gelir. Bazı kaynaklar çıkışı, yani ekrana yazmayı da paralelkenarla çizer. Bu notta ekrana yazma için ayrı bir sembol, alt kenarı dalgalı Yazdır sembolü kullanılır. Dalgalı kenar bir kâğıt yaprağını andırır; sembolün eski adı da “belge”dir.
İşlem sembolü düz bir dikdörtgendir. İçine bir hesaplama ya da atama yazılır: “alan = a × b”, “sayaç = sayaç + 1” gibi. İşlem kutusunun tek girişi ve tek çıkışı vardır.
Karar sembolü eşkenar dörtgendir. İçine cevabı Evet ya da Hayır olan bir soru yazılır: “sayı > 0 ?”. Karar kutusu, iki çıkışı olan tek semboldür. Çıkışlardan biri Evet (E), öteki Hayır (H) diye etiketlenir.
Döngü sembolü uzunlamasına bir altıgendir. Belirli sayıda tekrarlanan bir işi tek kutuda özetler: “i = 1; i ≤ 10; i++”. Altıgenin içindeki üç parça başlangıç, koşul ve güncellemedir. Bağlantı noktası küçük bir çemberdir. Birden çok okun birleştiği yeri gösterir; örneğin bir kararın iki kolu işini bitirince bağlantı noktasında buluşur. Akış çizgisi ise sembolleri birbirine bağlayan oktur. Yürütme her zaman okun gösterdiği yönde ilerler.
1.4.2.2Sembollerin Java karşılıkları
Bir diyagram Java programına çevrilirken her sembol belirli bir Java yapısına karşılık gelir. Tablo 1.4.1 bu eşlemeyi verir. Tablo, diyagramdan koda geçişte bir sözlük gibi kullanılabilir.
| Sembol | Diyagramdaki yazı | Java karşılığı |
|---|---|---|
| Başla / Bitir | Başla … Bitir | public static void main(String[] args) { … } |
| Giriş | Oku sayı | int sayi = giris.nextInt(); |
| İşlem | sonuç = sayı1 + sayı2 | int sonuc = sayi1 + sayi2; |
| Karar | sonuç = 0 ? | if (sonuc == 0) { … } else { … } |
| Karar + geri ok | sayaç ≤ 10 ? | while (sayac <= 10) { … } |
| Döngü | i = 1; i ≤ 10; i++ | for (int i = 1; i <= 10; i++) { … } |
| Yazdır | Yaz sonuç | System.out.println(sonuc); |
Tablonun ilk satırı, diyagramın Başla ve Bitir sembolleri arasındaki her şeyin Java'da main metodunun gövdesine yazılacağını söyler. Program main metodunun ilk satırından başlar, son satırına gelince biter. Giriş sembolü için Java'da java.util.Scanner sınıfı kullanılır. Program başında Scanner giris = new Scanner(System.in); satırıyla klavyeden okuyan bir nesne oluşturulur. Ardından her “Oku” kutusu için giris.nextInt() (tam sayı), giris.nextDouble() (ondalıklı sayı) ya da giris.next() (sözcük) çağrılır.
Karar sembolünün iki farklı Java karşılığı vardır. Geri dönen ok yoksa karar bir if deyimidir: soru bir kez sorulur, cevaba göre iki koldan biri çalışır. Kararın kollarından birinden çıkan ok karar kutusunun üstüne geri dönüyorsa yapı bir döngüdür ve while ile yazılır. Yani aynı eşkenar dörtgen, okların nereye gittiğine göre if de olabilir, while da. Altıgen döngü sembolü ise doğrudan for deyimine karşılık gelir.
Çeviride en çok hata yapılan nokta eşittir işaretidir. Diyagramdaki işlem kutusunda “=” atama demektir: sağdaki değer hesaplanır, soldaki değişkene konur. Karar kutusunda ise “=” karşılaştırma demektir: iki değer eşit mi diye sorulur. Java bu iki anlamı farklı işaretlerle yazar: atama =, karşılaştırma == ile. Benzer biçimde diyagramdaki “mod” (bölümden kalan) Java'da % operatörüdür; ≤ ve ≥ işaretleri <= ve >=, ≠ işareti != olarak yazılır.
Karar kutusundaki “sonuç = 0 ?” sorusu Java'ya if (sonuc = 0) diye çevrilir. Bu satır derlenmez. JDK 21'in derleyicisi şu iletiyi verir: error: incompatible types: int cannot be converted to boolean. sonuc = 0 bir atamadır ve değeri int türünde 0'dır; if ise boolean bir koşul bekler. Doğrusu if (sonuc == 0)'dır. C dilinde aynı hata derlenir ve sessizce yanlış çalışır; Java'nın tür denetimi bu hatayı derleme sırasında yakalar.
1.4.2.3Diğer semboller
Temel semboller çoğu diyagram için yeterlidir. Uzun diyagramları bölmek ya da verinin nereye yazıldığını göstermek için ISO 5807'de başka semboller de vardır. Şekil 1.4.4 bunlardan altısını gösterir.
// yorumu.Alt program sembolü, iki yanına dikey çizgi eklenmiş bir dikdörtgendir. Ayrı bir yerde çizilmiş adım dizisini çağırır; Java'daki karşılığı bir metot çağrısıdır. Uzun bir diyagramın bir parçası ayrı çizilir ve ana diyagramda bu sembolle çağrılır. Sayfa dışı bağlantı, bir diyagram tek sayfaya sığmadığında kullanılır. Birinci sayfanın sonundaki beşgene bir harf yazılır, örneğin B. İkinci sayfanın başındaki beşgende de aynı harf bulunur; okuyucu akışı bu harfle izler.
Veri deposu sembolü bir silindirdir ve kalıcı bir yere, örneğin bir dosyaya ya da veri tabanına yazılan veriyi gösterir. Elle giriş sembolü klavyeden yapılan girişi ayrıca vurgulamak için kullanılır; birçok kaynak bunun yerine paralelkenarı tercih eder. Açıklama sembolü akışın parçası değildir. Bir kutunun yanına not düşmeye yarar; Java'daki // yorumuna benzer. Derleyici yorumları nasıl yok sayıyorsa, diyagramı izleyen kişi de açıklamaları yürütmeye katmaz.
Hazırlık sembolünün biçimi döngü sembolüyle aynıdır. ISO 5807'de bu altıgenin adı “hazırlık”tır ve bir işe başlamadan önceki ayarı gösterir. Döngünün başlangıç değerini, koşulunu ve güncellemesini tek kutuda toplamak için bu sembolün kullanılması da buradan gelir.
1.4.2.4Çizim kuralları
Bir akış diyagramı birkaç adımda oluşturulur. Önce işlemler belirlenir: hangi girdiler okunacak, hangi hesaplar yapılacak, hangi çıktılar yazılacak? Sonra adımlar mantıklı bir sıraya dizilir. Ardından bütün semboller akış çizgileriyle birbirine bağlanır. Son olarak koşula bağlı adımlar için karar noktaları eklenir.
Çizimin okunabilir olması için şu kurallara uyulur:
- Diyagramda tek bir Başla ve en az bir Bitir bulunur. İki ayrı Bitir sembolü kurala aykırı değildir; ama iki Başla sembolü, yürütmenin nereden başlayacağını belirsiz bırakır.
- Akış yukarıdan aşağıya ve soldan sağa okunur. Bu yönün dışına çıkan oklar, örneğin bir döngünün geri oku, okun ucuyla açıkça gösterilir.
- Karar dışındaki her sembolün tek bir çıkışı vardır. Yalnızca karar sembolünün iki çıkışı olur.
- Karar çıkışları mutlaka Evet/Hayır (E/H) diye etiketlenir. Etiketsiz bir çıkış hangi cevaba ait olduğunu söylemez.
- Çizgiler birbirini kesmez. Kesişme kaçınılmazsa çizgiler bir bağlantı noktasında birleştirilir.
- Kutulara kısa ve açık ifadeler yazılır: “Oku a, b”, “alan = a × b”, “Yaz alan”. Uzun cümleler diyagramı kalabalıklaştırır.
1.4.2.5Adım adım çizim: dikdörtgenin alanı
Kurallar küçük bir problem üzerinde uygulanabilir. Problem, kenar uzunlukları klavyeden girilen bir dikdörtgenin alanını bulmaktır.
Problem: klavyeden okunan iki kenar uzunluğuna göre dikdörtgenin alanını ekrana yazmak.
- İskelet. Önce bir Başla ve bir Bitir sembolü çizilir. Bütün adımlar bu ikisinin arasına girecektir.
- Girdiler. Alanı hesaplamak için iki kenar uzunluğu gerekir. Bunlar klavyeden okunur: “Oku a, b” yazılı bir paralelkenar eklenir.
- İşlem. Alan, iki kenarın çarpımıdır. “alan = a × b” yazılı bir dikdörtgen eklenir. Bu kutu çarpımı hesaplar ve sonucu alan değişkenine atar.
- Çıktı. Hesaplanan alan ekrana yazılır: “Yaz alan” yazılı bir Yazdır sembolü eklenir.
- Bağlama. Semboller mantıklı sırayla akış çizgileriyle bağlanır: Başla → Oku → İşlem → Yaz → Bitir. Bu problemde karar noktası yoktur; akış sıralıdır.
- Sınama. Diyagram bir girdiyle denenir. a = 4 ve b = 3 girilirse alan = 4 × 3 = 12 hesaplanır ve ekranda 12 görülür. Beklenen sonuç da 12'dir; diyagram doğru çalışır.
Diyagram hazır olduğunda Java'ya çevirmek mekanik bir iştir. Her sembol Tablo 1.4.1 yardımıyla bir satıra dönüşür:
import java.util.Scanner;
public class DikdortgenAlani {
public static void main(String[] args) {
Scanner giris = new Scanner(System.in);
int a = giris.nextInt();
int b = giris.nextInt();
int alan = a * b;
System.out.println(alan);
giris.close();
}
}Paralelkenardaki “Oku a, b” iki ayrı nextInt() çağrısı olur. İşlem kutusu int alan = a * b; satırına dönüşür; diyagramdaki × işareti Java'da * ile yazılır. Yazdır sembolü System.out.println(alan); satırıdır. Program 4 ve 3 girdisiyle çalıştırıldığında ekrana 12 yazar; bu, diyagramın sınamasındaki sonuçla aynıdır. Her kutu yalnızca bir kez çalışır, hiçbir adım atlanmaz ve hiçbir adıma geri dönülmez. Bu özellikler sıralı akışın tanımını oluşturur.
1.4.3Kontrol yapıları
Bir programın hangi deyimi hangi sırayla çalıştıracağına kontrol akışı denir. Akış diyagramında kontrol akışı okların kendisidir. Oklar ne kadar karışık görünürse görünsün, iyi çizilmiş her diyagram yalnızca üç temel yapıdan kurulur.
1.4.3.1Üç akış türü
Sıralı akış (sequential flow), adımların yazıldıkları sırayla ve her birinin tam bir kez çalıştığı akıştır. Koşullu akış (conditional flow), bir koşulun sonucuna göre iki ya da daha çok yoldan birinin seçildiği akıştır. Tekrarlı akış ya da döngü (loop), bir koşul sağlandığı sürece bazı adımların tekrar tekrar çalıştığı akıştır.
Şekil 1.4.6 üç yapıyı yan yana gösterir. Sıralı akışta oklar hep aşağı iner, hiçbir ok ayrılmaz ya da geri dönmez. Koşullu akışta bir karar kutusundan iki ok çıkar; bu iki yol daha sonra bir bağlantı noktasında yeniden birleşir. Tekrarlı akışta ise bir ok geriye, karar kutusunun üstüne döner. Geri dönen ok bir döngünün kesin işaretidir.
Bu üç yapının yeterli olduğu matematiksel olarak gösterilmiştir. Corrado Böhm ve Giuseppe Jacopini 1966'da yayımladıkları makalede şu sonucu kanıtladılar:
Hesaplanabilen her algoritma yalnızca üç yapı kullanılarak yazılabilir: sıra, seçim ve tekrar. Bu yapılar ya art arda dizilir ya da birbirinin içine yerleştirilir.
Teoremin Java'daki karşılığı açıktır. Sıra, art arda yazılmış deyimlerdir. Seçim if/else, tekrar while ve for deyimleridir. Java'nın öteki kontrol deyimleri, örneğin switch ya da do-while, bu üç yapının kısa yazılışlarıdır. Teorem, karmaşık bir problemin bile bu üç parçayla çözülebileceğini garanti eder. Bir diyagram tasarlanırken de aynı fikir izlenir: problem sıra, seçim ve tekrar parçalarına bölünür ve parçalar birleştirilir.
1.4.3.2Yapısal ve yapısal olmayan diyagram
Yapısal diyagram (structured flowchart), her kontrol yapısının tek girişi ve tek çıkışı olan akış diyagramıdır. Yapılar ya art arda dizilir ya da birbirinin içine yerleştirilir; bir yapının ortasına dışarıdan ok girmez.
Şekil 1.4.7'nin solundaki diyagramda K kararıyla başlayan blok kesikli bir çerçeveyle gösterilmiştir. Bloğa üstten tek bir ok girer, alttan tek bir ok çıkar. B ve C kolları blok içinde kalır ve bağlantı noktasında birleşir. Bu bloğun içinde ne olduğunu bilmeden onu tek bir kutu gibi düşünmek mümkündür. Diyagramı okuyan kişi önce A'yı, sonra bloğu, sonra D'yi görür.
Sağdaki diyagramda ise L kararının Evet oku öteki kolun ortasına, C kutusuna girer. Hayır oku ise geriye, A'ya döner. Bu durumda C kutusuna iki farklı yoldan gelinebilir; A'ya da hem Başla'dan hem de L'den ulaşılır. Bir kutuya hangi yoldan gelindiğini anlamak için bütün diyagramı izlemek gerekir. Oklar spagetti gibi birbirine dolanır; bu yüzden böyle akışa “spagetti akış” denir. Spagetti akışı izlemek ve içindeki hatayı bulmak zordur.
Eski programlama dillerinde bu tür atlamalar goto deyimiyle yazılırdı. goto etiket; deyimi yürütmeyi programın herhangi bir yerine götürürdü. Java'da goto ayrılmış bir sözcüktür ama hiçbir anlamı yoktur; kullanılamaz. goto basa; yazılan bir program JDK 21'de error: illegal start of expression iletisiyle derlenmez. Java'nın tasarımcıları bu sözcüğü bilinçli olarak dilin dışında tutmuştur.
Java'da sınırlı iki atlama vardır: break ve continue. break içinde bulunduğu döngüyü hemen bitirir. continue döngünün o turunun geri kalanını atlar ve sonraki tura geçer. Bu iki deyim yürütmeyi programın rastgele bir yerine değil, yalnızca bulundukları döngünün sonuna ya da başına götürür. Böylece spagetti akış oluşmaz.
Böhm–Jacopini teoreminin pratik bir sonucu da şudur: yapısal olmayan her diyagram, gerekirse boolean bir bayrak değişkeni eklenerek yapısal biçime dönüştürülebilir. Bayrak, bir olayın olup olmadığını tutar; atlamanın yerine bu değişken sınanır.
1.4.4Sıralı akış
Sıralı akış üç yapının en basitidir. Yine de her program sıralı parçalar içerir: değişkenlere başlangıç değeri vermek, girdi okumak, bir formülü hesaplamak, sonucu yazmak. Koşullu ve tekrarlı yapılar bile kendi içlerinde sıralı adımlardan oluşur.
1.4.4.1Sıralı akışın özellikleri
Sıralı akış, yapılacak işlerin art arda ve mantıklı bir sırayla dizilmesidir. Şekil 1.4.8 böyle bir akışı soldan sağa çizer; aynı akış yukarıdan aşağıya da çizilebilir. Sıralı akışın dört özelliği vardır.
Basittir. Dallanma ve tekrar yoktur. Akışı anlamak için okları sırayla izlemek yeterlidir.
Bakımı kolaydır. Adımlar yazıldıkları sırayla çalıştığı için bir hata ararken programın hangi noktada olduğunu bulmak kolaydır. Hata ayıklama, adımların birer birer kontrol edilmesinden ibarettir.
Sıra önemlidir. Bir adım öncekinin sonucunu kullanıyorsa yer değiştiremez. “c = a + b” adımı a ve b okunmadan önce yapılamaz. Ama birbirinden bağımsız adımların sırası değiştirilebilir. “Oku a” ile “Oku b” adımlarının yeri değişirse sonuç değişmez; yalnızca kullanıcıdan istenen sıra değişir.
Geri dönüş yoktur. Her adım tam olarak bir kez çalışır. Hiçbir adım atlanmaz ve önceki bir adıma geri dönülmez. N adımlı bir sıralı akış, girdiden bağımsız olarak her zaman N adımda biter.
Toplama adımı sayılar okunmadan önce yazılırsa toplama henüz bilinmeyen değerlerle yapılmaya çalışılır. Diyagramda bu bir mantık hatasıdır. Java'da ise değişkenler tanımlanmış ama henüz değer almamışsa derleyici hatayı yakalar:
int sayi1, sayi2;
int sonuc = sayi1 + sayi2; // sayılar henüz okunmadı
sayi1 = giris.nextInt();
sayi2 = giris.nextInt();JDK 21 bu parça için iki hata verir: error: variable sayi1 might not have been initialized ve aynısı sayi2 için. Java, değer almamış bir yerel değişkenin okunmasına hiçbir koşulda izin vermez. Bu kurala kesin atama denir. Derleyici her değişken için programın bütün yollarını inceler; değişkenin kullanıldığı noktaya değer almadan ulaşan bir yol varsa programı derlemez.
1.4.4.2İki sayının toplamı
Sıralı akışın klasik örneği, klavyeden girilen iki sayının toplamını yazdırmaktır. Problemin algoritması altı adımdır:
- Başla.
- İlk sayıyı oku (sayı1).
- İkinci sayıyı oku (sayı2).
- İki sayıyı topla, sonucu sonuç değişkenine ata.
- Sonucu ekrana yaz.
- Bitir.
Şekil 1.4.9 bu algoritmanın diyagramıdır. Algoritmanın her adımı bir sembole dönüşmüştür: Başla ve Bitir ovaldir, iki okuma adımı paralelkenardır, toplama işlemi dikdörtgendir, ekrana yazma Yazdır sembolüdür. Algoritmada altı adım, diyagramda altı sembol vardır. Bu birebir eşleme sıralı akışın tipik bir özelliğidir.
Okuma adımları iki ayrı paralelkenar olarak çizilmiştir. Tek bir “Oku sayı1, sayı2” kutusu da doğru olurdu. İki ayrı kutu, Java programında da iki ayrı okuma ve iki ayrı soru mesajı olacağını açıkça gösterir.
1.4.4.3Diyagramdan Java'ya: toplam programı
Diyagram aşağıdaki Java programına çevrilir:
import java.util.Scanner;
public class IkiSayiToplami {
public static void main(String[] args) {
Scanner giris = new Scanner(System.in);
System.out.print("İlk sayı: ");
int sayi1 = giris.nextInt();
System.out.print("İkinci sayı: ");
int sayi2 = giris.nextInt();
int sonuc = sayi1 + sayi2;
System.out.println("Sonuç: " + sonuc);
giris.close();
}
}Program satır satır şöyle çalışır. 1. satırdaki import deyimi, Scanner sınıfını java.util paketinden programa getirir. Bu satır olmadan derleyici Scanner adını tanımaz. 3. satır IkiSayiToplami adlı sınıfı tanımlar; Java'da her program en az bir sınıfın içinde yazılır ve dosyanın adı IkiSayiToplami.java olmalıdır.
4. satırdaki main metodu diyagramdaki Başla sembolüdür; program buradan başlar. 5. satırda klavyeden okuyacak Scanner nesnesi oluşturulur. System.in standart girdi, yani klavyedir.
6. ve 7. satırlar birinci paralelkenardır. print önce kullanıcıya ne girmesi gerektiğini söyler. println'dan farklı olarak satır sonu eklemez; böylece kullanıcının yazdığı sayı mesajla aynı satırda görünür. giris.nextInt() kullanıcının bir tam sayı yazıp Enter'a basmasını bekler. Okunan değer sayi1 değişkenine atanır. 8. ve 9. satırlar aynı işi ikinci sayı için yapar.
10. satır işlem kutusudur: int sonuc = sayi1 + sayi2;. 11. satır Yazdır sembolüdür. "Sonuç: " + sonuc ifadesinde + operatörü bir dizgiyle bir sayıyı birleştirir; sayı dizgiye çevrilir ve sonuna eklenir. 12. satır Scanner nesnesini kapatır. 13. satırda main biter; bu da diyagramdaki Bitir sembolüdür.
Tablo 1.4.2 programın kullanıcı önce 7, sonra 5 girdiğindeki izlemesidir. Tabloda her satır bir diyagram kutusuna ve o kutuyu oluşturan kod satırlarına karşılık gelir. “—” işareti değişkenin henüz değer almadığını gösterir.
| Satır | Diyagram kutusu | sayi1 | sayi2 | sonuc | Ekrana eklenen |
|---|---|---|---|---|---|
| 4–5 | Başla; Scanner oluşturulur | — | — | — | |
| 6–7 | Oku sayı1 | 7 | — | — | İlk sayı: 7 |
| 8–9 | Oku sayı2 | 7 | 5 | — | İkinci sayı: 5 |
| 10 | sonuç = sayı1 + sayı2 | 7 | 5 | 12 | |
| 11 | Yaz sonuç | 7 | 5 | 12 | Sonuç: 12 |
| 12–13 | Bitir | 7 | 5 | 12 |
Ekranda görülen konuşma şöyledir; kullanıcının yazdığı sayılar mesajların hemen arkasındadır:
İlk sayı: 7
İkinci sayı: 5
Sonuç: 12İzleme tablosu sıralı akışın özelliklerini sayılarla gösterir. Tabloda altı satır vardır ve her diyagram kutusu tam bir kez görünür. Hiçbir satır atlanmamış, hiçbir satıra geri dönülmemiştir. sonuc değişkeni ancak 10. satırda değer alır; ondan önceki satırlarda “—” görünür. Girdi değişse de tablonun satır sayısı değişmez; değişen yalnızca hücrelerdeki değerlerdir. Örneğin −3 ve 10 girilirse program Sonuç: 7 yazar.
nextInt() yalnızca tam sayı okur. Kullanıcı “abc” ya da “7,5” yazarsa program bir hata iletisiyle durur: Exception in thread "main" java.util.InputMismatchException. Diyagramdaki “Oku sayı” kutusu kullanıcının doğru türde veri gireceğini varsayar. Bu varsayım programda da geçerlidir; geçersiz girdiyi yakalamak için ayrıca bir karar ya da istisna yakalama gerekir. Ondalıklı sayılar için nextDouble() kullanılır; bu metot ondalık ayırıcı olarak bilgisayarın bölge ayarındaki işareti bekler.
1.4.5Koşullu akış
Sıralı bir program her çalıştırmada aynı adımları izler. Oysa çoğu problemde yapılacak iş duruma göre değişir. Not 50'nin altındaysa öğrenci kalır, değilse geçer. Sayı çiftse bir mesaj, tekse başka bir mesaj yazılır. Koşullu akış programa bu esnekliği verir.
1.4.5.1Karar yapısı
Koşullu akışta iki ya da daha çok ihtimalden biri seçilir. Yapının üç parçası vardır. Karar noktası (K) bir koşul sorusu içerir; sorunun cevabı Evet ya da Hayır'dır. Cevap Evet ise akış P işlemi yönünde ilerler. Cevap Hayır ise akış Q işlemi yönünde ilerler. İki yol işini bitirince bir bağlantı noktasında birleşir ve akış sonraki adımla sürer.
Bu yapının Java karşılığı if/else deyimidir:
if (K) {
P; // koşul doğru
} else {
Q; // koşul yanlış
}Parantez içindeki K, değeri true ya da false olan bir boolean ifadedir. Java'da koşul mutlaka boolean olmalıdır; C dilindeki gibi sıfır ya da sıfırdan farklı bir tam sayı koşul yerine geçmez. Süslü parantezler bir kolda çalışacak deyimleri bir blok içinde toplar. Bir kolda tek deyim varsa süslü parantezler yazılmayabilir. Ama o kola sonradan ikinci bir deyim eklenince hata kolayca yapılır; bu yüzden parantezleri her zaman yazmak iyi bir alışkanlıktır.
Koşullu akışın programa kazandırdığı üç şey vardır. Esneklik: program farklı girdilere farklı davranır. Karar verme: bir işlem yalnızca gerektiğinde yapılır; örneğin sıfıra bölme ancak bölen sıfır değilse denenir. Kod kontrolü: program bir durumu denetler ve ona göre davranır; örneğin geçersiz bir girdiyi fark edip uyarı yazar.
Karar yapısının bir de tek kollu biçimi vardır. Hayır kolunda yapılacak bir iş yoksa o kol doğrudan bağlantı noktasına gider. Bu tek yönlü karardır ve Java'da else'siz bir if ile yazılır: if (x > 0) System.out.println(x);. Koşul yanlışsa hiçbir şey yapılmaz, akış bir sonraki deyimle sürer.
1.4.5.2Sayı tek mi çift mi?
Problem, girilen bir tam sayının tek mi çift mi olduğunu ekrana yazmaktır. Bir sayının çift olması, 2'ye bölümünden kalanın 0 olması demektir. Bölümden kalan mod işlemiyle bulunur: 7 mod 2 = 1, çünkü 7 = 3 × 2 + 1'dir. 8 mod 2 = 0'dır, çünkü 8 = 4 × 2 + 0'dır. Algoritma yedi adımdır:
- Başla.
- Sayıyı oku.
- Sayı mod 2'yi al, sonuç değişkenine ata.
- Sonuç 0 ise 5'e git, değilse 6'ya git.
- Ekrana “çift” yaz, 7'ye git.
- Ekrana “tek” yaz.
- Bitir.
Algoritmada “… 'e git” ifadeleri dikkat çeker. Yazıyla anlatılan bir algoritmada dallanma ancak böyle adım numaralarıyla gösterilebilir. Diyagramda ise aynı dallanma bir karar kutusu ve iki okla çizilir; adım numaralarına gerek kalmaz.
Diyagramın Java karşılığı şöyledir:
import java.util.Scanner;
public class TekMiCiftMi {
public static void main(String[] args) {
Scanner giris = new Scanner(System.in);
System.out.print("Sayı: ");
int sayi = giris.nextInt();
int sonuc = sayi % 2;
if (sonuc == 0) {
System.out.println("çift");
} else {
System.out.println("tek");
}
giris.close();
}
}Diyagramdaki “mod” Java'da % operatörüdür. 8. satır sonuc = sayi % 2 hesabını yapar. 9. satırdaki if karar kutusudur ve sonuc == 0 sorusunu sorar. Koşul doğruysa 10. satır, yanlışsa 12. satır çalışır; ikisi birden asla çalışmaz. 11. satırdaki else Hayır kolunun başlangıcıdır.
Tablo 1.4.3 programın 7 ve 8 girdileriyle iki ayrı çalıştırmasını özetler. 7 girildiğinde sonuc = 7 % 2 = 1 olur. 1 == 0 yanlıştır, akış Hayır koluna, yani else bloğuna gider ve “tek” yazılır. Bu çalıştırmada if bloğundaki 10. satır hiç çalışmaz. 8 girildiğinde sonuc = 0 olur, Evet kolundan “çift” yazılır ve bu kez 12. satır atlanır. Her çalıştırmada iki koldan yalnızca biri çalışır; iki yol Bitir'de birleşir.
| Girdi | İşlem kutusu | Karar | Çıkış | Çalışan satır | Çıktı |
|---|---|---|---|---|---|
| 7 | 7 % 2 = 1 | 1 == 0 → yanlış | Hayır | 12 | tek |
| 8 | 8 % 2 = 0 | 0 == 0 → doğru | Evet | 10 | çift |
Negatif sayılar ayrı bir dikkat ister. Java'da % işleminin sonucu bölünenin işaretini alır. Bu yüzden -3 % 2 değeri 1 değil, −1'dir; -4 % 2 ise 0'dır. Sunumdaki diyagram koşulu “sonuç = 0 ?” diye kurduğu için bu ayrıntıdan etkilenmez: −1 ≠ 0 olduğundan −3 için doğru olarak “tek” yazılır. Koşul “sonuç = 1 ?” diye kurulsaydı durum değişirdi. Tablo 1.4.4 iki koşulu −3, 7 ve 0 girdileriyle karşılaştırır.
| Girdi | sayi % 2 | Koşul == 0 (sunumdaki) | Koşul == 1 |
|---|---|---|---|
| −3 | −1 | Hayır → tek | Hayır → çift |
| 7 | 1 | Hayır → tek | Evet → tek |
| 0 | 0 | Evet → çift | Hayır → çift |
Tek sayı denetimini if (sayi % 2 == 1) diye yazmak negatif tek sayılarda yanlış sonuç verir. −3 için -3 % 2 değeri −1 olduğundan koşul yanlış olur ve program -3 çift yazar. Derleyici bu hatayı yakalamaz, çünkü kod Java kurallarına uygundur; hata mantıktadır. Güvenli yol, çiftliği sınamaktır: sayi % 2 == 0. Kalan −1 de olsa 1 de olsa sayı “tek” koluna düşer. Matematikteki gibi her zaman negatif olmayan bir kalan gerektiğinde Math.floorMod(sayi, 2) kullanılır; Math.floorMod(-3, 2) değeri 1'dir.
1.4.5.3İç içe karar: pozitif, negatif, sıfır
Bir karar kutusunun yalnızca iki çıkışı vardır. Üç ihtimal olduğunda iki karar kutusu art arda bağlanır: ilk sorunun Hayır çıkışı ikinci soruya gider. Bir sayının pozitif, negatif ya da sıfır olduğunu bulan Şekil 1.4.12 bu yapıyı gösterir.
Birinci karar “sayı > 0 ?” sorusunu sorar. Cevap Evet ise “pozitif” yazılır ve akış Bitir'e gider; ikinci soru hiç sorulmaz. Cevap Hayır ise sayı ya negatiftir ya da sıfırdır. Bunu ayırmak için ikinci karar “sayı < 0 ?” sorusunu sorar. Evet ise “negatif”, Hayır ise “sıfır” yazılır. İkinci kararın Hayır çıkışına ulaşan bir sayı ne pozitiftir ne negatif; geriye tek ihtimal kalır, o da sıfırdır. Bu yüzden üçüncü bir soruya gerek yoktur.
Java'da iç içe karar else if zinciriyle yazılır:
Scanner giris = new Scanner(System.in);
int sayi = giris.nextInt();
if (sayi > 0) {
System.out.println("pozitif");
} else if (sayi < 0) {
System.out.println("negatif");
} else {
System.out.println("sıfır");
}else if, Java'da ayrı bir deyim değildir. Birinci if'in else kolunda ikinci bir if deyimi bulunur; süslü parantezler bu yapıyı tek düzeyde yazmaya izin verir. Diyagramda ikinci kararın birinci kararın Hayır çıkışına bağlı olması da tam olarak bu iç içeliği gösterir.
Tablo 1.4.5 programın üç çalıştırmasını izler. −4 girildiğinde birinci koşul -4 > 0 yanlıştır; akış Hayır çıkışından ikinci karara gider. -4 < 0 doğrudur ve “negatif” yazılır; son else kolu atlanır. 0 girildiğinde 0 > 0 yanlıştır, çünkü 0 pozitif değildir. 0 < 0 da yanlıştır; iki koşul da yanlış olduğu için son else çalışır ve “sıfır” yazılır. 5 girildiğinde ise birinci koşul doğrudur ve ikinci koşul hiç sınanmaz.
| Girdi | 1. karar | 2. karar | Çıktı |
|---|---|---|---|
| −4 | −4 > 0 → yanlış | −4 < 0 → doğru | negatif |
| 0 | 0 > 0 → yanlış | 0 < 0 → yanlış | sıfır |
| 5 | 5 > 0 → doğru | sorulmaz | pozitif |
Üç kol olduğu için diyagramı tam olarak denemek en az üç girdi gerektirir. Her girdi farklı bir Yaz kutusunu çalıştırır. Bu, test durumlarının seçiminde kullanılan yol kapsama fikrinin ilk örneğidir: her karar kutusunun her çıkışı en az bir kez denenmelidir.
0–100 arasındaki bir notu harf notuna çeviren diyagramda dört ihtimal vardır: not ≥ 85 ise A, ≥ 70 ise B, ≥ 50 ise C, değilse F. Dört ihtimal için üç karar kutusu art arda bağlanır. Java karşılığı bir else if zinciridir:
if (not >= 85) {
System.out.println("A");
} else if (not >= 70) {
System.out.println("B");
} else if (not >= 50) {
System.out.println("C");
} else {
System.out.println("F");
}72 girildiğinde 72 >= 85 yanlış, 72 >= 70 doğrudur; “B” yazılır ve üçüncü karar hiç sınanmaz. 45 girildiğinde üç koşul da yanlıştır ve “F” yazılır. 72 için iki, 45 için üç karar sınanır. İkinci koşulda not < 85 diye ayrıca sormaya gerek yoktur: o karara yalnızca 85'ten küçük notlar ulaşır. Sınır değerler de doğru kola düşer: 85 → A, 84 → B, 70 → B, 50 → C, 49 → F.
1.4.5.4Birleşik koşullar: VE, VEYA
Bazı kararlar iki koşula birden bağlıdır. Bir kişinin araba sürebilmesi için hem 18 yaşında ya da büyük olması hem de ehliyetinin olması gerekir. Bu bir VE koşuludur. Bir indirimden yararlanmak için öğrenci olmak ya da 65 yaşını geçmiş olmak yetiyorsa bu bir VEYA koşuludur.
Şekil 1.4.14 VE koşulunu iki biçimde çizer. Soldaki çizimde önce “yaş ≥ 18 ?” sorulur. Cevap Hayır ise ehliyetin olup olmadığına bakmaya gerek yoktur; kişi zaten süremez ve ilk kararın Hayır çıkışı doğrudan “Yaz süremez” kutusuna gider. Cevap Evet ise ikinci karar “ehliyet ?” sorulur. Sağdaki çizim aynı mantığı tek bir karar kutusuna sığdırır. VEYA koşulunda durum tersine döner: iki kararla çizildiğinde ilk kararın Evet çıkışı doğrudan sonuca gider, çünkü koşullardan birinin doğru olması yeter.
Java'da VE &&, VEYA || ile yazılır: if (yas >= 18 && ehliyet). Burada ehliyet bir boolean değişkendir. Tablo 1.4.6 dört olası durumu iki koşul için de verir; tablo bir Java programıyla üretilmiştir.
yas | ehliyet | yas >= 18 | yas >= 18 && ehliyet | yas >= 18 || ehliyet |
|---|---|---|---|---|
| 20 | var | doğru | doğru | doğru (ehliyete bakılmaz) |
| 20 | yok | doğru | yanlış | doğru (ehliyete bakılmaz) |
| 16 | var | yanlış | yanlış (ehliyete bakılmaz) | doğru |
| 16 | yok | yanlış | yanlış (ehliyete bakılmaz) | yanlış |
Kısa devre değerlendirme (short-circuit evaluation), && ve || operatörlerinde sonuç sol taraftan belli olunca sağ tarafın hiç hesaplanmamasıdır. A && B ifadesinde A yanlışsa sonuç yanlıştır ve B'ye bakılmaz. A || B ifadesinde A doğruysa sonuç doğrudur ve B'ye bakılmaz.
Kısa devre, iki kararla çizilen diyagramın Java'daki karşılığıdır. Diyagramda ilk kararın Hayır çıkışı ikinci kararı atlıyordu; Java da ikinci koşula yalnızca gerekirse bakar. Bu davranış bir deneyle görülebilir. Sağ taraftaki koşul, her çağrıldığında bir sayacı artıran bir metotla yazılırsa, yas = 16 için yas >= 18 && ehliyetVarMi(true) ifadesi false verir ve sayaç 0'da kalır; metot hiç çağrılmamıştır. yas = 20 için yas >= 18 || ehliyetVarMi(false) ifadesi true verir ve sayaç yine 0'dır.
Kısa devrenin pratik bir yararı vardır: soldaki koşul sağdakinin güvenle hesaplanabileceğini garanti edebilir. adet != 0 && toplam / adet > 2 ifadesinde adet 0 ise bölme hiç yapılmaz. Sıra ters yazılsaydı, yani bölme sola konsaydı, adet = 0 için program ArithmeticException ile dururdu.
1.4.6Tekrarlı akış
Bilgisayarı güçlü kılan özelliklerden biri, aynı işi yorulmadan binlerce kez yapabilmesidir. Tekrarlı akış, işlemlerin birden çok kez tekrar ettiği akış türüdür. Diyagramda tekrar, geriye doğru giden bir okla gösterilir. Bu ok bir karar kutusunun üstüne döner; karar kutusu da tekrarın ne zaman biteceğine karar verir.
1.4.6.1Döngü türleri
Koşula bağlı döngü, bir koşul sağlandığı sürece tekrar eder. Kaç kez döneceği önceden bilinmeyebilir. “Kullanıcı 0 girene kadar sayı oku” böyle bir döngüdür; kullanıcının kaç sayı gireceği program yazılırken bilinmez. Java'da bu tür döngü genellikle while ile yazılır.
Belirli sayıda tekrar eden döngüde tekrar sayısı baştan bellidir. “1'den 10'a kadar sayıları yaz” işi tam 10 tur sürer. Java'da bu tür döngü genellikle for ile yazılır. for ile while arasındaki seçim bir zorunluluk değil, okunabilirlik meselesidir; her for döngüsü while ile, her while döngüsü de for ile yazılabilir.
Sonsuz döngüde koşul hep sağlandığı için işlemler durmadan tekrarlanır. Sonsuz döngü çoğunlukla bir hatadır. Döngü değişkenini güncellemeyi unutmak, koşulu yanlış kurmak ya da geri oku yanlış yere bağlamak sonsuz döngü üretir. Bazı programlar ise bilinçli olarak sonsuz döngüyle çalışır. Bir web sunucusu kapatılana kadar gelen istekleri bekler; bir gömülü sistemin ana döngüsü cihaz açık kaldıkça döner. Java'da bu tür döngü while (true) ile yazılır.
Döngülerin programa kazandırdığı üç şey vardır. Döngü verimlidir: aynı işlem, kod tekrar tekrar yazılmadan istenen sayıda yapılır. Döngü dinamiktir: tekrar sayısı girdiye göre değişebilir ve program farklı durumlara uyum sağlar. Döngü kod tekrarını önler: 1000 sayıyı yazdırmak için 1000 satır değil, 3–4 satır yeterlidir.
Her döngünün üç parçası vardır. Başlangıç, döngü değişkenine ilk değerini verir ve yalnızca bir kez çalışır. Koşul, her turdan önce sınanır ve döngünün sürüp sürmeyeceğini belirler. Güncelleme, döngü değişkenini değiştirir ve her turun sonunda çalışır. Bu üç parçadan biri eksik ya da yanlışsa döngü ya hiç çalışmaz, ya eksik ya da fazla döner, ya da hiç bitmez.
1.4.6.21'den 10'a kadar sayıları yazdırma
Tekrarlı akışın ilk örneği 1'den 10'a kadar sayıları ekrana yazmaktır. Algoritma yedi adımdır:
- Başla.
- Sayaç = 1.
- Sayaç ≤ 10 ise 4'e git, değilse 7'ye git.
- Sayacı yaz.
- Sayacı 1 artır.
- 3'e git.
- Bitir.
Algoritmanın 6. adımındaki “3'e git”, diyagramda karar kutusunun üstüne dönen geri oktur. Bu ok döngüyü oluşturur. Karar kutusu ise döngüden çıkış kapısıdır: sayaç 10'u aştığı anda Hayır çıkışından Bitir'e gidilir. Geri okun karar kutusuna, “sayaç = 1” kutusunun altına bağlandığına dikkat edilmelidir. Başlangıç değeri yalnızca bir kez, döngüden önce verilir.
Diyagramın Java karşılığı bir while döngüsüdür:
public class BirdenOna {
public static void main(String[] args) {
int sayac = 1;
while (sayac <= 10) {
System.out.print(sayac + " ");
sayac += 1;
}
}
}3. satır başlangıçtır: sayac 1 değerini alır. 4. satırdaki while (sayac <= 10) karar kutusudur. Koşul doğru olduğu sürece süslü parantezler arasındaki gövde çalışır. 5. satır sayacı yazar; print satır sonu eklemediği için sayılar aynı satırda, aralarında birer boşlukla görünür. 6. satır güncellemedir: sayac += 1, yani sayac = sayac + 1. Gövde bitince yürütme 4. satıra, yani koşula geri döner. Bu dönüş diyagramdaki geri oktur; Java'da ayrıca bir “git” deyimi yazılmaz, while'ın kapanan süslü parantezi bu işi görür.
Tablo 1.4.7 döngünün izlemesidir. Tablonun ortasındaki 4.–8. turlar aynı kalıbı izlediği için kısaltılmıştır.
| Tur | sayac (tur başı) | Koşul | Yazılan | sayac (tur sonu) | Çıktı |
|---|---|---|---|---|---|
| 1 | 1 | 1 <= 10 → doğru | 1 | 2 | 1 |
| 2 | 2 | 2 <= 10 → doğru | 2 | 3 | 1 2 |
| 3 | 3 | 3 <= 10 → doğru | 3 | 4 | 1 2 3 |
| … | … | … | … | … | … |
| 9 | 9 | 9 <= 10 → doğru | 9 | 10 | 1 2 3 4 5 6 7 8 9 |
| 10 | 10 | 10 <= 10 → doğru | 10 | 11 | 1 2 3 4 5 6 7 8 9 10 |
| — | 11 | 11 <= 10 → yanlış | — | 11 | 1 2 3 4 5 6 7 8 9 10 |
1 2 3 4 5 6 7 8 9 10 Tablodan iki önemli sayı okunur. Gövde 10 kez çalışmıştır; her turda bir sayı yazılmıştır. Koşul ise 11 kez sınanmıştır: on kez doğru, son kez yanlış çıkmıştır. Koşulun gövdeden bir fazla sınanması, karar kutusu başta olan her döngünün özelliğidir. Döngüden çıkıldığında sayac 10 değil, 11'dir. Çünkü 10 yazıldıktan sonra sayaç bir kez daha artırılmış, sonra koşul yanlış çıkmıştır.
1.4.6.3Sınır koşulu: < mı, ≤ mü?
Döngü koşulundaki tek bir karakter tekrar sayısını değiştirir. Sayaç 1'den başlayıp her turda 1 artarsa koşulun dört farklı yazılışı Tablo 1.4.8'deki sonuçları verir.
| Koşul | Gövde | Koşul sınaması | Çıkışta sayac | Son yazılan |
|---|---|---|---|---|
sayac < 10 | 9 | 10 | 10 | 9 |
sayac <= 10 | 10 | 11 | 11 | 10 |
sayac < 11 | 10 | 11 | 11 | 10 |
sayac <= 11 | 11 | 12 | 12 | 11 |
sayac < 10 koşulu 10'u yazmaz; çünkü sayaç 10 olduğunda 10 < 10 yanlıştır. Gövde 9 kez çalışır ve 1'den 9'a kadar sayılar yazılır. sayac <= 10 ve sayac < 11 koşulları aynı anlamdadır; ikisi de 10 tur döner ve 10'u da yazar. sayac <= 11 ise bir tur fazla döner ve 11'i de yazar.
Bir eksik / bir fazla hatası (off-by-one error), bir döngünün sınır koşulunun yanlış yazılması yüzünden gerekenden bir tur eksik ya da bir tur fazla dönmesidir.
Bu hata programlamanın en yaygın hatalarından biridir ve derleyici onu yakalamaz; çünkü yanlış yazılan koşul da geçerli bir Java ifadesidir. Hatayı önlemenin basit bir yolu vardır: koşul son değerle sınanır. “1'den 10'a kadar” ifadesi 10'u da kapsar. O hâlde sayaç 10 iken koşulun doğru olması gerekir. 10 < 10 yanlış, 10 <= 10 doğrudur; doğru koşul sayac <= 10'dur. Aynı yoklama ilk değerle de yapılır: sayaç 1 iken koşul doğru olmalıdır, yoksa döngü hiç başlamaz.
1.4.6.4Döngü sembolü ve for
Aynı problem, yani 1'den 10'a kadar sayıları yazdırmak, döngüye özel altıgen sembolle daha kısa çizilebilir. Algoritma beş adıma iner:
- Başla.
- Döngü: 1'den 10'a kadar.
- Döngü değişkenini yaz.
- Döngü sonu.
- Bitir.
Altıgen sembol döngünün üç parçasını tek kutuda toplar. Başlangıç i = 1'dir ve bir kez çalışır. Koşul i ≤ 10'dur ve her turdan önce sınanır. Güncelleme i++'dır, yani i'yi 1 artırır ve her turdan sonra çalışır. İçinde “i” yazan küçük çember döngünün sonudur. Gövde bitince akış bu çemberden altıgene döner; altıgen güncellemeyi yapar ve koşulu yeniden sınar. Koşul yanlış olunca akış çemberin altındaki “bitti” okundan Bitir'e geçer.
Altıgenin Java karşılığı for deyimidir. Üç parça for'un parantezi içinde noktalı virgülle ayrılarak aynı sırayla yazılır:
public class ForBirdenOna {
public static void main(String[] args) {
for (int i = 1; i <= 10; i++) {
System.out.print(i + " ");
}
System.out.println();
}
}Bu program ile while sürümü aynı çıktıyı verir: 1 2 3 4 5 6 7 8 9 10. Fark yalnızca yazılıştadır. for, döngünün üç parçasını tek satırda topladığı için okuyan kişi tekrar sayısını bir bakışta görür. while sürümünde başlangıç döngüden önce, güncelleme ise gövdenin sonunda yazılır ve gözden kaçabilir.
for ile while arasında küçük ama önemli bir fark daha vardır. for'un başlangıç kısmında tanımlanan int i değişkeni yalnızca döngü içinde geçerlidir. Döngüden sonra i kullanılmak istenirse derleyici cannot find symbol hatası verir. while sürümünde ise sayac döngüden önce tanımlandığı için döngüden sonra da kullanılabilir ve değeri 11'dir.
1.4.6.5Döngü içinde karar: sayaç ve biriktirici
Döngünün gövdesinde her türlü adım bulunabilir; bir karar kutusu da. Örnek problem şöyledir: beş öğrencinin notu okunur; kaç öğrencinin geçtiği (not ≥ 50) ve sınıf ortalaması yazılır.
int gecen = 0, toplam = 0;
for (int k = 1; k <= 5; k++) {
int not = giris.nextInt();
toplam += not;
if (not >= 50) {
gecen++;
}
}
System.out.println(gecen + " geçti, ortalama "
+ toplam / 5.0);Bu program iki önemli döngü kalıbını birlikte kullanır.
Sayaç (counter), bir koşul sağlandığında 1 artan ve böylece bir olayın kaç kez olduğunu sayan değişkendir. Biriktirici (accumulator), döngünün her turunda bir değer eklenerek sonucu toplayan değişkendir. İkisi de döngüden önce başlangıç değeri alır.
Programda gecen bir sayaçtır: yalnızca not >= 50 doğru olduğunda gecen++ ile 1 artar. toplam bir biriktiricidir: koşul ne olursa olsun her turda okunan not ona eklenir. İkisinin de başlangıç değeri 0'dır; toplama ve saymaya sıfırdan başlanır. Karar kutusu döngünün içindedir ve her turda yeni okunan notla yeniden sınanır. Tablo 1.4.9 programın 45, 70, 50, 30 ve 88 girdileriyle izlenmesidir.
k | not | toplam | Karar | gecen |
|---|---|---|---|---|
| 1 | 45 | 45 | 45 >= 50 → yanlış | 0 |
| 2 | 70 | 115 | 70 >= 50 → doğru | 1 |
| 3 | 50 | 165 | 50 >= 50 → doğru | 2 |
| 4 | 30 | 195 | 30 >= 50 → yanlış | 2 |
| 5 | 88 | 283 | 88 >= 50 → doğru | 3 |
Döngü bittiğinde gecen = 3 ve toplam = 283 olur. Program şunu yazar:
3 geçti, ortalama 56.6Bu kısa programda iki Java ayrıntısı saklıdır. Birincisi sınırdaki nottur. 50 alan öğrenci geçer, çünkü koşul >= ile yazılmıştır. Koşul not > 50 yazılsaydı 50 alan öğrenci kalırdı ve sonuç 3 değil 2 olurdu. Sınır değeri koşulu tek karakterle değiştirir; bir eksik/bir fazla hatasının karar kutusundaki biçimi budur.
İkincisi bölmedir. toplam / 5.0 ifadesinde bölen ondalıklı bir sayı olduğu için Java bölmeyi ondalıklı yapar: 283 / 5,0 = 56,6. Bölen 5 yazılsaydı iki tam sayı bölünürdü. Java'da iki tam sayının bölümü yine tam sayıdır; ondalık kısım atılır ve 283 / 5 = 56 olur. Diyagramdaki “toplam / 5” ifadesi bu ayrımı göstermez; Java'ya çevirirken türlere dikkat etmek gerekir. Ekranda ondalık ayırıcının nokta olarak (56.6) göründüğüne de dikkat edilmelidir; println sayıları her zaman noktayla yazar.
Sayaç ve biriktiricinin yanında üçüncü bir kalıp daha vardır: bayrak. Bayrak, bir olayın olup olmadığını tutan boolean bir değişkendir. Başlangıçta false'tur; olay gerçekleşince true yapılır, örneğin bulundu = true. Döngü bittikten sonra bayrağa bakılarak olayın en az bir kez olup olmadığı anlaşılır.
1.4.6.6Nöbetçi değerli döngü
Önceki örnekte not sayısı baştan belliydi: beş. Çoğu zaman ise kaç değer geleceği önceden bilinmez. Bir öğretmen bazen 3, bazen 40 not girer. Bu durumda kullanıcı, girişin bittiğini özel bir değerle bildirir.
Nöbetçi değer (sentinel value), girdinin bittiğini bildiren ve veri olarak sayılmayan özel bir değerdir. 0, −1 ya da “son” gibi bir değer seçilir.
int toplam = 0, adet = 0;
int sayi = giris.nextInt();
while (sayi != 0) {
toplam += sayi;
adet++;
sayi = giris.nextInt();
}
if (adet > 0) {
System.out.println("Ortalama: "
+ (double) toplam / adet);
} else {
System.out.println("Sayı yok");
}Kaç değer geleceği bilinmediği için döngü koşula bağlıdır ve while ile yazılır. Diyagramın en önemli özelliği önce okuma düzenidir. İlk değer döngüden önce, 2. satırda okunur. Sıradaki değer ise gövdenin sonunda, 6. satırda okunur. Böylece okunan her değer, gövdeye girmeden önce koşulda sınanır. Nöbetçi geldiğinde koşul hemen yanlış olur ve nöbetçi toplama hiç katılmaz.
Tablo 1.4.10 programın 12, 7, 5, 0 girdisiyle izlenmesidir. Her tur satırında sayi sütunu, o turda toplama eklenen değeri ve gövdenin sonunda okunan yeni değeri gösterir.
| Adım | sayi | Koşul | toplam | adet |
|---|---|---|---|---|
| önce okuma | 12 | — | 0 | 0 |
| 1. tur | 12 → 7 | 12 != 0 → doğru | 12 | 1 |
| 2. tur | 7 → 5 | 7 != 0 → doğru | 19 | 2 |
| 3. tur | 5 → 0 | 5 != 0 → doğru | 24 | 3 |
| karar | 0 | 0 != 0 → yanlış | 24 | 3 |
Döngüden çıkıldığında toplam = 24 ve adet = 3'tür. Döngüden sonraki karar adet > 0 koşulunu sınar; koşul doğrudur ve ortalama yazılır:
Ortalama: 8.0Ortalama hesabındaki (double) toplam / adet ifadesine dikkat edilmelidir. (double) bir tür dönüşümüdür: toplam'ı bölmeden önce ondalıklı sayıya çevirir. Böylece bölme ondalıklı yapılır ve 24 / 3 = 8.0 olur. Dönüşüm yazılmasaydı iki tam sayı bölünürdü; 24 / 3 için sonuç yine 8 olurdu, ama 25 / 3 için 8,33… yerine 8 çıkardı.
Nöbetçi değer, gerçek veride görülemeyecek bir değer olmalıdır. Öğrenci notları için −1 uygun bir nöbetçidir; 0 değildir, çünkü sınavdan 0 alan bir öğrenci olabilir. Bu örnekteki gibi sıradan tam sayılar okunuyorsa 0 nöbetçi seçilebilir, ama o zaman 0 hiçbir zaman veri olarak girilemez.
Döngüden sonraki adet > 0 denetimi gereksiz değildir. Kullanıcı ilk sayı olarak 0 girerse döngü hiç çalışmaz; toplam ve adet 0'da kalır. Denetim olmasaydı 0 / 0 hesaplanırdı. Java'da bu bölmenin sonucu türe göre değişir. (double) 0 / 0 ifadesi hata vermez, NaN (Not a Number, sayı değil) değerini üretir ve ekrana Ortalama: NaN yazılırdı. Tam sayılarda ise 0 / 0 programı java.lang.ArithmeticException: / by zero hatasıyla durdurur. Denetim sayesinde program bu durumda Sayı yok yazar.
Okuma yalnızca gövdenin başına konursa, yani “önce okuma” yerine “döngü içinde okuma” yapılırsa nöbetçi de toplama eklenir. Nöbetçi 0 ise sonuç değişmez ama adet bir fazla sayılır ve ortalama yanlış çıkar. Nöbetçi −1 ise hem toplam hem adet yanlış olur. Önce okuma düzeni bu yüzden vardır: her değer kullanılmadan önce sınanır.
1.4.6.7Döngüden erken çıkış
Bir aramada aranan bulununca kalan turlara gerek kalmaz. Örnek problem şöyledir: beş sayı sırayla okunur; ilk negatif sayının kaçıncı sırada girildiği yazılır. Negatif sayı bulununca geri kalan sayıları okumanın anlamı yoktur.
Diyagramda döngünün içinde ikinci bir karar vardır: “x < 0 ?”. Bu kararın Evet kolu, bulunan = i atamasından sonra akışı doğrudan döngünün dışına çıkarır. Böylece döngünün iki çıkışı olur. Birinci çıkış olağan çıkıştır: i 5'i aşınca koşul yanlış olur; bu, negatif sayının bulunamadığı anlamına gelir. İkinci çıkış erken çıkıştır: negatif sayı bulununca döngü hemen biter. İki yol “Yaz bulunan” kutusunda birleşir. Java'da ikinci çıkış break deyimiyle yazılır:
int bulunan = 0;
for (int i = 1; i <= 5; i++) {
int x = giris.nextInt();
if (x < 0) {
bulunan = i;
break;
}
}
System.out.println("Sıra: " + bulunan);break yalnızca içinde bulunduğu döngüyü bitirir. Yürütme döngüden sonraki ilk deyimle, burada println ile sürer. bulunan değişkeninin başlangıç değeri 0'dır ve “bulunamadı” anlamına gelir. Sıra 1'den başladığı için 0 hiçbir gerçek sırayla karışmaz. Tablo 1.4.11 programın 4, 9, −2, 6, 1 girdisiyle izlenmesidir.
i | Döngü koşulu | x | İç karar | bulunan |
|---|---|---|---|---|
| 1 | 1 <= 5 → doğru | 4 | 4 < 0 → yanlış | 0 |
| 2 | 2 <= 5 → doğru | 9 | 9 < 0 → yanlış | 0 |
| 3 | 3 <= 5 → doğru | −2 | −2 < 0 → doğru; break | 3 |
Üçüncü turda x = -2 okunur ve -2 < 0 doğrudur. bulunan = 3 olur ve break çalışır. break, for'un güncelleme kısmını (i++) ve koşulu da atlar; döngü hemen biter. Program Sıra: 3 yazar. Negatif sayı hiç girilmeseydi, örneğin 4, 9, 2, 6, 1 girdisinde, döngü beş tur döner, i = 6 olunca koşulun Hayır çıkışından çıkar ve Sıra: 0 yazılırdı.
Bu diyagram yapısal değildir: döngü bloğunun iki çıkışı vardır. Böhm–Jacopini teoremi, aynı işin tek çıkışlı bir yapıyla da yapılabileceğini söyler. Yapısal karşılık, break yerine bir bayrak kullanır:
int bulunan = 0;
boolean bulundu = false;
for (int i = 1; i <= 5 && !bulundu; i++) {
int x = giris.nextInt();
if (x < 0) {
bulunan = i;
bulundu = true;
}
}Burada bulundu bir bayraktır. Negatif sayı bulunduğunda true yapılır. Döngü koşulu artık iki parçalıdır: i <= 5 && !bulundu. ! operatörü “değil” demektir; !bulundu, “henüz bulunamadı” anlamına gelir. Bayrak true olunca koşul yanlış olur ve döngü olağan çıkışından biter. Tablo 1.4.12 aynı girdiyle bu sürümün izlenmesidir.
i | Döngü koşulu | x | bulundu | bulunan |
|---|---|---|---|---|
| 1 | 1 <= 5 && !false → doğru | 4 | false | 0 |
| 2 | 2 <= 5 && !false → doğru | 9 | false | 0 |
| 3 | 3 <= 5 && !false → doğru | −2 | true | 3 |
| 4 | 4 <= 5 && !true → yanlış | — | true | 3 |
İki sürüm aynı sonucu verir: Sıra: 3. Aralarındaki fark, döngü bittiğinde i'nin değerindedir. break'li sürümde döngü i = 3 iken biter. Bayraklı sürümde ise üçüncü turun sonunda i++ çalışır, i = 4 olur ve koşul bu değerle yanlış çıkar. Bu yüzden bayraklı sürümde sıra i'den değil, bulunan'dan okunur. Hangi sürümün seçileceği bir üslup meselesidir. Kısa döngülerde break okunaklıdır; uzun döngülerde ise döngünün tek çıkışlı olması izlemeyi kolaylaştırır.
1.4.6.8İç içe döngü
Bir döngünün gövdesinde başka bir döngü bulunabilir. Bu yapıya iç içe döngü denir. Dış döngünün her turunda iç döngü baştan sona bütün turlarını döner. Aşağıdaki program küçük bir çarpım tablosu yazar:
for (int i = 1; i <= 2; i++) {
for (int j = 1; j <= 3; j++) {
System.out.print(i * j + " ");
}
System.out.println();
}Dış döngü i = 1 ve 2 için iki tur döner. İç döngü her dış turda j = 1, 2, 3 için üç tur döner ve i * j değerini yazar. İç döngü bitince println() alt satıra geçer. Tablo 1.4.13 programın bütün adımlarıdır.
i | j | Koşul | Yazılan |
|---|---|---|---|
| 1 | 1 | 1 <= 3 → doğru | 1 × 1 = 1 |
| 1 | 2 | 2 <= 3 → doğru | 1 × 2 = 2 |
| 1 | 3 | 3 <= 3 → doğru | 1 × 3 = 3 |
| 1 | 4 | 4 <= 3 → yanlış: println() | (alt satır) |
| 2 | 1 | 1 <= 3 → doğru | 2 × 1 = 2 |
| 2 | 2 | 2 <= 3 → doğru | 2 × 2 = 4 |
| 2 | 3 | 3 <= 3 → doğru | 2 × 3 = 6 |
| 2 | 4 | 4 <= 3 → yanlış: println() | (alt satır) |
| 3 | — | 3 <= 2 → yanlış: dış döngü biter | — |
1 2 3
2 4 6 Tabloda dikkat edilecek nokta, ikinci dış turda j'nin yeniden 1'den başlamasıdır. Bunun nedeni, int j = 1 başlangıcının iç for'un parçası olmasıdır. İç for deyimi dış döngünün her turunda baştan çalıştığı için başlangıç da her seferinde yeniden yapılır. Diyagramda bu, dış döngünün geri okunun iç altıgenin üstüne gelmesiyle gösterilir.
Çalışma sayıları çarpımla bulunur. İç gövde, yani print, 2 × 3 = 6 kez çalışır. println() ise dış gövdenin parçası olduğu için yalnızca 2 kez çalışır. Genel olarak dış döngü m, iç döngü n tur dönüyorsa iç gövde m × n kez çalışır. Bu yüzden iç içe döngüler büyük girdilerde hızla yavaşlar: 1000 × 1000'lik bir iç içe döngü bir milyon kez döner.
1.4.7Alt program
Diyagramlar büyüdükçe tek sayfaya sığmaz ve okunması zorlaşır. Bazı adım dizileri de diyagramın farklı yerlerinde tekrar tekrar gerekir. Her iki sorunun çözümü aynıdır: diyagram anlamlı parçalara bölünür.
1.4.7.1Alt program sembolü ve metot
Alt program (subprogram, predefined process), ayrı bir diyagram olarak çizilen ve ana diyagramdan alt program sembolüyle çağrılan adım dizisidir. Java'daki karşılığı metottur.
Şekil 1.4.22 bir öğrencinin dönem ortalamasını hesaplayan diyagramı iki parçaya böler. Sağdaki parça alt programdır. Başla kutusunun yerinde alt programın adı ve girdileri yazar: “ortalama(vize, fin)”. Bu girdilere parametre denir. Alt program vize notunun %40'ını ve final notunun %60'ını toplar. Sonunda Bitir yerine bir Dön kutusu bulunur: “Dön ort”. Dön kutusu hesaplanan değeri alt programı çağıran yere geri verir.
Soldaki ana diyagram önce vize ve final notlarını okur. Sonra iki yanı çizgili alt program sembolüyle alt programı çağırır: “ort = ortalama(vize, fin)”. Çağrı anında akış alt programa geçer. Alt program Dön kutusuna gelince sonuç çağırana verilir ve akış çağrının hemen sonrasından sürer. Ana diyagram bu sonucu ort değişkenine atar ve “ort ≥ 50 ?” kararıyla öğrencinin geçip geçmediğini yazar.
Alt programın üç kazancı vardır. Aynı adımlar her ihtiyaç duyulduğunda yeniden çizilmez; bir kez çizilir, defalarca çağrılır. Her parça ayrı ayrı sınanabilir; ortalama hesabı doğruysa ana diyagramda yalnızca okuma ve karar denetlenir. Ana diyagram kısa ve okunaklı kalır; okuyucu ayrıntıya girmeden programın ne yaptığını görür.
Java karşılığı şöyledir:
static double ortalama(int vize, int fin) {
double ort = vize * 0.4 + fin * 0.6;
return ort;
}
public static void main(String[] args) {
Scanner giris = new Scanner(System.in);
int vize = giris.nextInt();
int fin = giris.nextInt();
double ort = ortalama(vize, fin);
if (ort >= 50) System.out.println(ort + " geçti");
else System.out.println(ort + " kaldı");
}1.–4. satırlar alt programdır. static double ortalama(int vize, int fin) başlığı metodun adını (ortalama), iki int parametresini ve döndürdüğü değerin türünü (double) belirtir. return ort; deyimi diyagramdaki Dön kutusudur. 9. satırdaki ortalama(vize, fin) ifadesi alt program sembolüdür; çağrıdır.
Parametre adı olarak final yerine fin seçilmiştir. Bunun nedeni, final'ın Java'da ayrılmış bir anahtar sözcük olmasıdır; değişken adı olarak kullanılamaz. int final = 70; yazılırsa derleyici error: not a statement başta olmak üzere bir dizi hata verir. Diyagramda “final” yazmak serbesttir, ama Java'ya çevirirken anahtar sözcükler değişken adı olamaz.
1.4.7.2Alt program çağrısını izlemek
Kullanıcı aynı satıra 40 ve 70 girdiğinde program şu adımlarla çalışır.
- Program
main'den başlar. 7. ve 8. satırlar iki notu okur:vize = 40,fin = 70. - 9. satırda
ortalamaçağrılır. 40 ve 70 değerleri metodun parametrelerine kopyalanır. Metodunvizevefindeğişkenleri,main'deki aynı adlı değişkenlerden ayrıdır; yalnızca değerleri aynıdır. - Alt programın kendi diyagramı çalışır:
ort = 40 × 0,4 + 70 × 0,6 = 16 + 42 = 58.0. Buort, metodun yerel değişkenidir;main'dekiort'tan ayrıdır. return ort;çalışır: 58.0 değeri çağırana verilir. Metot için ayrılan bellek alanı, yani metodun çerçevesi, çağrı yığınından kalkar; metodun yerel değişkenleri de onunla birlikte yok olur.- Akış 9. satırdan sürer: dönen değer
main'dekiort'a atanır. - 10. satırdaki karar:
58.0 >= 50doğrudur; Evet kolu58.0 geçtiyazar. mainbiter (Bitir).
Aynı alt program başka girdilerle yeniden çağrılabilir. Tablo 1.4.14 iki çalıştırmayı karşılaştırır. İkinci çalıştırmada 45 ve 30 girilir; ortalama 36.0 çıkar ve öğrenci kalır.
vize | fin | Alt programdaki işlem | Dönen değer | Karar | Çıktı |
|---|---|---|---|---|---|
| 40 | 70 | 40 × 0,4 + 70 × 0,6 = 16,0 + 42,0 | 58,0 | 58,0 >= 50 → doğru | 58.0 geçti |
| 45 | 30 | 45 × 0,4 + 30 × 0,6 = 18,0 + 18,0 | 36,0 | 36,0 >= 50 → yanlış | 36.0 kaldı |
Çıktıda ortalamanın 58.0 biçiminde, sonunda .0 ile yazıldığına dikkat edilmelidir. Metot double döndürdüğü için Java sayıyı ondalıklı biçimde yazar; değer tam sayı olsa bile ondalık kısmı gösterir. 40 * 0.4 çarpımında int bir değer double bir değerle çarpıldığı için sonuç da double'dır.
1.4.8Uygulama ve sınama
Bir diyagram ya da program yazıldıktan sonra doğru çalıştığından emin olmak gerekir. Bunun iki yolu vardır: diyagramı ya da programı kâğıt üzerinde elle izlemek ve onu iyi seçilmiş girdilerle denemek.
1.4.8.11'den n'e kadar toplam
Problem, kullanıcının girdiği bir n sayısı için 1 + 2 + … + n toplamını bulmaktır. Bu problemde üç akış türü bir aradadır: n'nin okunması ve başlangıç değerleri sıralı, toplama tekrarlı, sonucun yazılması yine sıralı akıştır.
System.out.print("n: ");
int n = giris.nextInt();
int toplam = 0;
int i = 1;
while (i <= n) {
toplam += i;
i += 1;
}
System.out.println("Toplam: " + toplam);toplam bir biriktiricidir: 0'dan başlar ve her turda o anki i kadar büyür. i ise bir sayaçtır: 1'den başlar ve her turda 1 artar. Tablo 1.4.15 kullanıcının 4 girdiği çalıştırmadır.
| Adım | Koşul ve işlem | toplam | i |
|---|---|---|---|
| başlangıç | — | 0 | 1 |
| 1. tur | 1 <= 4 → doğru; 0 + 1 = 1 | 1 | 2 |
| 2. tur | 2 <= 4 → doğru; 1 + 2 = 3 | 3 | 3 |
| 3. tur | 3 <= 4 → doğru; 3 + 3 = 6 | 6 | 4 |
| 4. tur | 4 <= 4 → doğru; 6 + 4 = 10 | 10 | 5 |
| karar | 5 <= 4 → yanlış | 10 | 5 |
Gövde 4 kez, koşul 5 kez çalışır. Program Toplam: 10 yazar; 1 + 2 + 3 + 4 = 10'dur. n = 5 için aynı diyagram bir tur daha döner ve Toplam: 15 yazar. Bu sonuç Gauss'un formülüyle de denetlenebilir: 1'den n'e toplam n(n + 1)/2'dir. n = 4 için 4 · 5 / 2 = 10, n = 5 için 5 · 6 / 2 = 15 bulunur.
Biriktiricinin başlangıç değeri sonucu doğrudan etkiler. “toplam = 0” kutusu yanlışlıkla “toplam = 1” yazılırsa döngü yine 1 + 2 + 3 + 4 = 10 ekler, ama başlangıç 1 olduğu için sonuç 11 çıkar. Toplama için biriktirici 0 ile, çarpma için 1 ile başlatılır. Örneğin n! hesaplanırken çarpım f = 1 ile başlar; f = 0 ile başlasaydı her çarpım 0 verirdi. Derleyici bu mantık hatalarını yakalamaz.
1.4.8.2Masa başı kontrol ve izleme tablosu
Masa başı kontrol (desk check), bir diyagramın ya da kodun bilgisayar kullanılmadan, bir girdiyle kâğıt üzerinde izlenmesidir. İzleme tablosu (trace table), bu izlemede değişkenlerin her adımdaki değerlerini gösteren tablodur: her değişkene bir sütun, her tura bir satır ayrılır.
Örnek olarak bir sayının basamaklarını toplayan küçük bir program alınabilir. 472 sayısının basamakları 4, 7 ve 2'dir; toplamları 13'tür.
int sayi = 472, toplam = 0;
while (sayi > 0) {
toplam += sayi % 10;
sayi /= 10;
}
System.out.println(toplam);Program iki tam sayı işlemine dayanır. sayi % 10 sayının son basamağını verir: 472 % 10 = 2. sayi / 10 ise tam sayı bölmesidir ve son basamağı atar: 472 / 10 = 47. Basamaklar böylece sağdan sola, birer birer alınır. toplam += sayi % 10, toplam = toplam + sayi % 10'un kısa yazılışıdır; sayi /= 10 de sayi = sayi / 10 demektir. Tablo 1.4.16 masa başı kontrolün izleme tablosudur.
| Adım | sayi % 10 | toplam | sayi | Koşul |
|---|---|---|---|---|
| başlangıç | — | 0 | 472 | 472 > 0 → doğru |
| 1. tur | 2 | 2 | 47 | 47 > 0 → doğru |
| 2. tur | 7 | 9 | 4 | 4 > 0 → doğru |
| 3. tur | 4 | 13 | 0 | 0 > 0 → yanlış |
Tablo döngünün kaç kez döndüğünü de gösterir: 3 tur ve 4 sınama. Program 13 yazar. Tablonun asıl değeri, hataları program çalıştırılmadan göstermesidir. “sayı = sayı / 10” kutusu unutulsaydı sayi sütunu her satırda 472 kalırdı. Koşul hep doğru olurdu ve toplam her turda 2 artardı: 2, 4, 6, … Tablonun ikinci satırında bu tuhaflık hemen görülür: döngü hiç bitmeyecektir. Program çalıştırılsaydı bu hata ancak ekran donduğunda fark edilirdi.
İzleme tablosu kurarken birkaç alışkanlık işe yarar. Her değişkene bir sütun ayrılır; koşul için de ayrı bir sütun açılır. Bir değişken değiştiğinde yeni değer yeni satıra yazılır, eskisi silinmez; böylece değişimin geçmişi görünür. Döngü bittiğinde değişkenlerin son değerleri ayrıca not edilir; döngüden sonraki adımlar bu değerleri kullanır.
1.4.8.3Test durumları
Bir diyagramın tek bir girdiyle doğru çalışması, her girdiyle doğru çalışacağını göstermez. İç içe karar diyagramı 5 girdisiyle denenirse yalnızca “pozitif” kolu çalışır; öteki iki kolun doğru olup olmadığı anlaşılmaz. Bu yüzden girdiler bilinçli olarak seçilir.
Yol kapsama (path coverage), sınamada her karar kutusunun her çıkışının en az bir kez çalıştırılmasıdır. Sınır değerleri, koşulun sonucunun değiştiği noktanın hemen iki yanındaki değerlerdir.
Tablo 1.4.17 pozitif/negatif/sıfır diyagramı için seçilmiş test durumlarıdır. Her girdinin yanında neden seçildiği ve beklenen çıktı yazılıdır.
| Girdi | Neden seçildi? | Beklenen |
|---|---|---|
| 5 | 1. kararın Evet yolu | pozitif |
| −2 | 2. kararın Evet yolu | negatif |
| 0 | iki kararın Hayır yolu | sıfır |
| 1 ve −1 | sınırın hemen iki yanı | pozitif, negatif |
İlk üç girdi yol kapsamayı sağlar: üç Yaz kutusunun her biri bir kez çalışır. Son satırdaki 1 ve −1 sınır değerleridir. Koşul sayi > 0 yerine yanlışlıkla sayi >= 0 yazılmış olsaydı 5 ve −2 yine doğru sonuç verirdi; hata ancak 0 girildiğinde “pozitif” yazılmasıyla ortaya çıkardı. Bir eksik/bir fazla hataları tam olarak sınır değerlerinde görünür. not >= 50 gibi bir koşul için sınır değerleri 49 ve 50'dir.
Döngüler için ayrı bir kural vardır: döngü hiç dönmeyen, bir kez dönen ve çok kez dönen girdilerle denenir. Tablo 1.4.18 1'den n'e toplam diyagramı için bu durumları verir.
| n | Neden seçildi? | Beklenen |
|---|---|---|
| 0 | gövde hiç çalışmaz | Toplam: 0 |
| 1 | tek tur | Toplam: 1 |
| 4 | olağan durum | Toplam: 10 |
| −3 | geçersiz girdi | Toplam: 0 (istenen bu mu?) |
n = 0 için 1 <= 0 yanlıştır ve gövde hiç çalışmaz; program Toplam: 0 yazar. Bu doğru bir sonuçtur: hiç sayı toplanmamıştır. n = −3 için de aynı şey olur. Ama burada sonuç tartışmalıdır. Negatif bir n anlamsız bir girdidir; programın 0 yazması yerine bir uyarı vermesi daha doğru olabilir. Test durumu bu soruyu açığa çıkarır; cevabı ise problemin tanımı verir.
Sınamanın son kuralı, beklenen çıktının denemeden önce elle bulunmasıdır. Önce n = 4 için sonucun 10 olması gerektiği hesaplanır, sonra program çalıştırılır ve gerçek çıktıyla karşılaştırılır. Program çalıştırıldıktan sonra çıktıya bakıp “doğru görünüyor” demek, hatayı gözden kaçırmanın en kolay yoludur. Fark çıkarsa hata ya diyagramda, ya kodda ya da beklentinin kendisindedir.
1.4.8.4Algoritmayı göstermenin yolları
Akış diyagramı bir algoritmayı göstermenin tek yolu değildir. Tablo 1.4.19 dört gösterimi tek/çift örneği üzerinden karşılaştırır.
| Gösterim | Tek/çift örneği | Güçlü yanı | Zayıf yanı |
|---|---|---|---|
| Doğal dil | “Sayıyı oku; 2'ye bölümünden kalan 0 ise çift, değilse tek yaz.” | Herkes okuyabilir | Belirsiz olabilir |
| Akış diyagramı | Oku → İşlem → Karar → Yaz çift / Yaz tek | Akışı görsel gösterir; dallanma ve döngü kolay görülür | Büyük problemlerde hantal |
| Sözde kod | OKU sayı; EĞER sayı mod 2 = 0 İSE YAZ "çift" DEĞİLSE YAZ "tek" | Hızlı yazılır, koda yakın | Standart bir söz dizimi yok |
| Java | if (sayi % 2 == 0) … else … | Bilgisayar çalıştırabilir | Söz dizimi kurallarına uymak gerekir |
Doğal dil en kolay okunan gösterimdir, ama belirsizdir. “Sayı büyükse” gibi bir ifade neyden büyük olduğunu söylemeyebilir. Sözde kod doğal dille programlama dili arasında durur. Anahtar sözcükleri (OKU, EĞER, İSE, YAZ) programlama diline benzer, ama derleyicisi yoktur ve herkes kendi biçimini kullanır. Java en kesin gösterimdir; bilgisayar onu çalıştırabilir. Buna karşılık noktalı virgülden süslü paranteze kadar bütün kurallara uymak gerekir. Akış diyagramı bu yelpazede görselliğiyle öne çıkar: dallanmalar ve döngüler okların biçiminden hemen anlaşılır.
Yazılım mühendisliğinde akış diyagramının bugünkü karşılığı UML (Unified Modeling Language, Birleşik Modelleme Dili) etkinlik diyagramıdır (activity diagram). Fikir aynıdır, semboller biraz farklıdır. Başlangıç dolu bir daireyle, karar yine bir eşkenar dörtgenle, etkinlikler yuvarlatılmış kutularla çizilir. Nesne yönelimli programların tasarımında etkinlik diyagramları UML'nin öteki diyagramlarıyla birlikte kullanılır.
1.4.8.5Çizim araçları
Akış diyagramı kâğıt ve kalemle çizilebileceği gibi bilgisayarda da çizilebilir. Tablo 1.4.20 yaygın araçları özetler.
| Araç | Ne yapar? | Not |
|---|---|---|
| Kâğıt ve kalem | En hızlı taslak; sınavda tek seçenek | Düzeltmesi zahmetli |
| draw.io (diagrams.net) | Tarayıcıda çalışan ücretsiz çizim aracı; hazır akış diyagramı sembolleri | Çizer, çalıştırmaz |
| Microsoft Visio | Ticari diyagram programı; standart sembol kütüphaneleri | Ücretli |
| Flowgorithm | Diyagramı çalıştırır, değişkenleri izler; Java dâhil birçok dile kod üretir | Ücretsiz, eğitim amaçlı |
| Mermaid | Metinden diyagram çizer; GitHub ve birçok Markdown aracı doğrudan gösterir | Kodla birlikte saklanır |
Mermaid ilginç bir yaklaşım izler: diyagram çizilmez, yazılır. Tek/çift diyagramının Mermaid metni şöyledir:
flowchart TD
A([Başla]) --> B[/Oku sayı/]
B --> C{sayı mod 2 = 0 ?}
C -- Evet --> D[Yaz çift]
C -- Hayır --> E[Yaz tek]
D --> F([Bitir])
E --> Fİlk satırdaki flowchart TD bir akış diyagramı başlatır; TD (top-down) yukarıdan aşağıya yerleşim demektir. Her düğümün bir harf adı ve köşeli parantezler içinde bir yazısı vardır. Parantezlerin biçimi sembolü belirler: ([ ]) Başla/Bitir ovali, [/ /] giriş paralelkenarı, { } karar eşkenar dörtgeni, [ ] işlem dikdörtgenidir. --> bir akış çizgisi, -- Evet --> etiketli bir karar çıkışıdır. Kutuların sayfadaki yerini araç kendisi belirler. Metin biçimi, diyagramın program koduyla aynı dosyalarda saklanmasını ve kodla birlikte güncellenmesini kolaylaştırır.
Çizim aracı ne olursa olsun kurallar aynıdır: tek Başla, etiketli karar çıkışları, kesişmeyen oklar. Araç yalnızca çizimi kolaylaştırır; diyagramın doğruluğu yine onu tasarlayan kişiye bağlıdır.
1.4.9Sık yapılan hatalar
Akış diyagramı çizerken ve diyagramı Java'ya çevirirken bazı hatalar çok sık görülür. Bir kısmını derleyici yakalar; bir kısmı ise derlenen ama yanlış çalışan programlara yol açar. İkinci gruptaki hatalar daha tehlikelidir, çünkü program hiçbir uyarı vermeden yanlış sonuç üretir.
Karar kutusunda tek çıkış. Karar sembolünden iki ok çıkmalı ve ikisi de E/H diye etiketlenmelidir. Yalnızca Evet oku çizilirse “hayır” durumunda ne olacağı belirsiz kalır. Hayır kolunda yapılacak iş yoksa bile ok çizilir ve doğrudan birleşme noktasına bağlanır.
Yanlış sembol. Klavyeden okuma için dikdörtgen, hesaplama için paralelkenar kullanmak diyagramı yanıltıcı yapar. Kural basittir: girdi paralelkenar, işlem dikdörtgen, soru eşkenar dörtgendir.
Karşılaştırmada = kullanmak. if (sonuc = 0) derlenmez: error: incompatible types: int cannot be converted to boolean. Karşılaştırma == ile yazılır: if (sonuc == 0).
Başlangıç değerini unutmak. Diyagramda “sayaç = 1” kutusu yoksa Java da hata verir. int sayac; diye tanımlanıp değer verilmeden while (sayac <= 10) yazılırsa derleyici error: variable sayac might not have been initialized iletisini verir.
Güncellemeyi unutmak. “sayaç += 1” kutusu yoksa sayaç hiç değişmez ve koşul hep doğru kalır: sonsuz döngü. Derleyici bu hatayı yakalamaz; program ekrana durmadan 1 yazar.
Sınır hatası. “1'den 10'a kadar” için sayac < 10 yazmak 10'u atlar. Koşul son değerle sınanmalıdır: sayaç 10 iken koşul doğru olmalıdır.
Döngü başlığına noktalı virgül. while (sayac <= 10); satırı derlenir, ama sondaki noktalı virgül boş bir deyimdir ve döngünün gövdesi olur. Altındaki süslü parantezli blok döngünün parçası değildir. Sayaç hiç artmadığı için koşul hep doğru kalır ve program hiçbir şey yazmadan takılır. JDK 21 bu kodu uyarısız derler.
Geri oku yanlış yere bağlamak. 1'den 10'a kadar yazan diyagramda geri ok karar kutusuna değil, “sayaç = 1” kutusunun üstüne dönerse sayaç her turda yeniden 1 olur. Koşul hep doğru kalır ve ekrana durmadan 1 yazılır: yine sonsuz döngü. Geri ok, başlangıç değerinden sonraya, karar kutusuna dönmelidir. Java'da bu hata, başlangıç atamasının döngünün içine yazılmasına karşılık gelir.
Tam sayı bölmesi. Diyagramdaki “toplam / 5” ifadesi Java'da iki int arasında yazılırsa ondalık kısım atılır: 283 / 5 = 56. Ondalıklı sonuç için bölenlerden biri double olmalıdır: toplam / 5.0 ya da (double) toplam / adet.
1.4.10Özet
- Algoritma bir problemi çözen sıralı ve sonlu adımlardır. Akış diyagramı algoritmanın semboller ve oklarla çizimidir; programlama dilinden bağımsız bir plandır. Büyük programlarda hantallaşır; o zaman sözde kod daha pratiktir.
- Temel semboller: oval Başla/Bitir, paralelkenar giriş, dikdörtgen işlem, eşkenar dörtgen karar, altıgen döngü, dalgalı kutu yazdır, çember bağlantı noktası, ok akış çizgisi. Ek semboller: alt program, sayfa dışı bağlantı, veri deposu, elle giriş, açıklama, hazırlık.
- Çizim kuralları: tek Başla, en az bir Bitir; yukarıdan aşağıya ve soldan sağa akış; yalnızca karar kutusunun iki çıkışı vardır ve çıkışlar E/H diye etiketlenir; çizgiler kesişmez.
- Java karşılıkları: Başla/Bitir →
main; giriş →nextInt(); işlem → atama; karar →if/else; karar + geri ok →while; altıgen →for; yazdır →println; alt program → metot. Diyagramdaki “=” işlem kutusunda atama (=), karar kutusunda karşılaştırmadır (==). - Böhm–Jacopini teoremi: her algoritma sıra, seçim ve tekrar yapılarıyla yazılabilir. Yapısal diyagramda her yapının tek girişi ve tek çıkışı vardır. Java'da
gotokullanılamaz;breakvecontinueyalnızca içinde bulundukları döngüye etki eden sınırlı atlamalardır. - Sıralı akışta her adım tam bir kez çalışır; birbirine bağlı adımların sırası değiştirilemez. Java, değer almamış bir değişkenin okunmasını derleme sırasında yakalar.
- Koşullu akışta karar kutusu K'ye göre P ya da Q çalışır. Üç ve daha çok ihtimal iç içe kararlarla (
else if) çizilir. Java'da%işleminin sonucu bölünenin işaretini alır:-3 % 2 == -1. VE&&, VEYA||ile yazılır ve kısa devre değerlendirilir. - Tekrarlı akışta geri ok karar kutusuna döner. Döngünün üç parçası başlangıç, koşul ve güncellemedir. Karar başta ise koşul gövdeden bir fazla sınanır (1'den 10'a: gövde 10, koşul 11 kez).
- Döngü kalıpları: sayaç koşul sağlanınca 1 artar; biriktirici her turda değer toplar (toplama için 0, çarpma için 1 ile başlar); bayrak bir olayın olup olmadığını tutar. Nöbetçi değerli döngüde önce okuma yapılır; nöbetçi toplama katılmaz; döngüden sonra adet = 0 durumu ayrıca denetlenir.
- Erken çıkış
breakile yazılır; yapısal karşılığı bir bayrakla döngü koşulunu genişletmektir. İç içe döngüde iç gövde m × n kez çalışır. - Alt program ayrı çizilen ve çağrılan adım dizisidir; parametre alır, Dön kutusuyla değer döndürür. Java'da metottur; parametreler kopyalanır, yerel değişkenler çağrı bitince yok olur.
- Masa başı kontrolde diyagram ya da kod bir izleme tablosuyla kâğıt üzerinde yürütülür. Test durumları her kararın her çıkışını (yol kapsama) ve sınır değerlerini içerir. Döngü hiç dönmeyen, bir kez ve çok kez dönen girdilerle denenir; beklenen çıktı denemeden önce elle bulunur.
- Tuzaklar: < / ≤ sınır hatası; güncellemeyi unutmak ya da geri oku başlangıç kutusuna bağlamak (sonsuz döngü); döngü başlığına noktalı virgül; tam sayı bölmesi.
1.4.11Kavram listesi
Terimlerin İngilizce karşılıkları ve öteki bölümlerdeki kullanımları terim sözlüğünde bulunur.
- algoritma algorithm
- akış diyagramı flowchart
- sözde kod pseudocode
- sıralı akış sequential flow
- koşullu akış conditional flow
- yapısal diyagram structured flowchart
- iç içe karar nested decision
- karşılaştırma operatörü comparison operator
- mantıksal operatör logical operator
- kısa devre değerlendirme short-circuit evaluation
- döngü loop
- while döngüsü while loop
- for döngüsü for loop
- sonsuz döngü infinite loop
- biriktirici accumulator
- nöbetçi değer sentinel value
- break / continue break / continue
- iç içe döngü nested loop
- alt program subprogram (predefined process)
- masa başı kontrol desk check
- izleme tablosu trace table
- yol kapsama path coverage
1.4.12Kendini Dene
“Sonuçları dosyaya kaydet”, “toplamı ekrana yaz” ve “i = 1; i ≤ 5; i++” adımları hangi sembollerle çizilir?
Cevap
Dosyaya kaydetme kalıcı bir yere yazmaktır: veri deposu (silindir). Ekrana yazma Yazdır sembolüyle (dalgalı alt kenarlı kutu) çizilir; bazı kaynaklar çıkış paralelkenarı da kullanır. Başlangıç, koşul ve güncellemeyi bir arada içeren ifade döngü sembolüdür (altıgen); Java karşılığı
for (int i = 1; i <= 5; i++)'dır.int x = 50, adim = 0; while (x > 1) { x = x / 2; adim++; }parçası çalıştıktan sonraxveadimkaçtır?Cevap
Tam sayı bölmesiyle x şu değerleri alır: 50 → 25 → 12 → 6 → 3 → 1. Her bölmede
adim1 artar; 5 bölme yapılır. x = 1 olunca1 > 1yanlıştır ve döngü biter. Sonuç:x = 1,adim = 5. 25 / 2 ve 3 / 2 bölmelerinde ondalık kısım atılmıştır.for (int i = 3; i <= 15; i += 4) toplam += i;döngüsü kaç kez döner?toplam0'dan başlıyorsa sonunda kaç olur?Cevap
i3, 7, 11 ve 15 değerlerini alır; 15 de koşulu sağlar çünkü koşul<=ile yazılmıştır. Bir sonraki değer 19'dur ve19 <= 15yanlıştır. Döngü 4 kez döner;toplam = 3 + 7 + 11 + 15 = 36. Koşul 5 kez sınanır.Nöbetçi değeri 0 olan ortalama programına kullanıcı sırasıyla 8, 0, 5, 0 giriyor. Program ne yazar? 5 değeri ne olur?
Cevap
İlk okunan 8'dir;
8 != 0doğrudur,toplam = 8,adet = 1olur. Gövdenin sonunda 0 okunur; 0 nöbetçidir ve döngü biter.adet > 0doğru olduğu içinOrtalama: 8.0yazılır. 5 ve ikinci 0 hiç okunmaz; program onları beklemeden biter. Nöbetçi, girdinin nerede bittiğini kesin olarak belirler.İlk negatif sayının sırasını bulan program 3, −1, −4, 2, 7 girdisiyle çalışıyor.
break'li sürüm ve bayraklı sürüm ne yazar? Döngü bittiğinde iki sürümdeikaçtır?Cevap
İkinci sayı −1 negatiftir; iki sürüm de
Sıra: 2yazar. −4 hiç dikkate alınmaz, çünkü aranan ilk negatif sayıdır.break'li sürümde döngüi = 2iken biter. Bayraklı sürümde ikinci turun sonundai++çalışır;i = 3olur ve3 <= 5 && !trueyanlış çıkar. (Sorudaki karşılaştırma içini'nin döngüden önce tanımlandığı varsayılır.)Dış döngü
a= 1'den 3'e kadar dönüyor. İç döngüb= 1'dena'ya kadar dönüyor ve gövdesi bir*yazıyor; iç döngüden sonraprintln()çalışıyor. Ekranda ne görülür? Kaç yıldız yazılır?Cevap
İç döngünün tur sayısı dış değişkene bağlıdır: a = 1 için 1, a = 2 için 2, a = 3 için 3 tur. Ekranda üç satır görülür:
*,**,***. Toplam 1 + 2 + 3 = 6 yıldız yazılır. Burada iç gövdenin çalışma sayısı m × n değil, tur sayılarının toplamıdır.“1'den 100'e kadar 5'in katlarını yaz” işi için
for (int i = 5; i < 100; i += 5)yazılmış. Kaç sayı yazılır? Hata nedir?Cevap
5, 10, …, 95 yazılır: 19 sayı. i = 100 olduğunda
100 < 100yanlıştır ve 100 yazılmaz. Bu bir eksik hatasıdır. Koşul son değerle sınanırsa hata görülür: 100 de katlardan biridir, o hâlde koşuli <= 100olmalıdır. Düzeltilmiş döngü 20 sayı yazar.Tek/çift programında koşul
sayi % 2 == 1diye yazılmış. −7 girildiğinde ne yazılır? Koşulsayi % 2 == 0olsaydı ne yazılırdı?Cevap
Java'da kalan bölünenin işaretini alır:
-7 % 2 == -1. Birinci koşulda-1 == 1yanlıştır ve −7 “çift” sanılır; bu yanlıştır. İkinci koşulda-1 == 0yanlıştır, Hayır kolundan “tek” yazılır; bu doğrudur. Çiftliği sınamak negatif sayılarda da güvenlidir.“Not ≥ 50 ise ‘geçti’, değilse ‘kaldı’ yaz” diyagramını sınamak için en az hangi girdiler seçilmelidir? Neden?
Cevap
Yol kapsama için her iki kol da çalışmalıdır: biri ≥ 50, biri < 50 olan iki not. Sınır değerleri için koşulun sonucunun değiştiği noktanın iki yanı seçilir: 49 (kaldı) ve 50 (geçti). Bu iki girdi aynı zamanda iki kolu da kapsar. Geçerli aralığın uçları (0 ve 100) da eklenebilir. Koşul yanlışlıkla
> 50yazılmışsa hatayı yalnızca 50 girdisi ortaya çıkarır.
1.4.13İleri okuma
- P. Deitel ve H. Deitel, Java: How to Program (11. baskı, 2017), Bölüm 4 ve 5: Java'nın kontrol deyimlerini UML etkinlik diyagramlarıyla birlikte anlatır; sayaç, nöbetçi değer ve iç içe kontrol yapılarını çok sayıda örnekle işler.
- A. B. Downey ve C. Mayfield, Think Java (2. baskı, 2019): koşullar, döngüler ve metotlar için kısa, sade bir giriş sunar; kitabın tamamı yazarların sitesinde ücretsiz okunabilir.
- C. Böhm ve G. Jacopini, “Flow Diagrams, Turing Machines and Languages with Only Two Formation Rules” (1966): yapısal programlama teoreminin özgün makalesidir; akış diyagramlarının üç yapıya indirgenebileceğini kanıtlar.
- Oracle, The Java Tutorials, “Control Flow Statements”:
if,switch,while,do-while,for,breakvecontinuedeyimlerinin resmî açıklaması ve kısa örnekleri.
1.4.14Kaynaklar
- ISO 5807:1985, Information processing — Documentation symbols and conventions for data, program and system flowcharts, program network charts and system resources charts.
- C. Böhm, G. Jacopini, “Flow Diagrams, Turing Machines and Languages with Only Two Formation Rules”, Communications of the ACM 9(5), 1966.
- P. Deitel, H. Deitel, Java: How to Program, 11. baskı, Pearson, 2017.
- A. B. Downey, C. Mayfield, Think Java, 2. baskı, O'Reilly, 2019.
- Oracle, The Java Tutorials: “Control Flow Statements” (docs.oracle.com/javase/tutorial).
- K. Sierra, B. Bates, T. Gee, Head First Java, 3. baskı, O'Reilly, 2022.
İlgili sayfalar: Bölüm 1 Akış Diyagramları sunumu · Çalışma soruları · Terim sözlüğü · © Sercan Külcü. Tüm hakları saklıdır.