SEN1001 · 3. hafta · Control Statements: Part 1

Karar yapıları: if/else, mantıksal operatörler, switch

if, else if zinciri, iç içe if, &&, || ve ! ile kısa devre, switch ve fall-through. Vizede hem çıktı izleme hem de getSeason tipi metot yazma olarak gelir.

selection statementboolean expressionrelational operatorif...elsenested ifdangling elselogical operatorshort-circuit evaluationconditional operator (ternary)switchcasebreakfall-throughdefault

Program şimdiye kadar yukarıdan aşağı her satırı çalıştırdı. Karar yapıları (selection statements) bir koşula göre bazı satırları çalıştırıp bazılarını atlamayı sağlar. Vizede iki tip soru çıkar: koşulları takip edip neyin basıldığını bulmak ve “şu değere göre şunu döndür” diyen kısa metotlar yazmak (not harfi, ay adı, mevsim).

Altın kurallar:

  1. else if zincirinde ilk true olan dal çalışır, gerisine bakılmaz.
  2. Süslü parantez yoksa if tek bir ifadeyi kapsar. Girinti yanıltır.
  3. && ve || kısa devre yapar: sonuç belli olunca sağ taraf hiç çalışmaz.
  4. switch’te break yoksa aşağı düşer (fall-through), default dahil.
  5. = atama, == karşılaştırma. if içinde = derlenmez.

Karşılaştırma ve boolean ifadeler

Karşılaştırma operatörleri (relational operators) iki değeri karşılaştırır ve boolean (true/false) üretir.

OperatörAnlamıa = 7, b = 3 iken
==eşit mia == b → false
!=eşit değil mia != b → true
> <büyük, küçüka > b → true
>= <=büyük eşit, küçük eşita <= 7 → true
int a = 7, b = 3;
System.out.println((a > b) + " " + (a == b) + " " + (a != b) + " " + (a <= 7));
boolean big = a > 5;
System.out.println(big);
true false true true
true

boolean bir değişkende saklanabilir ve doğrudan yazdırılabilir.

TUZAK · if içinde tek eşittir. if (x = 5) derlenmez: incompatible types: int cannot be converted to boolean. if bir boolean ister, x = 5 ise atamadır ve int üretir.

if ve if-else

int temp = 12;
if (temp > 25) {
    System.out.println("Sicak");
} else {
    System.out.println("Serin");
}
System.out.println("Bitti");
Serin
Bitti

Koşul true ise if bloğu, false ise else bloğu çalışır. İkisinden tam olarak biri çalışır. Bloktan sonraki satırlar (Bitti) her durumda çalışır.

else if zinciri

Birden çok aralık varsa else if kullanılır. Java koşulları yukarıdan aşağı dener, ilk true olanı çalıştırır, zincirin geri kalanını atlar.

public static String letter(int score) {
    if (score >= 90) return "A";
    else if (score >= 80) return "B";
    else if (score >= 70) return "C";
    else if (score >= 60) return "D";
    else return "F";
}

letter(85), letter(90), letter(59) çağrıları:

B A F

85 için score >= 80 dalına gelindiğinde score < 90 olduğunu zaten biliyoruz; o yüzden score >= 80 && score < 90 yazmaya gerek yok.

TUZAK · yanlış sıra. Zinciri if (score >= 60) return "D"; else if (score >= 70) ... diye küçükten başlatırsan 95 alan öğrenci de D alır, çünkü ilk true koşul >= 60. Doğrulamada letterWrongOrder(95) gerçekten D döndürdü. Alt sınırla çalışıyorsan büyükten küçüğe sırala.

Zincir ile ayrı if’ler farklıdır:

int s = 95;
if (s >= 90) System.out.print("A ");
if (s >= 80) System.out.print("B ");
if (s >= 70) System.out.print("C ");
A B C 

Üç ayrı if, üçü de bağımsız kontrol edilir ve üçü de true.

Süslü parantez ve noktalı virgül tuzakları

int x = -2, cnt = 0, other = 0;
if (x > 0)
    cnt++;
    other++;          // girinti yanıltıcı: bu satır if'in DIŞINDA
System.out.println(cnt + " " + other);
int y = -5;
if (y > 0);           // sondaki ; boş bir ifade, if'in gövdesi bu
{
    System.out.println("pozitif?");
}
0 1
pozitif?

İkinci örnekte if’in gövdesi o boş noktalı virgül. Alttaki süslü parantez bloğu if ile ilgisiz, her zaman çalışır. y negatif olduğu halde pozitif? basıldı.

Asılı else (dangling else)

int m = 5, n = 20;
if (m > 10)
    if (n > 10)
        System.out.println("ikisi de buyuk");
else
    System.out.println("else kime ait?");
System.out.println("son");
son

else her zaman en yakın, eşleşmemiş if’e aittir: burada içteki if (n > 10). Girinti onu dıştaki if’e aitmiş gibi gösteriyor ama Java girintiye bakmaz. Dıştaki koşul false olduğu için içerideki hiçbir şey çalışmadı. Kaçınmanın yolu: her zaman { } kullan.

Mantıksal operatörler

aba && b (VE)a || b (VEYA)!a (DEĞİL)
truetruetruetruefalse
truefalsefalsetruefalse
falsetruefalsetruetrue
falsefalsefalsefalsetrue

Öncelik: önce !, sonra &&, en son ||. Karşılaştırmalar bunlardan önce yapılır, o yüzden age >= 18 && student parantezsiz çalışır.

int age = 20;
boolean student = true;
System.out.println(age >= 18 && student);
System.out.println(age < 18 || !student);
System.out.println(!(age == 20));
System.out.println(true || false && false);     // && önce: true || false
System.out.println((true || false) && false);
true
false
false
true
false

Kısa devre (short-circuit evaluation)

  • &&: sol taraf false ise sonuç zaten false, sağa bakılmaz.
  • ||: sol taraf true ise sonuç zaten true, sağa bakılmaz.

Bu bir koruma olarak kullanılır:

int d = 0;
if (d != 0 && 10 / d > 1) System.out.println("buyuk");
else System.out.println("guvenli");
guvenli

d != 0 false olduğu için 10 / d hiç hesaplanmadı, program çökmedi. Sırayı ters yazsaydın (10 / d > 1 && d != 0) ArithmeticException alırdın.

Sağ tarafta ++z gibi bir yan etki (side effect) varsa, kısa devre o yan etkinin hiç olmamasına neden olur. Vizede tam bu kurulur.

Koşul operatörü (ternary)

koşul ? değer1 : değer2 kısa bir if-else’tir; bir değer üretir.

int t1 = 8;
String parity = (t1 % 2 == 0) ? "even" : "odd";
System.out.println(parity);
even

switch

Bir değişkenin belirli değerlerine göre dallanmak için switch kullanılır. int, char, String (ve byte, short) ile çalışır; double ve boolean ile yazılmaz.

int day = 3;
switch (day) {
    case 1: System.out.println("Mon"); break;
    case 2: System.out.println("Tue"); break;
    case 3: System.out.println("Wed"); break;
    default: System.out.println("Other");
}
Wed

Kural: Java eşleşen case’e atlar, oradan aşağı doğru çalışmaya başlar ve break görene kadar devam eder. Hiçbir case eşleşmezse default çalışır (else gibi). default zorunlu değil.

Fall-through

int lvl = 2;
switch (lvl) {
    case 1: System.out.println("one");
    case 2: System.out.println("two");
    case 3: System.out.println("three");
    default: System.out.println("default");
}
two
three
default

case 2’den girildi, hiç break olmadığı için altındaki her şey, default da dahil çalıştı. case 1 yukarıda kaldığı için çalışmadı: switch eşleşen case’in üstüne asla çıkmaz.

Fall-through bilerek de kullanılır: birden çok değer aynı işi yapacaksa case’leri alt alta yazarsın.

char g = 'B';
switch (g) {
    case 'A': case 'B': System.out.println("Iyi"); break;
    case 'C': System.out.println("Orta"); break;
    default: System.out.println("Zayif");
}
String cmd = "stop";
switch (cmd) {
    case "go": System.out.println("Gidiyor"); break;
    case "stop": System.out.println("Duruyor"); break;
    default: System.out.println("?");
}
Iyi
Duruyor

Metot içinde switch: return ile

Metot bir değer döndürüyorsa her case’te return yazarsın. return metodu anında bitirdiği için break gerekmez. Yukarıdaki soru bankasındaki daysInMonth bu kalıbın örneği; mevsim, gün adı ve not harfi soruları da aynı iskeletle çözülür.

Sık yapılan hatalar

Yanlış düşünceDoğrusu
if (x = 5)if (x == 5); tek = derlenmez
else if’te true olan bütün dallar çalışırSadece ilk true dal
Girinti if’in kapsamını belirler{ } yoksa sadece bir ifade
if (x > 0); zararsızBoş gövde; alttaki blok her zaman çalışır
else dıştaki if’e aittirEn yakın eşleşmemiş if’e
a || b && c soldan sağa&& önce: a || (b && c)
Koşulun sağındaki ++z her zaman çalışırKısa devrede hiç çalışmaz
switch eşleşen case’i çalıştırıp çıkarbreak yoksa aşağı düşer
switch double ile çalışırÇalışmaz; int, char, String kullan
String’i == ile karşılaştırequals; switch String’de bunu kendisi yapar

Kendini test et

Sınavdaki gibi İngilizce sorular. Önce kâğıt kalemle çöz, sonra cevabı aç.

Soru 1kolay

What is printed?

int x = 15;
if (x > 10) System.out.println("A");
else if (x > 5) System.out.println("B");
else System.out.println("C");
Cevabı göster
A

else if zincirinde ilk true olan dal çalışır, gerisine bakılmaz. 15 > 10 true → A. 15 > 5 de true ama o dala hiç gelinmez.

Soru 2orta

What is printed?

int x = 15;
if (x > 10) System.out.print("A");
if (x > 5) System.out.print("B");
else System.out.print("C");
System.out.println();
Cevabı göster
AB

Bu sefer iki ayrı if var. Birinci if A basar. İkinci if bağımsız olarak kontrol edilir: 15 > 5 true → B. else sadece ikinci if'e aittir, çalışmaz.

Soru 3kolay

What is printed?

int a = 4, b = 9;
System.out.println(a > 3 && b < 5);
System.out.println(a > 3 || b < 5);
System.out.println(!(a > 3) || b % 3 == 0);
Cevabı göster
false
true
true

1) true && false → false. 2) true || false → true. 3) !(true) = false; 9 % 3 == 0 true; false || true → true.

Soru 4orta

What is printed?

int x = 0;
if (x > 0)
    System.out.println("pos");
    System.out.println("checked");
Cevabı göster
checked

Süslü parantez yoksa if sadece hemen altındaki tek ifadeyi kapsar. Girinti (indentation) Java için anlamsızdır. checked satırı if'in dışında, her zaman çalışır.

Soru 5orta

What is printed when day is (a) 2, (b) 4, (c) 7?

switch (day) {
    case 1: System.out.println("Red");
    case 2: System.out.println("Green");
    case 3: System.out.println("Blue"); break;
    case 4: System.out.println("Black");
    default: System.out.println("White");
}
Cevabı göster
(a) Green, Blue · (b) Black, White · (c) White

(a) case 2'den gir, break yok → case 3'e düş (fall-through), Blue, break → çık. (b) case 4'ten gir, break yok → default'a düşer: Black, White. (c) eşleşen case yok → sadece default: White. Her kelime ayrı satırda basılır.

Soru 6zor

What is printed?

int q = 3, z = 0;
if (q > 5 && ++z > 0) System.out.println("in");
System.out.println(z);
if (q < 5 || ++z > 0) System.out.println("in2");
System.out.println(z);
Cevabı göster
0
in2
0

Kısa devre (short-circuit): && solu false ise sağa hiç bakmaz, ++z çalışmaz → z = 0. || solu true ise sağa bakmaz, yine ++z çalışmaz → z hâlâ 0. Koşul true olduğu için in2 basılır.

Soru 7zor

What is printed?

int a = 2, b = 8;
if (a > 5)
    if (b > 5)
        System.out.println("X");
else
    System.out.println("Y");
System.out.println("Z");
Cevabı göster
Z

Asılı else (dangling else): else, girintiye bakılmaksızın en yakın eşleşmemiş if'e, yani if (b > 5)'e aittir. Dış if (a > 5) false olduğu için içerideki her şey atlanır. Sadece Z basılır.

Soru 8orta

What is printed?

int n = 7;
String res = (n > 5) ? (n > 10 ? "big" : "medium") : "small";
System.out.println(res);
Cevabı göster
medium

Koşul operatörü (ternary) koşul ? a : b. 7 > 5 true → içteki ifadeye bak: 7 > 10 false → "medium".

Soru 9orta

What is printed?

String w = "B";
switch (w) {
    case "A": System.out.print("1 ");
    case "B": System.out.print("2 ");
    case "C": System.out.print("3 "); break;
    default: System.out.print("4 ");
}
Cevabı göster
2 3

switch String ile de çalışır (equals ile karşılaştırır). "B" eşleşir → 2 , break yok → 3 , break. default'a gelinmez.

Soru 10kolay

What is printed?

int score = 72;
if (score >= 90) System.out.println("A");
if (score >= 70) System.out.println("C");
else if (score >= 60) System.out.println("D");
else System.out.println("F");
Cevabı göster
C

İlk if bağımsız ve false. İkinci if ayrı bir zincir başlatır: 72 >= 70 true → C, zincirin geri kalanı atlanır.

Soru 11orta

Write a static method daysInMonth(int month) that uses a switch to return 28 for February, 30 for April, June, September and November, 31 for the other months, and -1 for an invalid month.

Cevabı göster
public static int daysInMonth(int month) { switch (month) { ... } }

Aynı sonucu veren case'leri alt alta yaz (bilinçli fall-through). return metodu bitirdiği için break gerekmez.public static int daysInMonth(int month) { switch (month) { case 2: return 28; case 4: case 6: case 9: case 11: return 30; case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31; default: return -1; }}Test: daysInMonth(4) → 30, daysInMonth(7) → 31, daysInMonth(2) → 28, daysInMonth(13) → -1.

Soru 12zor

Write a static method isLeapYear(int year): a year is a leap year if it is divisible by 4 but not by 100, or if it is divisible by 400. Use a single return statement.

Cevabı göster
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;

Kuralı kelimesi kelimesine mantıksal operatörlere çevir. && önceliği || 'den yüksek olsa da parantez yazmak okunurluğu artırır.public static boolean isLeapYear(int year) { return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;}Test: 2024 → true, 1900 → false (100'e bölünüyor, 400'e bölünmüyor), 2000 → true, 2026 → false.

Doğrulama: Tüm çıktılar JDK 26 ile çalıştırıldı (verify/SEN1001/W03.java). daysInMonth ve isLeapYear metotları birkaç girdiyle test edildi. if (x = 5) hatası verify/SEN1001/err/IfAssign.java javac ile derlenerek alındı.

Deftere not kartı

Karşılaştırma: == != < <= > >= sonuç boolean = atama, == karşılaştırma if (x = 5) → derlenmez (int cannot be converted to boolean) else if zinciri: İLK true dal çalışır, gerisi atlanır → sıra: büyükten küçüğe (>=90, >=80 ...) Ayrı if'ler: her biri bağımsız kontrol edilir { } yoksa if sadece TEK ifadeyi kapsar; girinti önemsiz if (x > 0); → noktalı virgül boş gövde, alttaki blok HER ZAMAN çalışır else en yakın eşleşmemiş if'e aittir (dangling else) && ikisi de true || biri yeter ! tersi öncelik: ! → && → || Kısa devre: false && ... sağa bakmaz true || ... sağa bakmaz x != 0 && 10 / x > 1 → sıfıra bölme korunur koşul ? a : b switch: int, char, String (double YOK). Eşleşen case'ten break'e kadar her şey çalışır break yoksa aşağı düşer (fall-through), default dahil. Hiç eşleşme yoksa default case 12: case 1: case 2: return "Winter"; (bilerek fall-through)