Data Structures

Data Structures konusuna değinilen kısım.

Data Structures Nedir?

Structs, Enums, ve Unions gibi yapılar, verileri farklı şekillerde organize etmek ve depolamak için kullanılan yapısal elemanlardır. Bu yapılar, programın verileri daha düzenli ve etkili bir şekilde yönetmesine yardımcı olur.

Structs

Struct, farklı veri türlerini tek bir veri yapısı içinde gruplamak için kullanılan bir yapıdır. Bu yapı, birçok farklı veriyi bir araya getirerek daha karmaşık veri yapıları oluşturmanıza olanak tanır. Struct'lar, programlarda verileri düzenli bir şekilde saklamak ve işlemek için oldukça kullanışlıdır.

Bir struct tanımlandığında, içinde farklı veri türlerine sahip veri elemanları (fields veya members) bulunur. Her bir veri elemanı, struct içinde bir isimle ve veri türü ile tanımlanır;

#include <stdio.h>

struct Ogrenci 
{
    char ad[50];
    int numara;
    float notlar[3];
};

int main() 
{
    // Ogrenci struct'ından bir nesne (instance) oluşturma
    struct Ogrenci ogrenci1;

    // Veri elemanlarına değer atama
    strcpy(ogrenci1.ad, "Ahmet Yilmaz");
    ogrenci1.numara = 12345;
    ogrenci1.notlar[0] = 90.5;
    ogrenci1.notlar[1] = 85.0;
    ogrenci1.notlar[2] = 78.5;

    // Veri elemanlarına erişim
    printf("Ad: %s\n", ogrenci1.ad);
    printf("Numara: %d\n", ogrenci1.numara);
    printf("Notlar: %.2f, %.2f, %.2f\n",
           ogrenci1.notlar[0], ogrenci1.notlar[1], ogrenci1.notlar[2],
           ogrenci1.notlar[3], ogrenci1.notlar[4]);

    return 0;
}

Yukarıda ki örnekte main() fonksiyonun da Ogrencı struct'ından bir nesne (instance) veya birden fazla nesne oluştururken sürekli struct Ogrenci yazmamak için struct'a Typedef ile etiket (label) verilebilir.

Linked List

Linked List, birbirine bağlı elemanlardan oluşan bir veri yapısıdır. Her eleman, kendinden önceki ve kendinden sonraki elemanın adresini tutar. Bu sayede, elemanlar bir zincir gibi birbirine bağlanır.

Linked List'in temel özellikleri şunlardır;

  1. Bağlı Elemanlar: Bir linked list, düğümler (nodes) olarak adlandırılan elemanların birbirine bağlandığı bir veri yapısıdır. Her düğüm, veri ve bir sonraki düğümün referansını içerir.

  2. Dinamik Boyut: Linked List, elemanlar ekledikçe veya çıkardıkça dinamik olarak büyüyebilir veya küçülebilir. Bu, bellek kullanımını daha verimli hale getirir.

  3. Bağlantılı Elemanlar: Her düğümün bir sonraki düğüme işaret ettiği bir bağlantı vardır. Bu bağlantılar sayesinde, linked list boyunca dolaşmak mümkün olur.

  4. Çeşitli Türleri: İki ana türü vardır: tek yönlü linked list (sadece ileri yönde dolaşılabilir) ve çift yönlü linked list (hem ileri hem de geri yönde dolaşılabilir).

  5. Baş ve Son Düğümler: Linked List'in başı ve sonu, listenin başlangıcını ve sonunu işaretleyen özel düğümlerdir. Bu baş ve son düğümler, listeye eleman eklerken veya çıkartırken işlemi kolaylaştırır.

#include <stdio.h>
#include <stdlib.h>

// Tek yönlü linked list düğümü
struct Node 
{
    int data;
    struct Node* next;
};

int main() 
{
    // Linked List başlangıcı
    struct Node* baslangic = NULL;

    // Düğümler oluşturma ve veri ekleme
    for (int i = 1; i <= 5; i++) 
    {
        struct Node* yeniDugum = (struct Node*)malloc(sizeof(struct Node));
        yeniDugum->data = i;
        yeniDugum->next = baslangic; // Yeni düğümü liste başına ekler.
        baslangic = yeniDugum; // Yeni düğümü liste başı yapar.
    }

    // Linked List'i dolaşma ve verileri yazdırma
    struct Node* current = baslangic;
    while (current != NULL) 
    {
        printf("%d -> ", current->data);
        current = current->next;
    }
    printf("NULL\n");
    return 0;
}

Bu ve buna benzer veri yapılarının oluşturulma amacı veriyi saklamanın, erişebilirliğin ve buna benzer yöntemlerin daha kolay olmasını sağlamaktır. Bu yüzden buna benzer yine veri yapıları vardır (Binary Tree, Red Black Tree, Stack, Queue, vb.).

Enums

Enum (Enumeration), belirli sabit değerleri sembolik isimlerle temsil etmek için kullanılan bir veri türüdür.

Enums, temelde belirli bir sıraya sahip tamsayı değerlerini sembolik isimlerle temsil eden bir yapıdır. İlk eleman, (spesifik olarak bir atama yapılmadıysa) varsayılan olarak 0'dan başlayarak artar ve her bir sonraki eleman bir öncekini bir birim artırır. Ancak, enum elemanlarına özel değerler atayabilirsiniz.

enum Renk {
    KIRMIZI,  // 0
    YESIL,    // 1
    MAVI,     // 2
    SARI      // 3
};

Varsayılan olarak, "KIRMIZI" 0, "YESIL" 1, "MAVI" 2 ve "SARI" 3 değerlerine sahiptir. Yani, bu enum değerleri birer sayı olarak temsil edilir.

Ancak, enum elemanlarına özel değerler atayabilirsiniz. Örneğin;

enum Renk {
    KIRMIZI = 1,
    YESIL = 2,
    MAVI = 4,
    SARI = 8
};
  1. Sembolik İsimler: Enums, belirli değerleri daha anlaşılır ve okunabilir hale getirmek için sembolik isimlerle ilişkilendirir. Bu, kodun daha anlaşılır ve bakımının daha kolay olmasını sağlar.

  2. Sıralı Değerler: Enum elemanları genellikle sıralıdır, yani her bir eleman önceki elemanın bir sonraki değerini bir birim artırır. Ancak, enum elemanları belirli bir değerle başlatılabilir ve ardışık olmak zorunda değildir.

  3. Varsayılan Veri Türü: Enum elemanları, genellikle int veri türüne sahiptir, ancak belirli bir tamsayı veri türü de atanabilir.

#include <stdio.h>

// Bir enum tanımı
enum Renk 
{
    KIRMIZI,
    YESIL,
    MAVI,
    SARI
};

int main() 
{
    // Enum değerlerini kullanma
    enum Renk secilenRenk = YESIL;

    // Enum değerini yazdırma
    printf("Secilen renk: %d\n", secilenRenk);

    // Switch kullanarak enum değerini işleme
    switch (secilenRenk) 
    {
        case KIRMIZI:
            printf("Kirmizi renk secildi.\n");
            break;
        case YESIL:
            printf("Yesil renk secildi.\n");
            break;
        case MAVI:
            printf("Mavi renk secildi.\n");
            break;
        case SARI:
            printf("Sari renk secildi.\n");
            break;
        default:
            printf("Bilinmeyen renk secildi.\n");
            break;
    }
    return 0;
}

Unions

Union, farklı veri tiplerini aynı bellek alanında saklamak için kullanılan bir veri yapısıdır. Unions, Struct'lar gibi, birden fazla veri elemanını bir araya getirir, ancak bu elemanlar aynı bellek alanını paylaşır ve aynı anda sadece bir elemana erişim sağlar.

#include <stdio.h>

union VeriUnion 
{
    int tamSayi;
    float ondalikSayi;
    char* isim;
};

int main() 
{
    union VeriUnion veri;

    // Tam sayı elemanını kullanıyoruz
    veri.tamSayi = 42;
    printf("Tam Sayi: %d\n", veri.tamSayi);

    // Şimdi, aynı bellek alanında ondalık sayı elemanını kullanmaya çalışırsak:
    veri.ondalikSayi = 3.14;
    printf("Ondalik Sayi: %.2f\n", veri.ondalikSayi);
    
    veri.isim = "Ali";
    // Şimdi tekrar tam sayı elemanını kullanmaya çalışırsak:
    printf("Tam Sayi: %d\n", veri.tamSayi);
    printf("Ondalik Sayi: %.2f\n", veri.ondalikSayi);
    printf("Isim: %s\n", veri.isim);

    return 0;
}

Burada dikkat edilmesi gereken nokta Unions'larda birbirinden farklı veri elemanlarının bellek kullanımı aynı alan üzerinden olduğundan içerisinde bulunan veri elemanına her bir değer ataması yapıldıktan önce ki veri elemanının değerinin kaybolmasıdır.

Burada ki örnekte ilk başta tamSayi elemanına bir atama yapıp değerini ekrana yazdırabiliyoruz ancak sonra ki satırlarda ondalikSayi elemanına bir değer ataması yapılınca tamSayi elemanının değeri kaybediliyor. Ve daha da sonrasında isim elemanına ardından gelen bir değer ataması yapılınca da bu sefer de ondalikSayi elemanı değerini kaybediyor bunun sebebi Union'ların Struct'larda ki gibi veri elemanları için ayrı ayrı bir bellek alanı oluşturmamalarıdır. Hepsi aynı bellek alanını paylaştıklarından her birine değer ataması yapılsa da en son değer ataması yapılan veri elemanı güncel değer olmuş oluyor.

Last updated