Bölüm 3: Fonksiyonlar

Bölüm 3: Fonksiyonlar · Çalışma Soruları
Parametre ve argümanreturn ve voidAşırı yüklemeÇağrı yığınıYapıcılarHazır metotlarKapsamTasarımLambda
Sercan KÜLCÜ

Çoktan Seçmeli · Fonksiyon Kavramı

Soru 1: Parametre ve Argüman

Bu çağrı için hangisi doğrudur?

static int kare(int x) {
    return x * x;
}
// main içinde:
int a = 3;
int b = kare(a + 1);

B: Tanımdaki x parametre, çağrıdaki ifade argümandır. Argüman önce hesaplanır (4), değeri yeni çerçevedeki x'e kopyalanır; metot 16 döndürür ve b'ye 16 atanır. a 3 olarak kalır.

Çoktan Seçmeli · Tanım ve Çağrı

Soru 2: Geçerli Metot Başlığı

Aşağıdakilerden hangisi geçerli bir metot başlığıdır?

C: Sıra: düzenleyiciler, dönüş tipi, ad, parametre listesi. Her parametrenin kendi tipi yazılır (int a, b olmaz). Dönüş tipi zorunludur; yoksa yalnızca sınıfla aynı adlı yapıcı olabilir. Dönüş tipi düzenleyiciden önce yazılamaz.

Çoktan Seçmeli · Tanım ve Çağrı

Soru 3: return Kuralları

Aşağıdaki metotlardan hangisi derlenir?

A: void metotta tek başına return; metottan erken çıkar. İkincide iki koşul her durumu kapsasa da derleyici koşulların değerini düşünmez; sonda return olmadığı için missing return statement verir. void metot değer döndüremez; int metot da değersiz return; ile bitemez.

Çoktan Seçmeli · Tanım ve Çağrı

Soru 4: Hangi yaz Çalışır?

Aşırı yüklenmiş üç metot var. Dört çağrı ne yazdırır?

static void yaz(int a) {
    System.out.print("I");
}
static void yaz(long a) {
    System.out.print("L");
}
static void yaz(double a) {
    System.out.print("D");
}
// main içinde:
yaz(5); yaz(5L);
yaz(5.0f); yaz('A');

D: Derleyici argümanın tipine bakar: 5 int → I; 5L long → L. 5.0f float'tır; float sürümü olmadığı için en yakın genişletme double → D. 'A' char'dır; char önce int'e genişler → I. Seçim derleme zamanında yapılır.

Adım Adım Çalıştırma · Tanım ve Çağrı

Soru 5: Değer ile Aktarım İzleme

Metot da main de sayi adlı bir değişken kullanıyor. Çağrı yığınını izleyin. Program ne yazdırır?

main'in yerel sayi'sı 5.

Yeni çerçeve: parametre sayi, main'deki değerin kopyası. Adları aynı ama iki ayrı değişken.

Yalnızca kopya 15 olur.

Çerçeve kapanır. Dönen 15 hiçbir değişkene atanmadığı için kaybolur.

main'deki sayi hiç değişmedi.

İkinci çağrıda da kopya 15 olur.

Bu kez dönen değer main'deki sayi'ya atanır.

Bir metodun sonucu, yalnızca return ile alınıp atanırsa çağırana ulaşır.

static int arttir(int sayi) {
    sayi += 10;
    return sayi;
}
// main içinde:
int sayi = 5;
arttir(sayi);
System.out.println(sayi);
sayi = arttir(sayi);
System.out.println(sayi);

Çıktı Sorusu · Tanım ve Çağrı

Soru 6: Öğrenci Numarasını Çözmek

Dokuz haneli numarada ilk iki hane kayıt yılı, sondan dördüncü hane bölüm kodu, son üç hane kayıt sırasıdır. Program ne yazdırır?

static int kayitYili(int no) {
    return no / 10000000 + 2000;
}
static int kayitSirasi(int no) {
    return no % 1000;
}
static String bolum(int no) {
    int kod = (no / 1000) % 10;
    if (kod == 7) return "Elektrik";
    if (kod == 6) return "Bilgisayar";
    return "Bilinmiyor";
}
// main içinde:
int no = 240706045;
System.out.println(kayitYili(no) + " "
        + kayitSirasi(no));
System.out.println(bolum(no) + " / "
        + bolum(no + 1000));
Cevabı göster
2024 45
Bilgisayar / Elektrik
  • 240706045 / 107 = 24 → 2024. 240706045 % 1000 = 45: sayı baştaki sıfırı (045) tutmaz.
  • 240706045 / 1000 = 240706, % 10 = 6 → Bilgisayar. no + 1000 = 240707045 → kod 7.
  • Her metot tek bir iş yapar ve sonucunu döndürür; yazdırma işi main'de kalır.

Adım Adım Çalıştırma · Fonksiyon İçinde Fonksiyon

Soru 7: Çağrı Yığını İzleme

Metotlar birbirini çağırıyor. Çerçevelerin açılıp kapanışını izleyin. Program ne yazdırır? Yığın en çok kaç çerçeve içerir?

main, fark(2, 3)'ü çağırır; 2 ve 3, a ve b'ye kopyalanır.

Çıkarmanın iki işleneni de gerekli; önce soldaki: kup(2).

n * kare(n) için kare(2) çağrılır.

En derin an: 4 çerçeve. kare(2) 4 döndürür.

kup(2) = 2 · 4 = 8 döner; çerçevesi kapanır.

Şimdi sağ işlenen: kare(3). Yeni çerçevenin kendi n'si 3, 9 döner.

8 − 9 = −1 döner.

Dönen −1 yazdırılır; yığında yalnızca main kaldı.

static int kare(int n) {
    return n * n;
}
static int kup(int n) {
    return n * kare(n);
}
static int fark(int a, int b) {
    return kup(a) - kare(b);
}
// main içinde:
System.out.println(fark(2, 3));

Çıktı Sorusu · Fonksiyon İçinde Fonksiyon

Soru 8: İç İçe Çağrılar

Bir metodun sonucu diğerinin argümanı oluyor. Program ne yazdırır?

static int usAl(int taban, int us) {
    int sonuc = 1;
    for (int i = 0; i < us; i++)
        sonuc *= taban;
    return sonuc;
}
static int faktoriyel(int n) {
    int sonuc = 1;
    for (int i = 2; i <= n; i++)
        sonuc *= i;
    return sonuc;
}
// main içinde:
System.out.println(faktoriyel(usAl(2, 2)));
System.out.println(usAl(faktoriyel(3), 2));
System.out.println(
        usAl(usAl(2, 2), faktoriyel(2)));
Cevabı göster
24
36
16
  • Önce içteki çağrı çalışır: usAl(2, 2) = 4 → faktoriyel(4) = 24.
  • faktoriyel(3) = 6 → usAl(6, 2) = 36. Argümanların sırası önemlidir: usAl(2, 6) 64 olurdu.
  • Argümanlar soldan sağa hesaplanır: usAl(2, 2) = 4, faktoriyel(2) = 2 → usAl(4, 2) = 16.

Çoktan Seçmeli · Fonksiyon İçinde Fonksiyon

Soru 9: Yanlış Kombinasyon

faktoriyel önceki sorudaki int sürümüdür. kombinasyon(5, 2) doğru sonucu (10) veriyor; kombinasyon(13, 2) ise 78 yerine 24 döndürüyor. Neden?

static int kombinasyon(int n, int r) {
    return faktoriyel(n)
         / (faktoriyel(r) * faktoriyel(n - r));
}

A: 13! = 6227020800, int sınırı (2147483647) aşılır ve sessizce 1932053504 olur. 2! · 11! = 79833600 int'e sığar; 1932053504 / 79833600 = 24. Çözüm: long kullanmak ya da C(n, r)'yi çarpıp bölerek adım adım hesaplamak.

Çoktan Seçmeli · Yapıcı Metotlar

Soru 10: void Yazılmış Yapıcı

main içinde Kitap k = new Kitap("Java"); yazıldığında ne olur?

class Kitap {
    String ad;
    public void Kitap(String ad) {
        this.ad = ad;
    }
}

C: Yapıcının dönüş tipi yoktur, void bile yazılmaz. Bu sınıfta hiç yapıcı olmadığı için derleyici yalnızca parametresiz varsayılan yapıcıyı ekler; new Kitap("Java") için uygun yapıcı bulunamaz: constructor Kitap in class Kitap cannot be applied to given types.

Çıktı Sorusu · Yapıcı Metotlar

Soru 11: Yapıcı Zinciri

Üç aşırı yüklenmiş yapıcı this(...) ile birbirini çağırıyor. Program ne yazdırır?

class Sayac {
    int deger;
    String ad;
    Sayac() {
        this(10);
        ad = "ilk";
    }
    Sayac(int d) {
        deger = d;
    }
    Sayac(String a, int d) {
        this(d * 2);
        ad = a;
    }
}
// main içinde:
Sayac s1 = new Sayac();
Sayac s2 = new Sayac(5);
Sayac s3 = new Sayac("x", 4);
System.out.println(s1.deger + " " + s1.ad);
System.out.println(s2.deger + " " + s2.ad);
System.out.println(s3.deger + " " + s3.ad);
Cevabı göster
10 ilk
5 null
8 x
  • new Sayac(): önce this(10) ile deger = 10, sonra ad = "ilk".
  • new Sayac(5): yalnızca deger atanır; ad hiç atanmadığı için String alanının varsayılan değeri null.
  • new Sayac("x", 4): this(8) → deger = 8, sonra ad = "x".
  • this(...) yapıcının ilk satırında olmak zorundadır.

Çoktan Seçmeli · Hazır Metotlar

Soru 12: Math ve Tam Sayı Bölmesi

System.out.println(Math.sqrt(16) + Math.max(3, 7) / 2); ne yazdırır?

B: Math.max(3, 7) iki int aldığı için int döndürür: 7. 7 / 2 tam sayı bölmesi: 3. Math.sqrt her zaman double döndürür: 4.0. 4.0 + 3 = 7.0.

Çıktı Sorusu · Hazır Metotlar

Soru 13: String Metotları

İndisler 0'dan başlar. Program ne yazdırır?

String s = "Bilgisayar";
System.out.print(s.length() + " ");
System.out.print(s.charAt(4) + " ");
System.out.print(s.indexOf('a') + " ");
System.out.println(s.lastIndexOf("a"));
System.out.print(s.substring(3, 7) + "|");
System.out.println(s.substring(7));
System.out.print(s.equals("bilgisayar") + " ");
System.out.println(
        s.equalsIgnoreCase("BILGISAYAR"));
System.out.print(s.indexOf("say") + " ");
System.out.println(s.contains("bil"));
Cevabı göster
10 i 6 8
gisa|yar
false true
5 false
indis0123456789
karakterBilgisayar
  • substring(3, 7): 3…6 (7 hariç) → "gisa"; substring(7) sonuna kadar → "yar".
  • equals harf duyarlıdır; equalsIgnoreCase değildir. contains("bil") da harf duyarlı: false.

Çıktı Sorusu · Hazır Metotlar

Soru 14: Mutlak Değer ve Taşma

Kendi yazdığımız metot ile Math.abs karşılaştırılıyor. Program ne yazdırır?

static int mutlakDeger(int sayi) {
    if (sayi < 0) {
        return -sayi;
    } else {
        return sayi;
    }
}
// main içinde
System.out.println(mutlakDeger(-3) + " "
        + mutlakDeger(3));
System.out.println(
        mutlakDeger(Integer.MIN_VALUE));
System.out.println(Math.abs(Integer.MIN_VALUE));
System.out.println(Math.abs(-7.5));
System.out.println(
        Math.abs((long) Integer.MIN_VALUE));
Cevabı göster
3 3
-2147483648
-2147483648
7.5
2147483648
  • int aralığı −2147483648 … 2147483647: en küçük değerin pozitifi int'e sığmaz. -sayi taşar ve yine −2147483648 olur; Math.abs(int) da aynı sonucu verir.
  • Math.abs aşırı yüklenmiştir: double argümanla double sürümü çağrılır (7.5), long argümanla long sürümü (2147483648 long aralığına sığar).

Çoktan Seçmeli · Kapsam

Soru 15: Hangi Kod Derlenir?

main içinde yazılan parçalardan hangisi derlenir?

D: Bir değişken tanımlandığı blokta yaşar. İki kardeş bloğun t'leri ayrı kapsamlardadır, çakışmaz. İç blok, dıştaki yerel değişkenle aynı adı kullanamaz (already defined). Döngü değişkeni döngüden sonra yoktur (cannot find symbol). Yerel değişken değer almadan okunamaz.

Adım Adım Çalıştırma · Kapsam

Soru 16: Gölgeleme İzleme

Sınıf alanı, parametre ve yerel değişken aynı adı taşıyor. Hangi x hangisi? Program ne yazdırır?

Sınıf alanı x program boyunca yaşar.

main'in yerel x'i alanı gölgeler: main içinde x bu değişkendir.

f'nin parametresi x, 5'in kopyası. Yerel kopya 15 olur; alana dokunulmaz.

f kendi x'ini yazar.

g'de bu adla yerel değişken yok: x sınıf alanını gösterir, alan 101 olur.

main'in x'i hâlâ 5. Gölgelenen alana Kapsam.x ile ulaşılır.

public class Kapsam {
    static int x = 1;
    static void f(int x) {
        x = x + 10;
        System.out.print(x + " ");
    }
    static void g() {
        x = x + 100;
        System.out.print(x + " ");
    }
    public static void main(String[] args) {
        int x = 5;
        f(x);
        g();
        System.out.println(x + " " + Kapsam.x);
    }
}

Çoktan Seçmeli · Soyutlama ve Tasarım

Soru 17: İyi Metot Tasarımı

Üç notun ortalaması için yazılan metotlardan hangisi iyi tasarım ilkelerine en uygundur?

C: İyi metot tek bir iş yapar, girdisini parametrelerle alır, sonucunu döndürür ve ne yaptığını anlatan bir ad taşır. Sonuç döndürüldüğü için başka hesaplarda da kullanılabilir. "Hesapla ve yaz", gizli alanlara bağımlılık ve anlamsız islem2 adı bu ilkeleri bozar.

Kod Yazma · Soyutlama ve Tasarım

Soru 18: Sonraki Asal Sayı

Problemi iki metoda bölün: boolean asalMi(int sayi) ve onu kullanan, n'den büyük ilk asal sayıyı döndüren int sonrakiAsal(int n). sonrakiAsal(20), sonrakiAsal(23) ve sonrakiAsal(1) kaçtır?

Cevabı göster
static boolean asalMi(int sayi) {
    if (sayi < 2) return false;
    for (int i = 2; i * i <= sayi; i++)
        if (sayi % i == 0) return false;
    return true;
}
static int sonrakiAsal(int n) {
    int aday = n + 1;
    while (!asalMi(aday)) aday++;
    return aday;
}

Sonuçlar: 23, 29 (n'nin kendisi değil, ondan büyük ilk asal), 2.

sonrakiAsal, asallığın nasıl sınandığını bilmez; yalnızca asalMi'nin ne döndürdüğüne güvenir (fonksiyonel soyutlama). asalMi daha hızlı yazılsa da sonrakiAsal değişmez.

Çoktan Seçmeli · Soyutlama ve Tasarım

Soru 19: Asal Denetiminde Eksik Koşul

bulSonrakiAsal(20) doğru sonucu (23) veriyor. bulSonrakiAsal(0) ve bulSonrakiAsal(-4) ne döndürür?

static int bulSonrakiAsal(int sayi) {
    int sonraki = sayi + 1;
    while (!asalMi(sonraki)) {
        sonraki++;
    }
    return sonraki;
}
static boolean asalMi(int sayi) {
    for (int i = 2; i < sayi; i++) {
        if (sayi % i == 0) {
            return false;
        }
    }
    return true;
}

D: 2'den küçük sayılarda asalMi'nin döngüsü hiç dönmez ve true döndürür. bulSonrakiAsal(0) ilk aday 1'i "asal" kabul eder; bulSonrakiAsal(-4) ilk aday −3'ü. Doğru sonuç ikisinde de 2 olmalıydı (A). Düzeltme: asalMi'nin başına if (sayi < 2) return false;. bulSonrakiAsal değişmez; hata yalnızca kullandığı metottadır.

Çıktı Sorusu · Lambda İfadeleri

Soru 20: Lambda ile Hesap ve Süzme

İçe aktarmalar yapılmış. Program ne yazdırır?

IntBinaryOperator f = (a, b) -> a * b + 1;
IntUnaryOperator g = x -> x * x;
int t = f.applyAsInt(3, 4) + g.applyAsInt(5);
System.out.println(t);
List<Integer> l =
        Arrays.asList(5, 8, 3, 12, 7);
System.out.println(l.stream()
        .filter(s -> s > 5)
        .map(s -> s / 2)
        .collect(Collectors.toList()));
Cevabı göster
38
[4, 6, 3]
  • f.applyAsInt(3, 4) = 3 · 4 + 1 = 13; g.applyAsInt(5) = 25. İkisi de int: 13 + 25 = 38.
  • filter koşulu sağlayanları tutar: 8, 12, 7 (sıra korunur). map her birini dönüştürür: 8 / 2 = 4, 12 / 2 = 6, 7 / 2 = 3 (tam sayı bölmesi).

Son

Bölüm 3: Fonksiyonlar: Çalışma Soruları
Konu anlatımı: fonksiyonlar sunumu · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.