2 - Fonksiyonlar, Diziler ve İşaretçiler
2026
Not
void fonksiyonlarda return; yazmak zorunlu değildir (yazılabilir).int, float vb. dönüş tipi olan fonksiyonlarda anlamlı bir dönüş değeri vermek gerekir.#include <stdio.h>
int ciftMi(int sayi) {
if (sayi % 2 == 0) {
return 1; // 1, "doğru" anlamına gelir
} else {
return 0; // 0, "yanlış" anlamına gelir
}
}
int main(void) {
int sayi = 6;
if (ciftMi(sayi)) { // ciftMi fonksiyonu 1 (doğru) döndürürse
printf("%d çift bir sayıdır.\n", sayi);
} else {
printf("%d tek bir sayıdır.\n", sayi);
}
return 0;
}Sözdizimi:
#include <stdio.h>
// Fonksiyon prototipi
int usAl(int taban, int us);
int main(void) {
int x = 2, y = 3;
int sonuc = usAl(x, y); // Prototip sayesinde çağrı doğru yorumlanır.
printf("%d üssü %d = %d\n", x, y, sonuc);
return 0;
}
int usAl(int taban, int us) {
int sonuc = 1;
// (Bu derste negatif üsleri ele almıyoruz.)
if (us < 0) {
return 0;
}
for (int i = 0; i < us; i++) {
sonuc *= taban;
}
return sonuc;
}Dikkat
Özyinelemede mutlaka bir temel durum olmalıdır; aksi takdirde sonsuz çağrı (ve çökme) oluşabilir.
dizi[0].Sözdizimi:
Dikkat!
Bir dizinin boyutu ve türü, tanımlandıktan sonra değiştirilemez!
int sayilar[5] = { 1, 2, 3, 4, 5 };
// 3. elemanın (indis 2) değerini -1 yap
sayilar[2] = -1;
// 5. elemanın (indis 4) değerini 0 yap
sayilar[4] = 0;Dizi elemanlarının indislerini kullanarak yukarıdaki gibi değiştirebiliriz.
sizeof Operatörü: Dizilerin Boyutunu Hesaplamasizeof operatörü, bir değişkenin veya veri tipinin bellekte kapladığı bayt sayısını döndürür.
Dizilerle kullanıldığında, dizinin toplam boyutunu bayt cinsinden verir.
Dizinin eleman sayısını bulmak için:
eleman_sayisi = sizeof(dizi) / sizeof(dizi[0])#include <stdio.h>
#include <stddef.h>
int main(void) {
int sayilar[] = {10, 20, 30, 40, 50};
size_t eleman_sayisi = sizeof(sayilar) / sizeof(sayilar[0]);
printf("Dizinin eleman sayısı: %zu\n", eleman_sayisi);
return 0;
}Not
Örneğin sizeof(sayilar) = 20 ve sizeof(sayilar[0]) = 4 ise 20 / 4 = 5 olur. Bu değerler sistem ve derleyiciye göre değişebilir; yöntem ise aynıdır.
Kritik not
Fonksiyon parametresi olarak alınan int dizi[], pratikte int *dizi gibi davranır. Bu yüzden fonksiyon içinde sizeof(dizi) artık dizinin toplam boyutu değildir; pointer’ın boyutudur.
+------------+------------+------------+------------+
| Adres | 0x1000 | 0x1004 | 0x1008 | ...
+------------+------------+------------+------------+
| Değer | 10 | 0x1000 | 'A' | ...
+------------+------------+------------+------------+
^ ^
| |
int sayi int *ptr
sayi değişkeni 0x1000 adresinde saklanıyor ve değeri 10.ptr işaretçisi 0x1004 adresinde saklanıyor ve değeri sayi değişkeninin adresi olan 0x1000.*ptr ifadesi, ptr’nin tuttuğu adresteki değeri verir (burada, 10).* operatörüne dereference (içeriğini alma) operatörü denir.Sözdizimi:
veri_tipi: İşaretçinin işaret edeceği değişkenin veri tipi.*: İşaretçi olduğunu belirtir.isaretci_adi: İşaretçiye verilen isim.İlklendirme:
#include <stdio.h>
int main(void) {
int sayi = 10;
int *ptr; // int türünde bir işaretçi tanımlama
ptr = &sayi; // ptr'ye sayi'nin adresi atanır
printf("sayi'nin değeri: %d\n", sayi);
printf("sayi'nin adresi: %p\n", (void*)&sayi);
printf("ptr'nin değeri: %p\n", (void*)ptr); // ptr, sayi'nin adresini tutar
printf("ptr'nin gösterdiği adresteki değer: %d\n", *ptr); // *ptr, sayi'nin değerini verir
return 0;
}Not
Dizi adı her zaman “pointer” değildir; bazı özel durumlarda dizi olarak ele alınır (ör. sizeof(dizi)).
#include <stdio.h>
int main(void) {
int sayilar[5] = {10, 20, 30, 40, 50};
int *ptr = sayilar; // ptr, sayilar[0]'ın adresini gösterir
printf("İlk eleman: %d\n", *ptr); // Çıktı: 10
printf("İkinci eleman: %d\n", *(ptr + 1)); // Çıktı: 20
printf("Üçüncü eleman: %d\n", *(ptr + 2)); // Çıktı: 30
return 0;
}Ek bilgi
ptr + 1 ifadesi adresi “1 bayt” değil, “1 eleman” ilerletir. Örneğin int 4 bayt ise ptr + 1 adresi 4 bayt ilerler.
NULL, bir işaretçinin geçerli bir adresi göstermediğini belirtmek için kullanılan özel bir değerdir.NULL farklı başlık dosyalarından gelebilir; pratikte yaygın bir kaynak <stddef.h>’dir.NULL bir adres değildir; “boş/işaret etmiyor” anlamında kullanılır.#include <stdio.h>
#include <stddef.h>
int main(void) {
int x, *p1, *p2, *p3;
x = 123;
p2 = NULL;
p3 = &x;
printf("Değer atanmamış p1 pointer'ının değeri: %p\n", (void*)p1);
printf("p2 = NULL atanmış pointer'ın değeri: %p\n", (void*)p2);
printf("p3 = &x atanmış pointer'ının değeri: %p\n", (void*)p3);
printf("&x adresinin değeri: %p\n", (void*)&x);
return 0;
}Dikkat
p1 değişkenine değer atanmadığı için ekrana basılan sonuç “rastgele/çöp” görünebilir. Gerçek kodda pointer’ları kullanmadan önce mutlaka bir adres veya NULL ile başlatın.
NULL atamak önemlidir.free() ile). (İlerleyen bölümlerde detaylı olarak işlenecek.)int sayilar[5] = { 11,22,33,44,55 }; şeklindeki sayilar dizisindeki tek sayıların toplamını hesaplayan, sayılardan en büyüğünü, en küçüğünü ve sayıların ortalamasını hesaplayan kodu yazın.main fonksiyonunda bu fonksiyonu farklı değerlerle çağırarak test edin.