← Back to list

C ile Yığın (Stack) Uygulaması Dizi ile

Bu yazıda, C dilinde yazılmış temel bir yığın (stack) uygulamasını satır satır inceleyeceğiz. Amaç sadece “bu kod çalışıyor”u görmek değil…

Heda GÜLER · 2025-12-04 21:40 · 0 claps · 5.2 min read
#stack #lifo #yığın #arrays #datastrucutre
Open on Medium ↗

C ile Yığın (Stack) Uygulaması Dizi ile

Bu yazıda, C dilinde yazılmış temel bir yığın (stack) uygulamasını satır satır inceleyeceğiz. Amaç sadece “bu kod çalışıyor”u görmek değil; neden böyle yazıldığını, hangi satırın ne işe yaradığını gerçekten anlamak.

Kodumuz şu işi yapıyor:

  • Yığına eleman ekleyebiliyoruz (push)
  • Yığından eleman çıkarabiliyoruz (pop)
  • En üstteki elemanı görebiliyoruz
  • Yığındaki tüm elemanları listeleyebiliyoruz
  • Menü tabanlı, kullanıcı ile etkileşimli bir C konsol uygulaması

1. Kodu Genel Haliyle Görelim

#include <stdio.h>
#include <locale.h>

#define YIGIN_KAPASITESI 5

typedef int YiginVeriTipi;

struct Yigin {
    YiginVeriTipi eleman[YIGIN_KAPASITESI];
    int ust;
};

void yigin_olustur(struct Yigin *yigin) {
    yigin->ust = 0;
}

int ekle(struct Yigin *yigin, YiginVeriTipi yeni) {
    if (yigin->ust < YIGIN_KAPASITESI) {
        yigin->eleman[yigin->ust++] = yeni;
        printf("%d yığına eklendi\n", yeni);
        return 1;
    } else {
        printf("Yığın dolu. Eklenemez.\n");
        return 0;
    }
}

YiginVeriTipi cikar(struct Yigin *yigin) {
    if (yigin->ust == 0) {
        printf("Yığın boş\n");
        return -1;
    } else {
        return yigin->eleman[--(yigin->ust)];
    }
}

int bosmu(struct Yigin *yigin) {
    return yigin->ust == 0;
}

void listele(struct Yigin *yigin) {
    if (bosmu(yigin)) {
        printf("Yığın boş\n");
    } else {
        printf("Yığındaki elemanlar : \n");
        for (int i = yigin->ust - 1; i >= 0; i--) {
            printf("%d\n", yigin->eleman[i]);
        }
    }
}

void enust(struct Yigin *yigin) {
    if (bosmu(yigin)) {
        printf("Yığın boş\n");
    } else {
        printf("Yığının en üstündeki eleman : %d\n", yigin->eleman[yigin->ust - 1]);
    }
}

int main() {
    setlocale(LC_ALL, "Turkish");
    struct Yigin yigin;
    yigin_olustur(&yigin);
    int secim, yigin_elemani;
    while (1) {
        printf("Yığın İşlemi\n");
        printf("[1] Push (Ekle) işlemi\n");
        printf("[2] Pop (Çıkar) işlemi\n");
        printf("[3] Yığında En üstteki eleman işlemi\n");
        printf("[4] Yığın Gezme İşlemi\n");
        printf("[5] Çıkış\n");
        printf("Seçiminiz : ");
        scanf("%d", &secim);
        switch (secim) {
            case 1:
                printf("Bir Sayı giriniz : ");
                scanf("%d", &yigin_elemani);
                ekle(&yigin, yigin_elemani);
                break;
            case 2:
                yigin_elemani = cikar(&yigin);
                if (yigin_elemani == -1) {
                    printf("Yığın yetersiz\n");
                } else {
                    printf("Yığındaki son eleman: %d\n", yigin_elemani);
                }
                break;
            case 3:
                enust(&yigin);
                break;
            case 4:
                listele(&yigin);
                break;
            case 5:
                return 0;
            default:
                printf("Lütfen doğru bir seçim girin : ");
        }
    }
    return 0;
}

Şimdi bu kodu parça parça açalım.

2. Başlangıç: Kütüphaneler ve Sabit Tanımları

#include <stdio.h>
#include <locale.h>
  • stdio.h: printf, scanf gibi giriş–çıkış fonksiyonları için gerekli.
  • locale.h: setlocale kullanarak Türkçe karakter desteği gibi yerelleştirme ayarları için.
#define YIGIN_KAPASITESI 5
  • Bu satır bir makro tanımı.
  • Yığının kapasitesini 5 olarak belirliyor.
  • Avantajı: Kapasiteyi değiştirmek için sadece burayı 10 yapıp tüm kodu otomatik güncelleyebilirsin.
typedef int YiginVeriTipi;
  • YiginVeriTipi adında yeni bir tür (type alias) tanımlıyor.
  • Şu an int, ama ileride istersen float, struct vs. yapabilirsin. Kodun geri kalanını değiştirmek yerine sadece burayı değiştirmen yeter.

3. Yığın Yapısının (struct) Tanımı

struct Yigin {
    YiginVeriTipi eleman[YIGIN_KAPASITESI];
    int ust;
};

Bu yapı yığının tüm durumunu tutuyor:

eleman[YIGIN_KAPASITESI]

  • Yığındaki verilerin tutulduğu dizi.
  • Kapasite kadar eleman depolayabiliyor.

int ust;

  • Yığının tepesini (top index) temsil eden değişken.
  • Kaç eleman olduğunu ve bir sonraki eklenecek indeksin neresi olduğunu gösteriyor.

Bu implementasyonda ust şu anlama geliyor:

  • Yığın boşken: ust = 0
  • Yığında N eleman varsa: ust = N
  • En üstteki elemanın indeksi: ust - 1

4. Yığın Oluşturma Fonksiyonu

void yigin_olustur(struct Yigin *yigin) {
    yigin->ust = 0;
}

Bu fonksiyon başlangıç ayarını yapıyor.

Parametre: struct Yigin *yigin

  • Adresteki Yigin yapısını alıyor (call by reference).
  • yigin->ust = 0;

Yığının henüz boş olduğunu ifade ediyor.

Programda main içinde:

struct Yigin yigin;
yigin_olustur(&yigin);
  • yigin isimli bir yığın nesnesi oluşturuluyor.
  • Adresi &yigin fonksiyona verilerek ilk ayar yapılıyor.

5. Push (Ekleme) İşlemi: ekle Fonksiyonu

int ekle(struct Yigin *yigin, YiginVeriTipi yeni) {
    if (yigin->ust < YIGIN_KAPASITESI) {
        yigin->eleman[yigin->ust++] = yeni;
        printf("%d yığına eklendi\n", yeni);
        return 1;
    } else {
        printf("Yığın dolu. Eklenemez.\n");
        return 0;
    }
}

Bu fonksiyon, push işlemini yapar.

  1. Yığın dolu mu kontrolü
if (yigin->ust < YIGIN_KAPASITESI)
  • ust kapasiteden küçükse hâlâ yer vardır.
  • ust == YIGIN_KAPASITESI olduğunda yığın tamamen doludur.

2. Elemanı ekleme ve ust değerini artırma

yigin->eleman[yigin->ust++] = yeni;

Bu ifade şu anlama gelir:

  • Önce yigin->eleman[yigin->ust] = yeni;
  • Sonra yigin->ust = yigin->ust + 1;

Yani yeni eleman mevcut tepe indeksine yazılıyor, sonra tepe bir sonraki pozisyona kaydırılıyor.

3. Ekleme sonucu

  • Başarılıysa: return 1;
  • Yığın doluysa: mesaj yazıp return 0;

6. Pop (Çıkarma) İşlemi: cikar Fonksiyonu

YiginVeriTipi cikar(struct Yigin *yigin) {
    if (yigin->ust == 0) {
        printf("Yığın boş\n");
        return -1;
    } else {
        return yigin->eleman[--(yigin->ust)];
    }
}

Bu fonksiyon, pop işlemini yapar: en üstteki elemanı çıkarıp geri döndürür.

  1. Boş mu kontrolü
if (yigin->ust == 0)
  • ust == 0 ⇒ yığında hiç eleman yok.

2. Boşsa yapılacaklar

printf("Yığın boş\n");
return -1;
  • Kullanıcıya yığının boş olduğu söyleniyor.
  • -1 özel bir “hata değeri” gibi kullanılıyor.

3. Doluysa eleman çıkarma

return yigin->eleman[--(yigin->ust)];

Burada önce ust 1 azaltılıyor, sonra o indisteki eleman döndürülüyor.

Adım adım:

  • yigin->ust = yigin->ust - 1;
  • return yigin->eleman[yigin->ust];

Böylece hem tepe geriye kayıyor, hem de eski tepedeki elemanı döndürmüş oluyoruz.

No: -1’in hata değeri olarak kullanılması, sadece pozitif sayılarla çalıştığında güvenli. Negatif sayılar da eklenebilseydi daha farklı bir hata mekanizması (mesela “başarı bilgisi + out param”) daha temiz olurdu.

7. Yardımcı Fonksiyon: bosmu

int bosmu(struct Yigin *yigin) {
    return yigin->ust == 0;
}
  • Yığının boş olup olmadığını kontrol etmek için küçük bir yardımcı fonksiyon.
  • true/false gibi düşün:
  • Boşsa 1
  • Doluysa 0 döner.

Bu fonksiyon, listele ve enust fonksiyonlarında kullanılıyor.

8. Yığını Listeleme: listele Fonksiyonu

void listele(struct Yigin *yigin) {
    if (bosmu(yigin)) {
        printf("Yığın boş\n");
    } else {
        printf("Yığındaki elemanlar : \n");
        for (int i = yigin->ust - 1; i >= 0; i--) {
            printf("%d\n", yigin->eleman[i]);
        }
    }
}

Amaç: Yığındaki tüm elemanları üstten alta doğru yazdırmak.

  1. Boş kontrolü
if (bosmu(yigin)) {
    printf("Yığın boş\n");
}

2. Doluysa döngü

for (int i = yigin->ust - 1; i >= 0; i--) {
    printf("%d\n", yigin->eleman[i]);
}
  • Başlangıç: i = yigin->ust - 1 ⇒ en üst elemandan başla.
  • Bitiş: i >= 0 ⇒ en alttaki elemana kadar in.
  • Her adımda: i-- ⇒ yukarıdan aşağı doğru sırayla yazdır.

Bu, stack mantığına uygun bir görüntü: Üstteki eleman önce gösteriliyor.

9. En Üst Elemanı Görme: enust Fonksiyonu

void enust(struct Yigin *yigin) {
    if (bosmu(yigin)) {
        printf("Yığın boş\n");
    } else {
        printf("Yığının en üstündeki eleman : %d\n", yigin->eleman[yigin->ust - 1]);
    }
}

Amaç: pop yapmadan en üstteki elemanı görmek (peek işlemi).

Mantık:

  • Boşsa: “Yığın boş” yaz.
  • Doluysa: yigin->eleman[yigin->ust - 1] değeri en üst elemandır, bunu göster.

10. main Fonksiyonu: Menü Tabanlı Uygulama

int main() {
    setlocale(LC_ALL, "Turkish");
    struct Yigin yigin;
    yigin_olustur(&yigin);
    int secim, yigin_elemani;

setlocale(LC_ALL, "Turkish");

  • Konsolda Türkçe karakter desteği için (bazı sistemlerde etkili / bazılarını etkilemez).

struct Yigin yigin;

  • Yığın nesnemiz.

yigin_olustur(&yigin);

  • Başlangıçta ust = 0 ile sıfırlanıyor.

secim, yigin_elemani;

  • secim: menü seçimi için
  • yigin_elemani: kullanıcıdan alınan veya pop sonrası dönen sayı.

10.1 Sonsuz Döngü: Menü Yapısı

    while (1) {
        printf("Yığın İşlemi\n");
        printf("[1] Push (Ekle) işlemi\n");
        printf("[2] Pop (Çıkar) işlemi\n");
        printf("[3] Yığında En üstteki eleman işlemi\n");
        printf("[4] Yığın Gezme İşlemi\n");
        printf("[5] Çıkış\n");
        printf("Seçiminiz : ");
        scanf("%d", &secim);
  • while (1) ⇒ sonsuz döngü.
  • Kullanıcı çıkış seçeneğini (5) seçene kadar menü dönüyor.

10.2 switch ile Menü Kontrolleri

        switch (secim) {
            case 1:
                printf("Bir Sayı giriniz : ");
                scanf("%d", &yigin_elemani);
                ekle(&yigin, yigin_elemani);
                break;

Case 1 ⇒ Push

  • Kullanıcıdan bir sayı alınıyor.
  • ekle(&yigin, yigin_elemani); ile yığına ekleniyor.
            case 2:
                yigin_elemani = cikar(&yigin);
                if (yigin_elemani == -1) {
                    printf("Yığın yetersiz\n");
                } else {
                    printf("Yığındaki son eleman: %d\n", yigin_elemani);
                }
                break;

Case 2 ⇒ Pop

  • cikar fonksiyonu çağrılıyor.
  • Eğer -1 dönmüşse: yığın boş demektir.
  • Aksi halde: çıkan eleman ekrana yazdırılıyor.
            case 3:
                enust(&yigin);
                break;

Case 3 ⇒ En Üst Eleman

  • enust fonksiyonu ile sadece gösterim yapılıyor.
            case 4:
                listele(&yigin);
                break;

Case 4 ⇒ Yığını Gezme

  • listele fonksiyonu tüm elemanları üstten alta doğru yazdırıyor.
            case 5:
                return 0;

Case 5 ⇒ Çıkış

  • main fonksiyonu 0 döndürerek programı sonlandırıyor.
            default:
                printf("Lütfen doğru bir seçim girin : ");
        }
    }
    return 0;
}
  • default ⇒ 1–5 dışında bir sayı girildiyse uyarı veriliyor.
  • while(1) döngüsü hiç kırılmadığı için çıkış sadece case 5 ile oluyor.

11. Bu Koddan Çıkarılacak Önemli Stack Dersleri

Bu örnek, yığın mantığını çok güzel gösteriyor:

LIFO (Last In, First Out)

  • Son giren ilk çıkar.
  • Ekleme/çıkarma hep tepe (top) tarafından.

Tek kontrol noktası: ust

  • Eleman sayısı, dolu/boş olma durumu, üstteki elemanın yeri hepsi ust ile yönetiliyor.

Dizi ile stack implementasyonu

  • Statik boyutlu bir stack: kapasite #define ile sabit.
  • Dinamik stack isteseydik, malloc ile dynamic array veya linked list kullanabilirdik.

메타데이터
post_id
a3fa3fe5ac27
slug
c-ile-yığın-stack-uygulaması-a3fa3fe5ac27
url
https://medium.com/@hedaguler25/c-ile-y%C4%B1%C4%9F%C4%B1n-stack-uygulamas%C4%B1-a3fa3fe5ac27
canonical_url
https://medium.com/@hedaguler25/c-ile-y%C4%B1%C4%9F%C4%B1n-stack-uygulamas%C4%B1-a3fa3fe5ac27
author_url
https://medium.com/@hedaguler25
status
ok
fetched_at
2026-06-24 04:09:36