Bölüm 3.1: Kontrol Yapıları
Giriş
Öğrenme Çıktıları
Sıralı işlem, karar ve döngü yapılarının programın akışını nasıl yönlendirdiğini açıklamak.
if, if-else, else if zinciri, iç içe kararlar ve &&, || ile birleşik koşullarla koşula bağlı kod yazmak.
Bir değeri sabitlerle karşılaştırmak; break'in görevini ve “aşağı düşme” davranışını açıklamak.
for, while ve do-while döngülerini doğru yerde seçmek; sonsuz döngü ve sınır hatalarından kaçınmak.
Desen, tablo ve basamak örneklerinde iç içe döngülerin kaç kez döndüğünü hesaplamak.
Bir programı adım adım izleyerek değişken değerlerini ve ekran çıktısını önceden bulmak; break ve continue'nun etkisini göstermek.
Giriş
Kontrol Yapıları
- Kontrol yapıları (control structures) programın akışını, yani deyimlerin hangi sırayla ve kaç kez çalışacağını yönlendirir.
- Java'da üç temel kontrol yapısı vardır; her program bu üçünün birleşimiyle yazılabilir:
Deyimler yukarıdan aşağıya, birer kez çalışır.
Koşula göre iki (veya daha çok) yoldan biri seçilir: if-else, switch.
Koşul sağlandıkça işlemler tekrarlanır: for, while, do-while.
Önemi: kararlar sayesinde program farklı durumlara ve kullanıcı girdilerine farklı tepki verir; döngüler tekrar eden işleri otomatikleştirir. Programlar böylece esnek ve güçlü olur.
Giriş · Adım adım kod izleme
Sıralı İşlemler
Kod, yukarıdan aşağıya doğru satır satır sırayla çalışır; bir işlem bitmeden diğeri başlamaz. Kontrol yapısı kullanılmayan her program sıralıdır.
İlk satır çalışır: x'e 5 yazılır. Sonraki satır bu satır bitmeden başlamaz.
İkinci satır: y'ye 10 yazılır.
Üçüncü satır, önceki iki satırın sonuçlarını kullanır: 5 + 10 = 15.
Son satır sonucu ekrana yazar. Satırların sırası değişseydi (ör. 3. satır en başta) program derlenmezdi.
int x = 5; int y = 10; int sonuc = x + y; System.out.println(sonuc);
Karar Yapıları: if
Karar Verme İşlemi
- Karar verme, programın hangi yolu izleyeceğine çalışma zamanında karar vermesidir.
- Belirli koşullara bağlı olarak farklı işlemleri yürütme yeteneği sağlar.
- Java'da
if-elseveswitch-caseile yapılır. - Koşul, sonucu
trueya dafalseolan bir mantıksal ifadedir (boolean expression). - Benzetme: yol ayrımındaki tabela. “Hava yağmurluysa şemsiye al, değilse alma.”
- Önemi: program farklı şartlara ve kullanıcı girdilerine tepki verir, kodun akışı yönlendirilir, esneklik artar.
| İşleç | Anlamı | Örnek (x = 7) |
|---|---|---|
== | eşit mi | x == 7 → true |
!= | eşit değil mi | x != 7 → false |
< > | küçük / büyük | x < 10 → true |
<= >= | küçük-eşit / büyük-eşit | x >= 8 → false |
= atamadır, == karşılaştırmadır. if (x = 7) derlenmez: koşul boolean olmalıdır.Karar Yapıları: if
if-else Yapısı
if (koşul) { // Koşul doğruysa burası çalışır } else { // Koşul yanlışsa burası çalışır }
- Önce koşul değerlendirilir.
- Koşul doğru (
true) iseifbloğu çalışır,elsebloğu atlanır. - Koşul yanlış (
false) iseifbloğu atlanır,elsebloğu çalışır. elsekısmı isteğe bağlıdır (opsiyonel). İki bloktan en fazla biri çalışır.- Koşul her zaman parantez içinde yazılır:
if (koşul).
Karar Yapıları: if
Yalnız if ve Süslü Parantezler
else olmadan if
int sicaklik = 35; if (sicaklik > 30) { System.out.println("Hava sıcak!"); } System.out.println("Program devam ediyor.");
Hava sıcak! Program devam ediyor.
Koşul yanlış olsaydı (ör. sicaklik = 20) yalnızca “Program devam ediyor.” yazılırdı. if'ten sonraki deyim her durumda çalışır.
Tuzak: süslü parantez yok
int sicaklik = 35; if (sicaklik > 40) System.out.println("Çok sıcak!"); System.out.println("Bol su için.");
Bol su için.
Parantez yoksa if'e yalnızca ilk deyim bağlıdır. Girinti Java için anlamsızdır: “Bol su için.” koşuldan bağımsız çalışır. Bu yüzden tek satırlık blokta bile { } kullanılır.
Karar Yapıları: if · Adım adım kod izleme
Örnek: Yaş Kontrolü
yas değişkenine 18 atanır.
Koşul değerlendirilir: 18 >= 18 → true. Akış “E” (evet) koluna gider.
if bloğu çalışır ve mesaj yazdırılır.
else bloğu (satır 5) atlanır. yas = 16 olsaydı koşul false olur, yalnızca “Ehliyet alamazsınız.” yazılırdı.
int yas = 18; if (yas >= 18) { System.out.println("Ehliyet alabilirsiniz."); } else { System.out.println("Ehliyet alamazsınız."); }
Karar Yapıları: if · Adım adım kod izleme
Örnek: Mutlak Değer
Klavyeden okumak için bir Scanner nesnesi oluşturulur (dosyanın başında import java.util.Scanner; gerekir).
Kullanıcıya ne gireceği söylenir. print satır atlamaz; imleç aynı satırda bekler.
Kullanıcı -7,5 yazar. Türkçe bölge ayarlı bilgisayarda ondalık ayırıcı virgüldür; -7.5 yazmak InputMismatchException verir.
mutlakDeger tanımlanır ama henüz değeri yoktur.
Koşul: -7.5 < 0 → true.
-sayi = −(−7.5) = 7.5 atanır. else bloğu atlanacak.
Sonuç yazılır. println ise double değeri her zaman noktayla yazar: 7.5.
Scanner scanner = new Scanner(System.in); System.out.print("Bir sayı girin: "); double sayi = scanner.nextDouble(); double mutlakDeger; if (sayi < 0) { mutlakDeger = -sayi; } else { mutlakDeger = sayi; } System.out.println("Mutlak değer: " + mutlakDeger);
Karar Yapıları: if
else-if Zinciri
import java.util.Scanner; public class PozitifNegatif { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("Bir sayı girin: "); double sayi = scanner.nextDouble(); if (sayi > 0) { System.out.println("Sayı pozitif."); } else if (sayi < 0) { System.out.println("Sayı negatif."); } else { System.out.println("Sayı sıfır."); } } }
- İkiden çok seçenek varsa
else ifile koşullar art arda sınanır. - Koşullar yukarıdan aşağıya denenir; ilk doğru koşulun bloğu çalışır, gerisi atlanır.
- Hiçbiri doğru değilse son
elseçalışır (varsa).
Üç ayrı çalıştırma
Bir sayı girin: 4 Sayı pozitif.
Bir sayı girin: -2 Sayı negatif.
Bir sayı girin: 0 Sayı sıfır.
Karar Yapıları: if · Adım adım kod izleme
else-if Zinciri: Harf Notu
not = 75.
75 >= 90 → false. Sonraki else if'e geçilir.
75 >= 80 → false. Sonraki koşula geçilir.
75 >= 70 → true: ilk doğru koşul bulundu.
“C” yazılır.
Kalan koşullar (not >= 60 dahil) hiç sınanmaz. Sıra önemlidir: >= 60 en üstte olsaydı 75 için “D” yazılırdı.
int not = 75; if (not >= 90) { System.out.println("A"); } else if (not >= 80) { System.out.println("B"); } else if (not >= 70) { System.out.println("C"); } else if (not >= 60) { System.out.println("D"); } else { System.out.println("F"); }
Karar Yapıları: if
İç İçe Kararlar (Nesting)
- Bir karar yapısının bloğu içinde başka bir karar yapısı kullanılabilir.
- Daha karmaşık koşullar ve işlemler için kullanışlıdır: dış koşul sağlandıktan sonra ikinci bir soru sorulur.
- İç
ifyalnızca dış koşul doğruysa sınanır. - Çok derin iç içe yapı kodun okunabilirliğini olumsuz etkiler; düzgün girinti kullanılır, mümkünse
&&veyaelse ifile düzleştirilir:if (yas >= 18) { if (ehliyetVar) … }ileif (yas >= 18 && ehliyetVar) …aynı işi yapar. - Aralık denetimi de
&&ile yazılır:not >= 60 && not < 90;60 <= not < 90derlenmez.
if (koşul1) { if (koşul2) { // koşul1 VE koşul2 doğru } } else { // koşul1 yanlış }
Karar Yapıları: if · Adım adım kod izleme
İç İçe Karar: Harf Notu
not = 85.
Dış koşul: 85 >= 60 → true. Dış if bloğuna girilir.
İç koşul: 85 >= 90 → false. İç else'e gidilir.
“Harf notu: B” yazılır.
Dış else (satır 9) atlanır. not = 45 olsaydı iç if hiç sınanmaz, doğrudan F yazılırdı.
int not = 85; if (not >= 60) { if (not >= 90) { System.out.println("Harf notu: A"); } else { System.out.println("Harf notu: B"); } } else { System.out.println("Harf notu: F"); }
Karar Yapıları: if · Adım adım kod izleme
Kısa Devre: Kodun Adım Adım İzlenmesi
b = 0: a / b hesaplanırsa sıfıra bölme hatası (ArithmeticException) oluşur. sayac sağ tarafların çalışıp çalışmadığını sayacak.
&& önce sol tarafı hesaplar: b != 0 → false.
Sol false ise &&'nin sonucu zaten false: a / b > 2 hiç hesaplanmaz, hata oluşmaz. s1 = false.
|| için sol taraf: b == 0 → true.
Sol true ise ||'nin sonucu zaten true: ++sayac çalışmaz, sayac 0 kalır. s2 = true.
Yine &&; sol taraf b == 0 → true. Sonuç henüz belli değil.
Sağ taraf hesaplanmak zorunda: ++sayac → 1, 1 > 0 → true. s3 = true.
Üç sonuç yazdırılır: false true true.
sayac = 1: üç sağ taraftan yalnızca biri çalıştı. Yan etkili işlemleri (++) &&/||'nin sağına yazmak bu yüzden yanıltıcıdır.
int a = 10, b = 0, sayac = 0; boolean s1 = b != 0 && a / b > 2; boolean s2 = b == 0 || ++sayac > 0; boolean s3 = b == 0 && ++sayac > 0; System.out.println(s1 + " " + s2 + " " + s3); System.out.println("sayac = " + sayac);
Karar Yapıları: switch
switch-case Yapısı
- switch-case, bir değişkenin değerini bir dizi sabit değerle karşılaştırır ve duruma göre farklı işlemler yapar.
- Birden çok şarta dayalı bir yol seçmeye yarar.
- Aynı değişken için çok sayıda
==karşılaştırması olduğundaelse ifzincirinden daha düzenlidir. - Benzetme: asansör düğmeleri. Basılan kat numarası hangi kata gidileceğini seçer.
switch (değişken) { // kontrol edilen değer case değer1: // her case bir değer // İşlemler 1 break; case değer2: // İşlemler 2 break; // ... default: // hiçbiri eşleşmezse // Varsayılan işlemler (opsiyonel) }
Karar Yapıları: switch
switch-case İşleyişi
- Değişken,
casedeğerleriyle yukarıdan aşağıya karşılaştırılır. - Eşleşen
casebulunursa ocase'in işlemleri çalıştırılır, ardındanbreakileswitch'ten çıkılır. - Eşleşen
caseyoksadefaultbölümü (varsa) çalışır. defaultda yoksa hiçbir şey yapılmadanswitch'ten çıkılır.breakyazılmazsa çalışma bir sonraki case'e düşer (fall-through).
Karar Yapıları: switch · Adım adım kod izleme
Örnek: Mevsim Belirleme
ay = 4.
mevsim tanımlanır, henüz değeri yok.
switch (ay): değer 4 olarak bir kez hesaplanır, sonra case etiketleri aranır.
case 4 eşleşir. Aynı satırdaki üç case aynı koda iner.
mevsim = "İlkbahar".
break: switch'in kapanış parantezinin (satır 18) arkasına atlanır.
default sayesinde mevsim her yolda değer alır; yoksa: variable mevsim might not have been initialized.
int ay = 4; String mevsim; switch (ay) { case 3: case 4: case 5: mevsim = "İlkbahar"; break; case 6: case 7: case 8: mevsim = "Yaz"; break; case 9: case 10: case 11: mevsim = "Sonbahar"; break; case 12: case 1: case 2: mevsim = "Kış"; break; default: mevsim = "Bilinmiyor"; } System.out.println(ay + ". ay: " + mevsim);
Karar Yapıları: switch · Adım adım kod izleme
break Unutulursa: Aşağı Düşme
gun = 2.
2 değeriyle eşleşen case aranır.
case 1 atlanır, case 2 eşleşir.
“Salı” yazılır. Burada break yok!
case 3: etiketi bir karşılaştırma değildir; çalışma alttaki koda “düşer” (fall-through).
“Çarşamba” da yazılır, oysa gün 3 değil.
break ile switch'ten çıkılır; default çalışmaz.
switch'ten sonra devam edilir. Aşağı düşme istenmiyorsa her case break ile biter.
int gun = 2; switch (gun) { case 1: System.out.println("Pazartesi"); case 2: System.out.println("Salı"); case 3: System.out.println("Çarşamba"); break; default: System.out.println("Diğer gün"); } System.out.println("switch bitti");
Karar Yapıları: switch
switch: char ve String
char ile basit hesap makinesi
int a = 12, b = 4; char islem = '*'; int sonuc; switch (islem) { case '+': sonuc = a + b; break; case '-': sonuc = a - b; break; case '*': sonuc = a * b; break; case '/': sonuc = a / b; break; default: System.out.println("Geçersiz işlem"); sonuc = 0; } System.out.println(a + " " + islem + " " + b + " = " + sonuc);
12 * 4 = 48
String ile komut seçimi (Java 7+)
String komut = "dur"; switch (komut) { case "basla": System.out.println("Motor çalıştı"); break; case "dur": System.out.println("Motor durdu"); break; default: System.out.println("Bilinmeyen komut"); }
Motor durdu
Kısa case'ler tek satıra yazılabilir: case '+': sonuc = a + b; break;. String karşılaştırması büyük-küçük harfe duyarlıdır: "Dur" ≠ "dur".
Karar Yapıları: switch
switch Kuralları
- Seçici (parantez içindeki ifade) şu türlerden olabilir:
byte,short,char,int(ve sarmalayıcıları),String,enum. long,float,double,booleanile klasikswitchyazılamaz.casedeğerleri derleme zamanında bilinen sabitler olmalıdır (5,'a',"dur",finalsabitler).- Aynı değer iki
case'te kullanılamaz. - Aralık (
ay >= 3 && ay <= 5) veya karmaşık koşul içinif-elsegerekir.
double d = 2.5; switch (d) { ... }
error: selector type double is not allowedint b = 2; switch (a) { case b: break; }
error: constant expression requiredswitch (a) { case 1: break; case 1: break; }
error: duplicate case labelKarar Yapıları: switch
switch-case ve if-else
if-else / else if | switch-case | |
|---|---|---|
| Ne sınanır? | Her türlü boolean koşul: aralık, birleşik koşul, farklı değişkenler | Tek bir ifadenin sabit değerlerle eşitliği |
| Esneklik | Daha esnek | Yalnızca belirli tipler ve sabit case değerleri |
| Çok seçenekte | Uzun zincirler karmaşık görünebilir | Düzenli ve okunaklı bir liste |
| Tuzak | Koşul sırası yanlışsa yanlış dal seçilir | break unutulursa alttaki case'lere düşülür |
| Örnek | if (not >= 90) … else if (not >= 80) … | switch (ay) { case 3: … } |
Her switch, bir else if zinciriyle yazılabilir; tersi her zaman mümkün değildir (ör. not >= 90 gibi aralıklar).
Karar Yapıları: switch
Yeni switch (Java 14+)
int ay = 11; String mevsim = switch (ay) { case 3, 4, 5 -> "İlkbahar"; case 6, 7, 8 -> "Yaz"; case 9, 10, 11 -> "Sonbahar"; case 12, 1, 2 -> "Kış"; default -> "Bilinmiyor"; }; System.out.println(mevsim);
Sonbahar
- Java 14 ile gelen ok (arrow) biçimi:
case 3, 4, 5 -> … - Bir
casevirgülle birden çok değer alabilir. - Ok biçiminde aşağı düşme yoktur;
breakgerekmez. - switch ifadesi bir değer üretir ve doğrudan atanabilir; sonuna
;konur. - İfade biçimi tüm olasılıkları kapsamalıdır:
intiçindefaultzorunludur. - Bu derste klasik biçim esastır; ok biçimi Java 14 ve sonrasında kullanılabilir.
Uygulama: Sıcaklık
Sıcaklık Dönüşümü: Tablo ve Formüller
| Celsius (°C) | Fahrenheit (°F) | Kelvin (K) |
|---|---|---|
| −40 | −40 | 233,15 |
| 0 | 32 | 273,15 |
| 25 | 77 | 298,15 |
| 100 | 212 | 373,15 |
°F = (°C × 1.8) + 32
°C = (°F − 32) / 1.8
K = °C + 273.15
Hedef: formülleri Java'ya çevirmek ve tek bir değer için hesaplamak.
Uygulama: Sıcaklık
Sıcaklık Dönüşümü: Tek Değer
public class Program { public static void main(String[] args) { double celsius = 25.0; double fahrenheit = (celsius * 1.8) + 32; double kelvin = celsius + 273.15; System.out.println(celsius + " °C = " + fahrenheit + " °F = " + kelvin + " K"); } }
25.0 °C = 77.0 °F = 298.15 K
- Sıralı bir programdır: üç satır hesaplama, bir satır yazdırma; karar ya da döngü yoktur.
- Ondalıklı değerler için
doublekullanılır. Parantez önceliği netleştirir: öncecelsius * 1.8, sonra+ 32. +bir dizgiyle (String) kullanılınca birleştirme yapar;doubledeğerler25.0biçiminde yazılır.- Hesaplanan her değer kullanılmalıdır:
kelvinyazdırılmasaydı boşuna hesaplanmış olurdu.
Döngüler
Döngü ve Türleri
Döngü (loop), aynı işlemi birden çok kez tekrarlamak için kullanılır. Benzetme: pistte 10 tur koşmak; her turda aynı hareketler, tur sayacı bir artar.
Tekrar sayısı belli olduğunda; belirli bir aralıktaki değerlerle çalışır.
for (int i = 0; i < 5; i++) { … }
Belirli bir koşul sağlandığı sürece çalışır; tekrar sayısı önceden bilinmeyebilir.
while (koşul) { … }
Koşul sona yazılır; gövde en az bir kez çalışır.
do { … } while (koşul);
- Döngüler bir veri kümesinin sırayla işlenmesi ve işlem tekrarları için kullanışlıdır; özellikle diziler ve listelerle çalışırken önemlidir.
- Aynı satırı 100 kez yazmak yerine tek bir döngü: kod daha kısa, düzenli ve okunabilir olur.
Döngüler
for Döngüsü
- Başlık, döngünün başlangıç, koşul ve güncelleme (artırma) adımlarını tek satırda belirler; aralarında
;vardır. - Her döngü dönüşünden (tur, iteration) önce koşul kontrol edilir; güncelleme adımı döngü değişkenini değiştirir.
- Çalışma sırası: 1 → 2 → 4 → 3 → 2 → 4 → 3 → … → 2 yanlış → döngüden çık.
i= 0, 1, 2, 3, 4 için gövde 5 kez çalışır;i5 olunca koşul yanlış olur.iyalnızca döngünün içinde tanımlıdır.
Döngüler
Döngülerin İşleyişi
- Döngü başlangıç adımıyla başlar.
- Koşul kontrol edilir.
- Koşul sağlanıyorsa döngü içindeki işlemler yapılır.
- Güncelleme (artırma) adımı uygulanır (
fordöngüsü için). - Koşul hâlâ sağlanıyorsa tekrar döngü içine girilir.
- Koşul sağlanmazsa döngüden çıkılır ve sonraki deyimle devam edilir.
- Koşul ilk kontrolde yanlışsa gövde hiç çalışmaz.
1. Başlangıç: döngü değişkeni ilk değerini alır (bir kez).
2. Koşul kontrol edilir.
3. Koşul doğruysa gövde çalışır.
4. Güncelleme: döngü değişkeni değişir.
5. Koşula geri dönülür; doğru oldukça 3–4–5 tekrarlanır.
6. Koşul yanlış olunca döngüden çıkılır.
Döngüler · Adım adım kod izleme
Sayı Toplama (for)
toplam 0 ile başlar (toplama işleminin etkisiz elemanı).
Başlangıç: sayac = 1 (bir kez).
Koşul: 1 <= 10 → true.
1. tur: toplam = 0 + 1 = 1.
sayac++ → 2, koşul: 2 <= 10 → true.
2. tur: toplam = 1 + 2 = 3.
sayac++ → 3, koşul: 3 <= 10 → true.
3. tur: toplam = 3 + 3 = 6. Güncelleme ve koşul her turda aynı biçimde tekrarlanır.
4. tur: toplam = 6 + 4 = 10.
5. tur: toplam = 10 + 5 = 15.
6. tur: toplam = 15 + 6 = 21.
7. tur: toplam = 21 + 7 = 28.
8. tur: toplam = 28 + 8 = 36.
9. tur: toplam = 36 + 9 = 45.
10. tur: toplam = 45 + 10 = 55.
sayac++ → 11, koşul: 11 <= 10 → false. Döngü biter; gövde tam 10 kez çalıştı.
Döngüden sonra toplam yazılır. sayac artık tanımlı değil: yalnızca döngünün içinde yaşar.
int toplam = 0; for (int sayac = 1; sayac <= 10; sayac++) { toplam += sayac; } System.out.println("Toplam: " + toplam);
Döngüler
Aralık Toplama
import java.util.Scanner; public class AralikToplama { public static void main(String[] args) { Scanner klavye = new Scanner(System.in); System.out.print("Başlangıç değeri (a): "); int a = klavye.nextInt(); System.out.print("Bitiş değeri (b): "); int b = klavye.nextInt(); int toplam = 0; for (int i = a; i <= b; i++) { toplam += i; } System.out.println("Sayıların toplamı: " + toplam); } }
Girdiler: 3 ve 7
Başlangıç değeri (a): 3 Bitiş değeri (b): 7 Sayıların toplamı: 25
Döngü değişkeni i sabit bir sayıdan değil, kullanıcının girdiği a'dan başlar: 3 + 4 + 5 + 6 + 7 = 25.
Girdiler: 7 ve 3
Başlangıç değeri (a): 7 Bitiş değeri (b): 3 Sayıların toplamı: 0
İlk kontrolde 7 <= 3 yanlıştır: gövde hiç çalışmaz, toplam 0 kalır. Çözüm: a > b ise önce ikisi yer değiştirilir (if ile).
Döngüler
while Döngüsü
int i = 0; while (i < 5) { // Döngü içinde yapılacak işlemler i++; }
- Yalnızca bir koşulu kontrol eder; başlangıç ve güncelleme döngünün dışında/içinde ayrıca yazılır.
- Koşul sağlandığı sürece çalışır; koşul gövdeden önce sınanır.
- Tekrar sayısı önceden belli değilse doğal seçimdir (ör. “kullanıcı 0 girene kadar”).
- Sonsuz döngülere dikkat!
i++unutulursaihep 0 kalır, koşul hep doğrudur ve program hiç bitmez.
Döngüler
for ve while Karşılaştırması
for
int toplam = 0; for (int sayac = 1; sayac <= 10; sayac++) { toplam += sayac; } System.out.println("Toplam: " + toplam);
while
int toplam = 0; int sayac = 1; while (sayac <= 10) { toplam += sayac; sayac++; } System.out.println("Toplam: " + toplam);
Toplam: 55
Aynı üç parça iki döngüde de var: başlangıç sayac = 1, koşul sayac <= 10, güncelleme sayac++. for bunları tek satırda toplar; while'da dağınıktır ve güncelleme unutulabilir. Her ikisi de 55 yazar.
Döngüler · Adım adım kod izleme
Faktöriyel Hesaplama (while)
Hedef: 5! = 1 × 2 × 3 × 4 × 5. Çarpımın başlangıç değeri 1'dir (0 olsaydı sonuç hep 0 olurdu).
1 <= 5 → true. faktoriyel *= sayac: 1 × 1 = 1.
sayac++ → 2. Koşula geri dönülür.
2 <= 5 → true. faktoriyel *= sayac: 1 × 2 = 2.
3 <= 5 → true. faktoriyel *= sayac: 2 × 3 = 6.
4 <= 5 → true. faktoriyel *= sayac: 6 × 4 = 24.
5 <= 5 → true. faktoriyel *= sayac: 24 × 5 = 120.
sayac++ → 6. Koşula geri dönülür.
Koşul yanlış: döngüden çıkılır.
Sonuç yazılır. int 12!'ye kadar yeterlidir; 13! taşar, long gerekir.
int n = 5; int faktoriyel = 1; int sayac = 1; while (sayac <= n) { faktoriyel *= sayac; sayac++; } System.out.println(n + " faktöriyeli: " + faktoriyel);
Döngüler
Üs Alma (for)
import java.util.Scanner; public class UsAlma { public static void main(String[] args) { Scanner tarayici = new Scanner(System.in); System.out.print("Taban ve üs girin: "); int taban = tarayici.nextInt(); int us = tarayici.nextInt(); long sonuc = 1; for (int i = 1; i <= us; i++) { sonuc = sonuc * taban; } System.out.println("Sonuç: " + sonuc); System.out.println("Math.pow: " + Math.pow(taban, us)); tarayici.close(); } }
Taban ve üs girin: 3 4 Sonuç: 81 Math.pow: 81.0
Java'nın hazır Math.pow(taban, us) metodu aynı işi yapar ama sonucu double döndürür (81.0). Kendi döngümüz algoritmanın nasıl çalıştığını gösterir; gerçek programlarda hazır metotlar tercih edilir.
Döngüler
do-while Döngüsü
int i = 0; do { // Döngü içinde yapılacak işlemler i++; } while (i < 5);
- Önce işlem yapar, ardından koşulu kontrol eder.
- Koşul sağlandığı sürece tekrar eder.
- Gövde koşuldan bağımsız olarak en az bir kez çalışır.
while (koşul)'dan sonra noktalı virgül zorunludur.- Tipik kullanım: kullanıcıdan geçerli bir değer alınana kadar tekrar sormak, menüler.
Döngüler
do-while: Girdi Doğrulama
import java.util.Scanner; public class DoWhileGirdi { public static void main(String[] args) { Scanner klavye = new Scanner(System.in); int sayi; do { System.out.print("1-10 arası bir sayı girin: "); sayi = klavye.nextInt(); } while (sayi < 1 || sayi > 10); System.out.println("Kabul edilen sayı: " + sayi); } }
Girdiler: 15, 0, 7
1-10 arası bir sayı girin: 15 1-10 arası bir sayı girin: 0 1-10 arası bir sayı girin: 7 Kabul edilen sayı: 7
- Soru en az bir kez sorulmalıdır:
do-whiletam bu iş içindir. - 15 ve 0 aralık dışında: koşul
sayi < 1 || sayi > 10true → tekrar sor. - 7 geçerli: koşul false → döngüden çık.
sayidöngüden önce tanımlanır; çünkü koşulda ve döngüden sonra da kullanılır.
Döngüler · Adım adım kod izleme
Girdi Doğrulama: Kodun Adım Adım İzlenmesi
Kullanıcı sırayla 12, −3, 4 yazacak. sayi döngüden önce bildirilir; koşulda ve döngüden sonra da kullanılır.
Soru koşula bakılmadan sorulur. nextInt() ilk girdiyi okur: sayi = 12.
12 < 1 || 12 > 10: sağ taraf true → koşul true, soru yeniden sorulur.
İkinci girdi okunur: sayi = -3.
-3 < 1 true; || sağ tarafa bakmaz → koşul true, tekrar.
Üçüncü girdi: sayi = 4.
4 < 1 false, 4 > 10 false → koşul false: döngüden çıkılır.
Geçerli sayı kabul edilir. Soru toplam 3 kez soruldu; geçerli bir sayı gelene kadar döngü sürer.
Scanner klavye = new Scanner(System.in); int sayi; do { System.out.print("1-10 arası bir sayı girin: "); sayi = klavye.nextInt(); } while (sayi < 1 || sayi > 10); System.out.println("Kabul edilen sayı: " + sayi);
Döngüler · Adım adım kod izleme
while ve do-while Farkı
i = 10.
while koşulu önce sınar: false. Gövde (satır 3–4) hiç çalışmaz.
j = 10.
do bloğuna koşul sınanmadan girilir.
Gövde bir kez çalışır.
j++ → 11.
Koşul sonra sınanır: false → çıkılır.
Aynı koşul, farklı sonuç: while 0 kez, do-while 1 kez çalıştı.
int i = 10; while (i < 5) { System.out.println("while: " + i); i++; } int j = 10; do { System.out.println("do-while: " + j); j++; } while (j < 5); System.out.println("i = " + i + ", j = " + j);
Döngüler
Döngü Türlerinin Karşılaştırılması
for | while | do-while | |
|---|---|---|---|
| Koşul nerede sınanır? | Her turdan önce | Her turdan önce | Her turdan sonra |
| En az kaç tur? | 0 | 0 | 1 |
| Başlangıç / güncelleme | Başlıkta, tek satırda | Döngü dışında / gövdede | Döngü dışında / gövdede |
| Ne zaman? | Tekrar sayısı belli: “1'den n'e”, “dizinin her öğesi” | Bir koşul değişene kadar: “sayı 0 olana kadar” | İşlem en az bir kez yapılmalı: girdi doğrulama, menü |
| Söz dizimi | for (bas; koşul; günc) { } | while (koşul) { } | do { } while (koşul); |
Üç döngü birbirine dönüştürülebilir; seçim okunabilirliğe göre yapılır.
Döngüler
for Döngüsü: Deneme Alanı
Kutular, gövdenin çalıştığı her turdaki i değeridir. Örnek ayarlar: başlangıç 10, koşul <=, bitiş 1 (hiç dönmez); güncelleme i-- ile <= (sonsuz döngü); başlangıç 1, != ve i += 2 ile bitiş 9 (durur) ve 10 (hiç eşit olmaz: sonsuz). 200 turdan sonra simülasyon durdurulur.
İç İçe Döngüler
İç İçe Döngüler
- İç içe döngü (nested loop): bir döngünün gövdesinde başka bir döngü kullanmaktır.
- Daha karmaşık işlemler için kullanılır: matris ve çok boyutlu diziler, tablolar, desenler.
- Benzetme: saat. Akrep (dış döngü) bir ilerlediğinde yelkovan (iç döngü) tam bir tur atar.
- Toplam tur sayısı çarpımdır: dış 3 tur × iç 2 tur = 6 kez gövde.
- İç içe döngülerin sayısı ve koşulları kodun karmaşıklığını etkiler. Fazla iç içe döngüler karmaşık ve yavaş kodlara yol açabilir: üç döngü × 1000 tur = 1 milyar işlem!
for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 2; j++) { // İç içe döngü gövdesi } }
İç İçe Döngüler · Adım adım kod izleme
İç İçe Döngülerin İşleyişi
Dış döngü başlar: i = 1, 1 <= 3 → true.
İç döngü başlar: j = 1. Gövde: i = 1, j = 1 yazılır.
Gövde: i = 1, j = 2 yazılır.
j = 3 → 3 <= 2 false: iç döngü tamamlandı. Dışa dönülür: i++ → 2, 2 <= 3 → true; iç döngü baştan başlayacak.
İç döngü başlar: j = 1. Gövde: i = 2, j = 1 yazılır.
Gövde: i = 2, j = 2 yazılır.
j = 3 → 3 <= 2 false: iç döngü tamamlandı. Dışa dönülür: i++ → 3, 3 <= 3 → true; iç döngü baştan başlayacak.
İç döngü başlar: j = 1. Gövde: i = 3, j = 1 yazılır.
Gövde: i = 3, j = 2 yazılır.
j = 3 → 3 <= 2 false: iç döngü tamamlandı. i++ → 4, 4 <= 3 false: dış döngü de biter. Gövde 3 × 2 = 6 kez çalıştı.
for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 2; j++) { System.out.println("i = " + i + ", j = " + j); } }
İç İçe Döngüler · Adım adım kod izleme
Örnek: Yıldız Deseni
İç döngünün sınırı dış döngünün değişkenine bağlıdır (j <= i): her satırda bir yıldız fazla yazılır.
1. satır: iç döngü j = 1'den i = 1'e kadar döner. print("* "): aynı satırda kalınır.
İç döngü bitti (j = 2 > 1). println() alt satıra geçer.
2. satır: iç döngü j = 1'den i = 2'ye kadar döner. print("* "): aynı satırda kalınır.
print("* "): aynı satırda kalınır.
İç döngü bitti (j = 3 > 2). println() alt satıra geçer.
3. satır: iç döngü j = 1'den i = 3'e kadar döner. print("* "): aynı satırda kalınır.
print("* "): aynı satırda kalınır.
print("* "): aynı satırda kalınır.
İç döngü bitti (j = 4 > 3). println() alt satıra geçer.
4. satır: iç döngü j = 1'den i = 4'e kadar döner. print("* "): aynı satırda kalınır.
print("* "): aynı satırda kalınır.
print("* "): aynı satırda kalınır.
print("* "): aynı satırda kalınır.
İç döngü bitti (j = 5 > 4). println() alt satıra geçer. Toplam 1 + 2 + 3 + 4 = 10 yıldız.
for (int i = 1; i <= 4; i++) { for (int j = 1; j <= i; j++) { System.out.print("* "); } System.out.println(); }
İç İçe Döngüler
Basamak Değeri: Çıktı Ne Olur?
for (int onlar = 0; onlar <= 4; onlar++) { for (int birler = 1; birler <= 9; birler++) { int sayi = onlar * 10 + birler; System.out.println("Onlar basamağı: " + onlar + ", Birler basamağı: " + birler + " --> " + sayi); } }
Soru: Program kaç satır yazar? İlk ve son satır nedir? Hangi sayılar hiç yazılmaz?
Cevap
Onlar basamağı: 0, Birler basamağı: 1 --> 1 Onlar basamağı: 0, Birler basamağı: 2 --> 2 Onlar basamağı: 0, Birler basamağı: 3 --> 3 … Onlar basamağı: 4, Birler basamağı: 8 --> 48 Onlar basamağı: 4, Birler basamağı: 9 --> 49
Dış döngü 5 tur (onlar = 0…4), iç döngü 9 tur (birler = 1…9): 5 × 9 = 45 satır. sayi = 1…49 olur; birler 0'dan başlamadığı için 10, 20, 30, 40 yazılmaz. Uzun bir dizgi iki satıra + ile bölünür; tırnak içinde satır atlanırsa unclosed string literal hatası alınır.
İç İçe Döngüler
Çarpım Tablosu
for (int i = 1; i <= 10; i++) { for (int j = 1; j <= 10; j++) { int carpim = i * j; System.out.print(i + "x" + j + "=" + carpim + "\t"); } System.out.println(); // Yeni satır }
- Dış döngü satırları (
i), iç döngü sütunları (j) gezer: 10 × 10 = 100 çarpım. printsatır atlamaz;"\t"(sekme, tab) sütunları hizalar.- Satır bitince
println()ile alt satıra geçilir. Bu satır iç döngünün dışında ama dış döngünün içindedir.
Çıktıdan kesit (sekmeler boşlukla gösterildi)
1x1=1 1x2=2 1x3=3 1x4=4 1x5=5 1x6=6 … 2x1=2 2x2=4 2x3=6 2x4=8 2x5=10 2x6=12 … 3x1=3 3x2=6 3x3=9 3x4=12 3x5=15 3x6=18 … … 10x1=10 10x2=20 10x3=30 10x4=40 10x5=50 …
break ve continue · Adım adım kod izleme
Döngülerde break
break, döngüyü sonlandırmak için kullanılır: koşul sağlandığında döngüden çıkılır, döngü sona erer.
i = 1: 1 == 5 false, break atlanır; adım yazılır.
i = 2: 2 == 5 false → yazılır.
i = 3: 3 == 5 false → yazılır.
i = 4: 4 == 5 false → yazılır.
i = 5: koşul true → break. Döngü hemen sona erer; 5 yazılmaz, 6–10 hiç denenmez.
Döngü dışındaki işlemler devam eder. i artık tanımlı değil.
for (int i = 1; i <= 10; i++) { if (i == 5) { break; } System.out.println("Döngü adımı: " + i); } System.out.println("Döngüden çıkıldı.");
break ve continue
Asal Sayı: Bayrak ve break
import java.util.Scanner; public class AsalSayi { public static void main(String[] args) { Scanner tarayici = new Scanner(System.in); System.out.print("Bir sayı girin: "); int sayi = tarayici.nextInt(); boolean asalMi = true; // bayrak (flag) if (sayi < 2) asalMi = false; // 0 ve 1 asal değildir for (int bolen = 2; bolen <= sayi / 2; bolen++) { if (sayi % bolen == 0) { // tam bölünüyor asalMi = false; break; // döngüyü kır } } if (asalMi) { System.out.println(sayi + " bir asal sayıdır."); } else { System.out.println(sayi + " bir asal sayı değildir."); } tarayici.close(); } }
Bir sayı girin: 21 21 bir asal sayı değildir. Bir sayı girin: 97 97 bir asal sayıdır.
Daha hızlısı: bir sayının böleni varsa biri √sayı'dan küçük veya eşittir. Koşul bolen * bolen <= sayi olunca 97 için 47 yerine yalnızca 8 bölen denenir.
break ve continue · Adım adım kod izleme
Döngülerde continue
continue, o anki adımın kalanını atlar ve bir sonraki adıma geçer.
i = 1 tek → koşul false, sayı yazılır.
i = 2 çift → continue: satır 5 atlanır, doğrudan i++'ya geçilir.
i = 3 tek → koşul false, sayı yazılır.
i = 4 çift → continue: satır 5 atlanır, doğrudan i++'ya geçilir.
i = 5 tek → koşul false, sayı yazılır.
i = 6 çift → continue: satır 5 atlanır, doğrudan i++'ya geçilir.
i = 7 tek → koşul false, sayı yazılır.
i = 8 çift → continue: satır 5 atlanır, doğrudan i++'ya geçilir.
i = 9 tek → koşul false, sayı yazılır.
i = 10 çift → continue: satır 5 atlanır, doğrudan i++'ya geçilir.
11 <= 10 false: döngü normal biçimde biter. continue döngüyü bitirmez, yalnızca o turu atlar.
for (int i = 1; i <= 10; i++) { if (i % 2 == 0) { continue; } System.out.println("Tek sayı: " + i); }
break ve continue
break ve continue Karşılaştırması
Döngü tamamen sona erer; döngüden sonraki deyime geçilir.
Turun geri kalanı atlanır; güncelleme ve koşulla döngü sürer.
İkisi de genellikle bir if içinde, while ve do-while'da da kullanılır; while'da continue güncellemeyi atlarsa sonsuz döngü oluşabilir.
break ve continue
İç İçe Döngülerde break
break yalnızca içteki döngüyü bitirir
for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { if (j == 2) { break; } System.out.println(i + " " + j); } }
1 1 2 1 3 1
Etiketli break: dış döngüden çıkış
dis: for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { if (i * j == 4) { break dis; } System.out.println(i + " x " + j); } }
1 x 1 1 x 2 1 x 3 2 x 1
Soldaki örnekte her i için yalnızca j = 1 yazılır, dış döngü sürer. Sağda dis: etiketi dış döngüyü adlandırır; i * j == 4 olunca (i = 2, j = 2) break dis; iki döngüden birden çıkar. Etiketler seyrek kullanılmalıdır.
break ve continue · Adım adım kod izleme
Etiketli break: Kodun Adım Adım İzlenmesi
dis: etiketi dış döngüyü adlandırır. i = 1, j = 1: 1 × 1 = 1 ≠ 4, satır yazdırılır.
j = 2: 1 × 2 = 2, yazdırılır.
j = 3: 1 × 3 = 3, yazdırılır. İç döngü biter; dış döngü i = 2'ye geçer.
i = 2, j = 1: 2 × 1 = 2, yazdırılır.
i = 2, j = 2: 2 × 2 = 4 → koşul doğru.
break dis; yalnızca iç döngüden değil, etiketli dış döngüden de çıkar. Kalan hücreler hiç ziyaret edilmez.
Akış iki döngünün de sonrasına atlar: bitti yazılır. Etiketsiz break olsaydı i = 3 turu da çalışırdı.
dis: for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { if (i * j == 4) { break dis; } System.out.println(i + " x " + j); } } System.out.println("bitti");
Özet
Özet
| Yapı | Ne yapar? | Söz dizimi |
|---|---|---|
| Sıralı | Deyimler yukarıdan aşağıya birer kez çalışır | — |
| if / else | Koşul doğruysa bir blok, değilse diğeri | if (k) { } else { } |
| else if | İlk doğru koşulun bloğu çalışır | if (k1) { } else if (k2) { } else { } |
| switch | Bir değeri sabit case'lerle karşılaştırır; break ile çıkılır | switch (x) { case 1: … break; default: … } |
| for | Başlangıç, koşul, güncelleme tek satırda; sayılı tekrar | for (int i = 0; i < n; i++) { } |
| while | Koşul doğru oldukça; 0 veya daha çok tur | while (k) { } |
| do-while | Önce gövde, sonra koşul; en az 1 tur | do { } while (k); |
| break / continue | Döngüyü bitirir / o turu atlar | break; · continue; |
Özet
Sık Yapılan Hatalar: Kararlar
if (x = 5) → error: incompatible types: int cannot be converted to boolean. Doğrusu x == 5.if (x > 5); { … } derlenir ama ; boş deyimdir: blok her zaman çalışır.if (k) a(); b(); else c(); → error: 'else' without 'if'. Birden çok deyim için { } şarttır.switch'te break yoksa alttaki case'ler de çalışır (aşağı düşme). Derleyici uyarmaz.case'lerde atanıyorsa: error: variable mevsim might not have been initialized. Çözüm: default eklemek.nextDouble() için -7.5 → InputMismatchException. -7,5 yazılmalı.Özet
Sık Yapılan Hatalar: Döngüler
while'da güncellemeyi (i++) unutmak ya da yanlış yönde güncellemek (i-- ile i <= 10). Derleyici yakalamaz; program durmaz.for (int i = 0; i < 3; i++); veya while (i < 5); gövdesi boş bir döngüdür; alttaki blok döngüye ait değildir.i < 10 yazmak 10'u atlar; i = 0 ile i <= 10 11 tur döner. İlk ve son tur ayrıca denetlenmelidir.for (int i …) { } sonrası println(i) → error: cannot find symbol. Gerekirse i döngüden önce tanımlanır.break; System.out.println(i); → error: unreachable statement. break'ten sonraki satıra asla ulaşılmaz.faktoriyel = 0 ile sonuç hep 0 olur. Değişkeni döngünün içinde sıfırlamak da yanlıştır.Özet
Örnek Problemler (1): Ne Yazar?
Problem 1
int x = 7; if (x > 5) if (x > 10) System.out.println("A"); else System.out.println("B");
Problem 2
int s = 0; for (int i = 1; i <= 10; i += 3) { s += i; } System.out.println(s);
Problem 3
int k = 2; int puan = 0; switch (k) { case 1: puan += 10; case 2: puan += 20; case 3: puan += 30; break; case 4: puan += 40; } System.out.println(puan);
Cevaplar
- B.
elseen yakınif'e (içtekine) bağlanır: 7 > 5 doğru, 7 > 10 yanlış → B. - 22.
i= 1, 4, 7, 10; toplam 22. - 50.
case 2'den girilir (+20),breakyok:case 3'e düşülür (+30). Toplam 50.
Özet
Örnek Problemler (2)
1'den 100'e kadar olan sayılardan 3'e veya 5'e tam bölünenlerin toplamını bulan kodu yazın.
Bir tam sayının (ör. 2024) kaç basamaklı olduğunu while döngüsüyle bulun (sayi /= 10 son basamağı atar).
Cevaplar
int toplam = 0; for (int i = 1; i <= 100; i++) { if (i % 3 == 0 || i % 5 == 0) { toplam += i; } } System.out.println(toplam);
Çıktı: 2418. Her sayı bir kez denenir; || sayesinde 15 gibi ortak katlar iki kez eklenmez.
int sayi = 2024, basamak = 0; while (sayi > 0) { basamak++; sayi /= 10; } System.out.println(basamak);
Çıktı: 4. Her turda son basamak atılır: 2024 → 202 → 20 → 2 → 0.
Özet
Alıştırmalar (1)
int n = 1; while (n < 100) { n *= 3; } System.out.println(n);
int k = 5; do { k -= 2; } while (k > 0); System.out.println(k);
int adet = 0; for (int i = 1; i <= 4; i++) { for (int j = i; j <= 4; j++) { adet++; } } System.out.println(adet);
Cevaplar (önce kâğıt üzerinde çözün, sonra çalıştırıp doğrulayın)
- 243.
n: 1 → 3 → 9 → 27 → 81 → 243; 243 < 100 yanlış olunca durur. - -1.
k: 5 → 3 → 1 → −1. Koşul sonda sınandığı için −1'e kadar iner. - 10. İç döngü
i= 1, 2, 3, 4 için 4, 3, 2, 1 kez döner: 4 + 3 + 2 + 1 = 10.
Özet
Alıştırmalar (2)
int t = 0; for (int i = 1; i <= 10; i++) { if (i % 3 == 0) { continue; } t += i; } System.out.println(t);
int i = 10; while (i >= 1) { System.out.print(i + " "); i -= 2; } System.out.println();
int a = 17, b = 42; int enBuyuk = (a > b) ? a : b; System.out.println(enBuyuk);
Cevaplar
- 37. 1–10 toplamı 55; atlanan 3 + 6 + 9 = 18; 55 − 18 = 37.
- 10 8 6 4 2.
i10'dan 2'şer azalır; 0 olunca 0 >= 1 yanlış.forile:for (int i = 10; i >= 1; i -= 2). - 42. 17 > 42 yanlış olduğu için ikinci değer seçilir. Aynı işi yapan
if-else'i de yazın.
Özet
Kaynaklar
- Oracle, The Java Tutorials: “Control Flow Statements” (if-then-else, switch, while, do-while, for, branching statements).
- J. Gosling ve diğ., The Java Language Specification, Java SE 21 Edition (Bölüm 14: Blocks, Statements, and Patterns).
- P. Deitel ve H. Deitel, Java: How to Program, 11. baskı, Pearson (Bölüm 4–5: Control Statements).
- A. B. Downey ve C. Mayfield, Think Java, 2. baskı, O'Reilly (Bölüm 5: Conditionals and Logic, Bölüm 6: Loops).
- K. Sierra ve B. Bates, Head First Java, 3. baskı, O'Reilly.
- C. S. Horstmann, Core Java, Volume I: Fundamentals, 12. baskı (3.8: Control Flow).