🚀 BAŞTAN SONA C DİLİ BÖLÜM-5: Fonksiyonlar, Fonksiyon Prototipleri ve `Call by Value` / `Call by Reference` 🛠️

Konu Özeti

C dilinde fonksiyon tanımlama, fonksiyon prototipleri ve parametre geçirme yöntemleri ele alınıyor. Call by Value ile değişkenin kopyası üzerinde çalışılırken, Call by Reference ile pointer kullanılarak orijinal değişkenin adresine erişilip değeri değiştirilebiliyor. Ayrıca rekürsif fonksiyonlar ve faktöriyel hesabı örneğiyle durma koşulunun önemi vurgulanıyor.

🚀 BAŞTAN SONA C DİLİ BÖLÜM-5: Fonksiyonlar, Fonksiyon Prototipleri ve `Call by Value` / `Call by Reference` 🛠️

Selamlar! Serimizin 5. bölümüne hoş geldiniz.

Önceki bölümde `for`, `while` ve `do-while` döngülerini, `break`/`continue` ifadelerini ve iç içe döngü yapılarını incelemiştik. Bu bölümde ise kodlarımızı modüler hale getiren, tekrarı önleyen **Fonksiyonları (Functions)**, **Fonksiyon Prototiplerini (Function Prototypes)** ve C dilinin belkemiği olan **`Call by Value`** ile **`Call by Reference` (Pointer ile Parametre Geçirme)** mantığını öğreneceğiz.

---

📌 1. Fonksiyon Nedir ve Nasıl Tanımlanır? ⚙️

Fonksiyon, belirli bir görevi yerine getirmek için gruplanmış kod bloğudur. C dilinde her program en az bir fonksiyona (`main` fonksiyonu) sahip olmak zorundadır.

Fonksiyon Tanımlama Syntax'ı:
`DönüşTipi FonksiyonAdı(Parametreler) { // Gövde return değer; }`

### Temel Fonksiyon Örneği:

#include <stdio.h>

// 1. Değer Döndürmeyen (void) Parametreli Fonksiyon
void selamla(char isim[]) {
printf("Merhaba %s, C Dili Egitimine Hos Geldin! 🚀\n", isim);
}

// 2. Değer Döndüren (`int`) Parametreli Fonksiyon
int topla(int a, int b) {
return a + b;
}

int main() {
// Fonksiyon Çağırma (Function Call)
selamla("Ahmet");

int sonuc = topla(15, 25);
printf("Toplama Sonucu: %d\n", sonuc);

return 0;
}

---

📋 2. Fonksiyon Prototipi (Function Prototype) Neden Gereklidir? 📑

C derleyicisi kodu yukarıdan aşağıya doğru okur. Eğer bir fonksiyonu `main` fonksiyonunun **altında** tanımlarsanız ve üstte beyan etmezseniz, derleyici fonksiyonu tanımadığı için *Warning/Error* (Implicit declaration) verir.

Bu durumu önlemek için fonksiyonun imzasını `main` fonksiyonunun üstüne yazarak derleyiciye bildiririz. Buna **Fonksiyon Prototipi** denir.

#include <stdio.h>

// Fonksiyon Prototipi (Derleyiciye haber veriyoruz)
int kareAl(int sayi);

int main() {
int sonuc = kareAl(5);
printf("5'in Karesi: %d\n", sonuc);
return 0;
}

// Fonksiyonun Gerçek Tanımı (Gövdesi)
int kareAl(int sayi) {
return sayi * sayi;
}

---

🔄 3. Parametre Geçirme Yöntemleri 🔀

C dilinde fonksiyonlara parametre aktarırken iki farklı yaklaşım kullanılır:

### A. Call by Value (Değer İle Çağırma):
Fonksiyona değişkenin kendisi değil, **değerinin bir kopyası** gönderilir. Fonksiyon içinde parametre üzerinde yapılan değişiklikler `main` içindeki orijinal değişkeni **ETKİLEMEZ**.

#include <stdio.h>

void degeriArtir(int x) {
x = x + 10; // Sadece kopya x değişir
printf("Fonksiyon Ici x: %d\n", x);
}

int main() {
int sayi = 5;
degeriArtir(sayi);
printf("Main Ici Sayi : %d\n", sayi); // Halen 5'tir!

return 0;
}

---

📍 B. Call by Reference (Referans / Adres İle Çağırma):
Fonksiyona değişkenin değeri yerine **bellekteki adresi (`&`)** gönderilir. Fonksiyon bu adresi **Pointer (`*`)** kullanarak karşılar. Böylece fonksiyon içinde yapılan değişiklikler orijinal değişkeni **DOĞRUDAN ETKİLER**.

C dilindeki efsanevi `swap` (değer değiştirme) örneği:

#include <stdio.h>

// Pointer (*) kullanarak bellek adreslerindeki değerleri değiştiriyoruz
void yerDegistir(int *a, int *b) {
int Gecici = *a;
*a = *b;
*b = Gecici;
}

int main() {
int x = 10, y = 20;

printf("Degisimden Once : x = %d, y = %d\n", x, y);

// Değişkenlerin bellek adreslerini (&) fonksiyona gönderiyoruz
yerDegistir(&x, &y);

printf("Degisimden Sonra: x = %d, y = %d\n", x, y); // x=20, y=10 oldu!

return 0;
}

---

🔄 4. Rekürsif (Öz Yinemeli) Fonksiyonlar 🌀

Bir fonksiyonun kendi kendisini çağırmasına **Recursion** denir. Faktöriyel veya Fibonacci gibi matematiksel işlemlerde sıklıkla tercih edilir.

⚠️ **Kritik Kural:** Rekürsif fonksiyonlarda mutlaka bir **Durma Koşulu (Base Case)** bulunmalıdır. Aksi halde sonsuz döngüye girerek **Stack Overflow** hatasına yol açar!

#include <stdio.h>

// Faktöriyel Hesabı: n! = n * (n-1)!
long long faktoriyel(int n) {
// Durma Koşulu (Base Case)
if (n <= 1) {
return 1;
}
return n * faktoriyel(n - 1); // Fonksiyon kendisini çağırıyor
}

int main() {
int sayi = 5;
printf("%d! = %lld\n", sayi, faktoriyel(sayi)); // 120

return 0;
}

---

📝 Bölüm Özeti ve Gelecek Bölüm 🔮

Bu bölümde Fonksiyon yapılarını, Fonksiyon Prototiplerini, `Call by Value` vs `Call by Reference` (Pointer ile adres aktarımı) farkını ve Rekürsif fonksiyonları öğrendik.

👉 **Bölüm 6'da Bizi Ne Bekliyor?**
• C Dilinin En Güçlü ve Korkulan Konusu: **Pointers (İşaretçiler)** 📍
• Pointer Nedir? Adres Operatörü (`&`) ve Dereference Operatörü (`*`)
• Null Pointer ve Wild Pointer
• P
ointer Aritmetiği (`ptr++`, `ptr + i`)
• Pointer ile Dizi İlişkisi

Sorularınızı konu altından iletebilirsiniz. Bir sonraki bölümde görüşmek üzere! 💻✨

🔒 Bu içeriği görmek için giriş yapın

 
Yanıt yazmak için giriş yapmalısınız
Forum özelliklerini kullanmak ve Level 2 üyelik satın almak için hesabınıza giriş yapın.
136,665Threads
3,307,463Messages
328,515Members
LucidselfLatest member
Top Bottom